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 Apple Inc. All rights reserved.
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB.  If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#include "config.h"
25#include "RenderBlock.h"
26
27#include "ColumnInfo.h"
28#include "Document.h"
29#include "Element.h"
30#include "FloatQuad.h"
31#include "Frame.h"
32#include "FrameView.h"
33#include "GraphicsContext.h"
34#include "HTMLFormElement.h"
35#include "HTMLNames.h"
36#include "HitTestResult.h"
37#include "InlineIterator.h"
38#include "InlineTextBox.h"
39#include "PaintInfo.h"
40#include "RenderCombineText.h"
41#include "RenderFlexibleBox.h"
42#include "RenderImage.h"
43#include "RenderInline.h"
44#include "RenderLayer.h"
45#include "RenderMarquee.h"
46#include "RenderReplica.h"
47#include "RenderTableCell.h"
48#include "RenderTextFragment.h"
49#include "RenderTheme.h"
50#include "RenderView.h"
51#include "SelectionController.h"
52#include "Settings.h"
53#include "TextRun.h"
54#include "TransformState.h"
55#include <wtf/StdLibExtras.h>
56
57#ifdef ANDROID_LAYOUT
58#include "Settings.h"
59#endif
60
61using namespace std;
62using namespace WTF;
63using namespace Unicode;
64
65namespace WebCore {
66
67using namespace HTMLNames;
68
69typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
70static ColumnInfoMap* gColumnInfoMap = 0;
71
72typedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap;
73static PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;
74
75typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
76static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
77
78typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
79
80typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
81static int gDelayUpdateScrollInfo = 0;
82static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
83
84bool RenderBlock::s_canPropagateFloatIntoSibling = false;
85
86// Our MarginInfo state used when laying out block children.
87RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int beforeBorderPadding, int afterBorderPadding)
88    : m_atBeforeSideOfBlock(true)
89    , m_atAfterSideOfBlock(false)
90    , m_marginBeforeQuirk(false)
91    , m_marginAfterQuirk(false)
92    , m_determinedMarginBeforeQuirk(false)
93{
94    // Whether or not we can collapse our own margins with our children.  We don't do this
95    // if we had any border/padding (obviously), if we're the root or HTML elements, or if
96    // we're positioned, floating, a table cell.
97    m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned()
98        && !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable()
99        && !block->isWritingModeRoot();
100
101    m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && (beforeBorderPadding == 0) && block->style()->marginBeforeCollapse() != MSEPARATE;
102
103    // If any height other than auto is specified in CSS, then we don't collapse our bottom
104    // margins with our children's margins.  To do otherwise would be to risk odd visual
105    // effects when the children overflow out of the parent block and yet still collapse
106    // with it.  We also don't collapse if we have any bottom border/padding.
107    m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && (afterBorderPadding == 0) &&
108        (block->style()->logicalHeight().isAuto() && block->style()->logicalHeight().value() == 0) && block->style()->marginAfterCollapse() != MSEPARATE;
109
110    m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginBeforeCollapse() == MDISCARD ||
111        block->style()->marginAfterCollapse() == MDISCARD;
112
113    m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : 0;
114    m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : 0;
115}
116
117// -------------------------------------------------------------------------------------------------------
118
119RenderBlock::RenderBlock(Node* node)
120      : RenderBox(node)
121      , m_floatingObjects(0)
122      , m_positionedObjects(0)
123      , m_rareData(0)
124      , m_lineHeight(-1)
125      , m_beingDestroyed(false)
126{
127    setChildrenInline(true);
128}
129
130RenderBlock::~RenderBlock()
131{
132    if (m_floatingObjects)
133        deleteAllValues(m_floatingObjects->set());
134
135    if (hasColumns())
136        delete gColumnInfoMap->take(this);
137
138    if (gPercentHeightDescendantsMap) {
139        if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {
140            HashSet<RenderBox*>::iterator end = descendantSet->end();
141            for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
142                HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);
143                ASSERT(containerSet);
144                if (!containerSet)
145                    continue;
146                ASSERT(containerSet->contains(this));
147                containerSet->remove(this);
148                if (containerSet->isEmpty()) {
149                    gPercentHeightContainerMap->remove(*descendant);
150                    delete containerSet;
151                }
152            }
153            delete descendantSet;
154        }
155    }
156}
157
158void RenderBlock::destroy()
159{
160    // Mark as being destroyed to avoid trouble with merges in removeChild().
161    m_beingDestroyed = true;
162
163    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
164    // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
165    children()->destroyLeftoverChildren();
166
167    // Destroy our continuation before anything other than anonymous children.
168    // The reason we don't destroy it before anonymous children is that they may
169    // have continuations of their own that are anonymous children of our continuation.
170    RenderBoxModelObject* continuation = this->continuation();
171    if (continuation) {
172        continuation->destroy();
173        setContinuation(0);
174    }
175
176    if (!documentBeingDestroyed()) {
177        if (firstLineBox()) {
178            // We can't wait for RenderBox::destroy to clear the selection,
179            // because by then we will have nuked the line boxes.
180            // FIXME: The SelectionController should be responsible for this when it
181            // is notified of DOM mutations.
182            if (isSelectionBorder())
183                view()->clearSelection();
184
185            // If we are an anonymous block, then our line boxes might have children
186            // that will outlast this block. In the non-anonymous block case those
187            // children will be destroyed by the time we return from this function.
188            if (isAnonymousBlock()) {
189                for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
190                    while (InlineBox* childBox = box->firstChild())
191                        childBox->remove();
192                }
193            }
194        } else if (isInline() && parent())
195            parent()->dirtyLinesFromChangedChild(this);
196    }
197
198    m_lineBoxes.deleteLineBoxes(renderArena());
199
200    RenderBox::destroy();
201}
202
203void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
204{
205    s_canPropagateFloatIntoSibling = style() ? !isFloatingOrPositioned() && !avoidsFloats() : false;
206
207    setReplaced(newStyle->isDisplayInlineType());
208
209    if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {
210        if (newStyle->position() == StaticPosition)
211            // Clear our positioned objects list. Our absolutely positioned descendants will be
212            // inserted into our containing block's positioned objects list during layout.
213            removePositionedObjects(0);
214        else if (style()->position() == StaticPosition) {
215            // Remove our absolutely positioned descendants from their current containing block.
216            // They will be inserted into our positioned objects list during layout.
217            RenderObject* cb = parent();
218            while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
219                if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
220                    cb = cb->containingBlock();
221                    break;
222                }
223                cb = cb->parent();
224            }
225
226            if (cb->isRenderBlock())
227                toRenderBlock(cb)->removePositionedObjects(this);
228        }
229
230        if (containsFloats() && !isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
231            markAllDescendantsWithFloatsForLayout();
232    }
233
234    RenderBox::styleWillChange(diff, newStyle);
235}
236
237void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
238{
239    RenderBox::styleDidChange(diff, oldStyle);
240
241    if (!isAnonymousBlock()) {
242        // Ensure that all of our continuation blocks pick up the new style.
243        for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
244            RenderBoxModelObject* nextCont = currCont->continuation();
245            currCont->setContinuation(0);
246            currCont->setStyle(style());
247            currCont->setContinuation(nextCont);
248        }
249    }
250
251    // FIXME: We could save this call when the change only affected non-inherited properties
252    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
253        if (child->isAnonymousBlock()) {
254            RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
255            if (style()->specifiesColumns()) {
256                if (child->style()->specifiesColumns())
257                    newStyle->inheritColumnPropertiesFrom(style());
258                if (child->style()->columnSpan())
259                    newStyle->setColumnSpan(true);
260            }
261            newStyle->setDisplay(BLOCK);
262            child->setStyle(newStyle.release());
263        }
264    }
265
266    m_lineHeight = -1;
267
268    // Update pseudos for :before and :after now.
269    if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {
270        updateBeforeAfterContent(BEFORE);
271        updateBeforeAfterContent(AFTER);
272    }
273
274    // After our style changed, if we lose our ability to propagate floats into next sibling
275    // blocks, then we need to find the top most parent containing that overhanging float and
276    // then mark its descendants with floats for layout and clear all floats from its next
277    // sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
278    bool canPropagateFloatIntoSibling = !isFloatingOrPositioned() && !avoidsFloats();
279    if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
280        RenderBlock* parentBlock = this;
281        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
282        FloatingObjectSetIterator end = floatingObjectSet.end();
283
284        for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) {
285            if (curr->isRenderBlock()) {
286                RenderBlock* currBlock = toRenderBlock(curr);
287
288                if (currBlock->hasOverhangingFloats()) {
289                    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
290                        RenderBox* renderer = (*it)->renderer();
291                        if (currBlock->hasOverhangingFloat(renderer)) {
292                            parentBlock = currBlock;
293                            break;
294                        }
295                    }
296                }
297            }
298        }
299
300        parentBlock->markAllDescendantsWithFloatsForLayout();
301        parentBlock->markSiblingsWithFloatsForLayout();
302    }
303}
304
305void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
306{
307    // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
308    if (parent() && parent()->createsAnonymousWrapper())
309        return;
310    return children()->updateBeforeAfterContent(this, pseudoId);
311}
312
313RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
314{
315    if (beforeChild && beforeChild->parent() == this)
316        return this;
317
318    RenderBlock* curr = toRenderBlock(continuation());
319    RenderBlock* nextToLast = this;
320    RenderBlock* last = this;
321    while (curr) {
322        if (beforeChild && beforeChild->parent() == curr) {
323            if (curr->firstChild() == beforeChild)
324                return last;
325            return curr;
326        }
327
328        nextToLast = last;
329        last = curr;
330        curr = toRenderBlock(curr->continuation());
331    }
332
333    if (!beforeChild && !last->firstChild())
334        return nextToLast;
335    return last;
336}
337
338void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
339{
340    RenderBlock* flow = continuationBefore(beforeChild);
341    ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
342    RenderBoxModelObject* beforeChildParent = 0;
343    if (beforeChild)
344        beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
345    else {
346        RenderBoxModelObject* cont = flow->continuation();
347        if (cont)
348            beforeChildParent = cont;
349        else
350            beforeChildParent = flow;
351    }
352
353    if (newChild->isFloatingOrPositioned())
354        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
355
356    // A continuation always consists of two potential candidates: a block or an anonymous
357    // column span box holding column span children.
358    bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
359    bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
360    bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
361
362    if (flow == beforeChildParent)
363        return flow->addChildIgnoringContinuation(newChild, beforeChild);
364
365    // The goal here is to match up if we can, so that we can coalesce and create the
366    // minimal # of continuations needed for the inline.
367    if (childIsNormal == bcpIsNormal)
368        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
369    if (flowIsNormal == childIsNormal)
370        return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
371    return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
372}
373
374
375void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
376{
377    ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
378
379    // The goal is to locate a suitable box in which to place our child.
380    RenderBlock* beforeChildParent = toRenderBlock(beforeChild && beforeChild->parent()->isRenderBlock() ? beforeChild->parent() : lastChild());
381
382    // If the new child is floating or positioned it can just go in that block.
383    if (newChild->isFloatingOrPositioned())
384        return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
385
386    // See if the child can be placed in the box.
387    bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
388    bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
389
390    if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans)
391        return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
392
393    if (!beforeChild) {
394        // Create a new block of the correct type.
395        RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
396        children()->appendChildNode(this, newBox);
397        newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
398        return;
399    }
400
401    RenderObject* immediateChild = beforeChild;
402    bool isPreviousBlockViable = true;
403    while (immediateChild->parent() != this) {
404        if (isPreviousBlockViable)
405            isPreviousBlockViable = !immediateChild->previousSibling();
406        immediateChild = immediateChild->parent();
407    }
408    if (isPreviousBlockViable && immediateChild->previousSibling())
409        return toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
410
411    // Split our anonymous blocks.
412    RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild);
413
414    // Create a new anonymous box of the appropriate type.
415    RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
416    children()->insertChildNode(this, newBox, newBeforeChild);
417    newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
418    return;
419}
420
421RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
422{
423    for (RenderObject* curr = this; curr; curr = curr->parent()) {
424        if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
425            || curr->isInlineBlockOrInlineTable())
426            return 0;
427
428        RenderBlock* currBlock = toRenderBlock(curr);
429        if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
430            return currBlock;
431
432        if (currBlock->isAnonymousColumnSpanBlock())
433            return 0;
434    }
435    return 0;
436}
437
438RenderBlock* RenderBlock::clone() const
439{
440    RenderBlock* cloneBlock;
441    if (isAnonymousBlock())
442        cloneBlock = createAnonymousBlock();
443    else {
444        cloneBlock = new (renderArena()) RenderBlock(node());
445        cloneBlock->setStyle(style());
446    }
447    cloneBlock->setChildrenInline(childrenInline());
448    return cloneBlock;
449}
450
451void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
452                              RenderBlock* middleBlock,
453                              RenderObject* beforeChild, RenderBoxModelObject* oldCont)
454{
455    // Create a clone of this inline.
456    RenderBlock* cloneBlock = clone();
457    if (!isAnonymousBlock())
458        cloneBlock->setContinuation(oldCont);
459
460    // Now take all of the children from beforeChild to the end and remove
461    // them from |this| and place them in the clone.
462    if (!beforeChild && isAfterContent(lastChild()))
463        beforeChild = lastChild();
464    moveChildrenTo(cloneBlock, beforeChild, 0);
465
466    // Hook |clone| up as the continuation of the middle block.
467    if (!cloneBlock->isAnonymousBlock())
468        middleBlock->setContinuation(cloneBlock);
469
470    // We have been reparented and are now under the fromBlock.  We need
471    // to walk up our block parent chain until we hit the containing anonymous columns block.
472    // Once we hit the anonymous columns block we're done.
473    RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
474    RenderBoxModelObject* currChild = this;
475
476    while (curr && curr != fromBlock) {
477        ASSERT(curr->isRenderBlock());
478
479        RenderBlock* blockCurr = toRenderBlock(curr);
480
481        // Create a new clone.
482        RenderBlock* cloneChild = cloneBlock;
483        cloneBlock = blockCurr->clone();
484
485        // Insert our child clone as the first child.
486        cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
487
488        // Hook the clone up as a continuation of |curr|.  Note we do encounter
489        // anonymous blocks possibly as we walk up the block chain.  When we split an
490        // anonymous block, there's no need to do any continuation hookup, since we haven't
491        // actually split a real element.
492        if (!blockCurr->isAnonymousBlock()) {
493            oldCont = blockCurr->continuation();
494            blockCurr->setContinuation(cloneBlock);
495            cloneBlock->setContinuation(oldCont);
496        }
497
498        // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
499        // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
500        // content gets properly destroyed.
501        if (document()->usesBeforeAfterRules())
502            blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
503
504        // Now we need to take all of the children starting from the first child
505        // *after* currChild and append them all to the clone.
506        RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0;
507        blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent);
508
509        // Keep walking up the chain.
510        currChild = curr;
511        curr = toRenderBoxModelObject(curr->parent());
512    }
513
514    // Now we are at the columns block level. We need to put the clone into the toBlock.
515    toBlock->children()->appendChildNode(toBlock, cloneBlock);
516
517    // Now take all the children after currChild and remove them from the fromBlock
518    // and put them in the toBlock.
519    fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0);
520}
521
522void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
523                            RenderObject* newChild, RenderBoxModelObject* oldCont)
524{
525    RenderBlock* pre = 0;
526    RenderBlock* block = containingColumnsBlock();
527
528    // Delete our line boxes before we do the inline split into continuations.
529    block->deleteLineBoxTree();
530
531    bool madeNewBeforeBlock = false;
532    if (block->isAnonymousColumnsBlock()) {
533        // We can reuse this block and make it the preBlock of the next continuation.
534        pre = block;
535        pre->removePositionedObjects(0);
536        block = toRenderBlock(block->parent());
537    } else {
538        // No anonymous block available for use.  Make one.
539        pre = block->createAnonymousColumnsBlock();
540        pre->setChildrenInline(false);
541        madeNewBeforeBlock = true;
542    }
543
544    RenderBlock* post = block->createAnonymousColumnsBlock();
545    post->setChildrenInline(false);
546
547    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
548    if (madeNewBeforeBlock)
549        block->children()->insertChildNode(block, pre, boxFirst);
550    block->children()->insertChildNode(block, newBlockBox, boxFirst);
551    block->children()->insertChildNode(block, post, boxFirst);
552    block->setChildrenInline(false);
553
554    if (madeNewBeforeBlock)
555        block->moveChildrenTo(pre, boxFirst, 0);
556
557    splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
558
559    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
560    // time in makeChildrenNonInline by just setting this explicitly up front.
561    newBlockBox->setChildrenInline(false);
562
563    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
564    // connected, thus allowing newChild access to a renderArena should it need
565    // to wrap itself in additional boxes (e.g., table construction).
566    newBlockBox->addChild(newChild);
567
568    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
569    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
570    // make new line boxes instead of leaving the old line boxes around.
571    pre->setNeedsLayoutAndPrefWidthsRecalc();
572    block->setNeedsLayoutAndPrefWidthsRecalc();
573    post->setNeedsLayoutAndPrefWidthsRecalc();
574}
575
576RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
577{
578    while (beforeChild->parent() != this) {
579        RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
580        if (blockToSplit->firstChild() != beforeChild) {
581            // We have to split the parentBlock into two blocks.
582            RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
583            post->setChildrenInline(blockToSplit->childrenInline());
584            RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent());
585            parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling());
586            blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer());
587            post->setNeedsLayoutAndPrefWidthsRecalc();
588            blockToSplit->setNeedsLayoutAndPrefWidthsRecalc();
589            beforeChild = post;
590        } else
591            beforeChild = blockToSplit;
592    }
593    return beforeChild;
594}
595
596void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
597{
598    RenderBlock* pre = 0;
599    RenderBlock* post = 0;
600    RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
601                               // so that we don't have to patch all of the rest of the code later on.
602
603    // Delete the block's line boxes before we do the split.
604    block->deleteLineBoxTree();
605
606    if (beforeChild && beforeChild->parent() != this)
607        beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
608
609    if (beforeChild != firstChild()) {
610        pre = block->createAnonymousColumnsBlock();
611        pre->setChildrenInline(block->childrenInline());
612    }
613
614    if (beforeChild) {
615        post = block->createAnonymousColumnsBlock();
616        post->setChildrenInline(block->childrenInline());
617    }
618
619    RenderObject* boxFirst = block->firstChild();
620    if (pre)
621        block->children()->insertChildNode(block, pre, boxFirst);
622    block->children()->insertChildNode(block, newBlockBox, boxFirst);
623    if (post)
624        block->children()->insertChildNode(block, post, boxFirst);
625    block->setChildrenInline(false);
626
627    // The pre/post blocks always have layers, so we know to always do a full insert/remove (so we pass true as the last argument).
628    block->moveChildrenTo(pre, boxFirst, beforeChild, true);
629    block->moveChildrenTo(post, beforeChild, 0, true);
630
631    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
632    // time in makeChildrenNonInline by just setting this explicitly up front.
633    newBlockBox->setChildrenInline(false);
634
635    // We delayed adding the newChild until now so that the |newBlockBox| would be fully
636    // connected, thus allowing newChild access to a renderArena should it need
637    // to wrap itself in additional boxes (e.g., table construction).
638    newBlockBox->addChild(newChild);
639
640    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
641    // get deleted properly.  Because objects moved from the pre block into the post block, we want to
642    // make new line boxes instead of leaving the old line boxes around.
643    if (pre)
644        pre->setNeedsLayoutAndPrefWidthsRecalc();
645    block->setNeedsLayoutAndPrefWidthsRecalc();
646    if (post)
647        post->setNeedsLayoutAndPrefWidthsRecalc();
648}
649
650RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
651{
652    // FIXME: This function is the gateway for the addition of column-span support.  It will
653    // be added to in three stages:
654    // (1) Immediate children of a multi-column block can span.
655    // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
656    // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
657    // cross the streams and have to cope with both types of continuations mixed together).
658    // This function currently supports (1) and (2).
659    RenderBlock* columnsBlockAncestor = 0;
660    if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned()
661        && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
662        if (style()->specifiesColumns())
663            columnsBlockAncestor = this;
664        else if (parent() && parent()->isRenderBlock())
665            columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false);
666    }
667    return columnsBlockAncestor;
668}
669
670void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
671{
672    // Make sure we don't append things after :after-generated content if we have it.
673    if (!beforeChild) {
674        RenderObject* lastRenderer = lastChild();
675        if (isAfterContent(lastRenderer))
676            beforeChild = lastRenderer;
677        else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild()))
678            beforeChild = lastRenderer->lastChild();
679    }
680
681    // If the requested beforeChild is not one of our children, then this is because
682    // there is an anonymous container within this object that contains the beforeChild.
683    if (beforeChild && beforeChild->parent() != this) {
684        RenderObject* anonymousChild = beforeChild->parent();
685        ASSERT(anonymousChild);
686
687        while (anonymousChild->parent() != this)
688            anonymousChild = anonymousChild->parent();
689
690        ASSERT(anonymousChild->isAnonymous());
691
692        if (anonymousChild->isAnonymousBlock()) {
693            // Insert the child into the anonymous block box instead of here.
694            if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
695                beforeChild->parent()->addChild(newChild, beforeChild);
696            else
697                addChild(newChild, beforeChild->parent());
698            return;
699        }
700
701        ASSERT(anonymousChild->isTable());
702        if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
703                || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
704                || newChild->isTableSection()
705                || newChild->isTableRow()
706                || newChild->isTableCell()) {
707            // Insert into the anonymous table.
708            anonymousChild->addChild(newChild, beforeChild);
709            return;
710        }
711
712        // Go on to insert before the anonymous table.
713        beforeChild = anonymousChild;
714    }
715
716    // Check for a spanning element in columns.
717    RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
718    if (columnsBlockAncestor) {
719        // We are placing a column-span element inside a block.
720        RenderBlock* newBox = createAnonymousColumnSpanBlock();
721
722        if (columnsBlockAncestor != this) {
723            // We are nested inside a multi-column element and are being split by the span.  We have to break up
724            // our block into continuations.
725            RenderBoxModelObject* oldContinuation = continuation();
726            setContinuation(newBox);
727
728            // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
729            // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
730            // content gets properly destroyed.
731            bool isLastChild = (beforeChild == lastChild());
732            if (document()->usesBeforeAfterRules())
733                children()->updateBeforeAfterContent(this, AFTER);
734            if (isLastChild && beforeChild != lastChild())
735                beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
736                                 // point to be 0.  It's just a straight append now.
737
738            splitFlow(beforeChild, newBox, newChild, oldContinuation);
739            return;
740        }
741
742        // We have to perform a split of this block's children.  This involves creating an anonymous block box to hold
743        // the column-spanning |newChild|.  We take all of the children from before |newChild| and put them into
744        // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
745        makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
746        return;
747    }
748
749    bool madeBoxesNonInline = false;
750
751    // A block has to either have all of its children inline, or all of its children as blocks.
752    // So, if our children are currently inline and a block child has to be inserted, we move all our
753    // inline children into anonymous block boxes.
754    if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
755        // This is a block with inline content. Wrap the inline content in anonymous blocks.
756        makeChildrenNonInline(beforeChild);
757        madeBoxesNonInline = true;
758
759        if (beforeChild && beforeChild->parent() != this) {
760            beforeChild = beforeChild->parent();
761            ASSERT(beforeChild->isAnonymousBlock());
762            ASSERT(beforeChild->parent() == this);
763        }
764    } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
765        // If we're inserting an inline child but all of our children are blocks, then we have to make sure
766        // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
767        // a new one is created and inserted into our list of children in the appropriate position.
768        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
769
770        if (afterChild && afterChild->isAnonymousBlock()) {
771            afterChild->addChild(newChild);
772            return;
773        }
774
775        if (newChild->isInline()) {
776            // No suitable existing anonymous box - create a new one.
777            RenderBlock* newBox = createAnonymousBlock();
778            RenderBox::addChild(newBox, beforeChild);
779            newBox->addChild(newChild);
780            return;
781        }
782    }
783
784    RenderBox::addChild(newChild, beforeChild);
785
786    if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
787        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
788    // this object may be dead here
789}
790
791void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
792{
793    if (continuation() && !isAnonymousBlock())
794        return addChildToContinuation(newChild, beforeChild);
795    return addChildIgnoringContinuation(newChild, beforeChild);
796}
797
798void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
799{
800    if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
801        return addChildToAnonymousColumnBlocks(newChild, beforeChild);
802    return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
803}
804
805static void getInlineRun(RenderObject* start, RenderObject* boundary,
806                         RenderObject*& inlineRunStart,
807                         RenderObject*& inlineRunEnd)
808{
809    // Beginning at |start| we find the largest contiguous run of inlines that
810    // we can.  We denote the run with start and end points, |inlineRunStart|
811    // and |inlineRunEnd|.  Note that these two values may be the same if
812    // we encounter only one inline.
813    //
814    // We skip any non-inlines we encounter as long as we haven't found any
815    // inlines yet.
816    //
817    // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
818    // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
819    // a non-inline.
820
821    // Start by skipping as many non-inlines as we can.
822    RenderObject * curr = start;
823    bool sawInline;
824    do {
825        while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
826            curr = curr->nextSibling();
827
828        inlineRunStart = inlineRunEnd = curr;
829
830        if (!curr)
831            return; // No more inline children to be found.
832
833        sawInline = curr->isInline();
834
835        curr = curr->nextSibling();
836        while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
837            inlineRunEnd = curr;
838            if (curr->isInline())
839                sawInline = true;
840            curr = curr->nextSibling();
841        }
842    } while (!sawInline);
843}
844
845void RenderBlock::deleteLineBoxTree()
846{
847    m_lineBoxes.deleteLineBoxTree(renderArena());
848}
849
850RootInlineBox* RenderBlock::createRootInlineBox()
851{
852    return new (renderArena()) RootInlineBox(this);
853}
854
855RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
856{
857    RootInlineBox* rootBox = createRootInlineBox();
858    m_lineBoxes.appendLineBox(rootBox);
859    return rootBox;
860}
861
862void RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
863{
864    ASSERT(this == child->parent());
865    ASSERT(!beforeChild || to == beforeChild->parent());
866    to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
867}
868
869void RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
870{
871    ASSERT(!beforeChild || to == beforeChild->parent());
872    RenderObject* nextChild = startChild;
873    while (nextChild && nextChild != endChild) {
874        RenderObject* child = nextChild;
875        nextChild = child->nextSibling();
876        to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
877        if (child == endChild)
878            return;
879    }
880}
881
882void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
883{
884    // makeChildrenNonInline takes a block whose children are *all* inline and it
885    // makes sure that inline children are coalesced under anonymous
886    // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
887    // the new block child that is causing us to have to wrap all the inlines.  This
888    // means that we cannot coalesce inlines before |insertionPoint| with inlines following
889    // |insertionPoint|, because the new child is going to be inserted in between the inlines,
890    // splitting them.
891    ASSERT(isInlineBlockOrInlineTable() || !isInline());
892    ASSERT(!insertionPoint || insertionPoint->parent() == this);
893
894    setChildrenInline(false);
895
896    RenderObject *child = firstChild();
897    if (!child)
898        return;
899
900    deleteLineBoxTree();
901
902    while (child) {
903        RenderObject *inlineRunStart, *inlineRunEnd;
904        getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
905
906        if (!inlineRunStart)
907            break;
908
909        child = inlineRunEnd->nextSibling();
910
911        RenderBlock* block = createAnonymousBlock();
912        children()->insertChildNode(this, block, inlineRunStart);
913        moveChildrenTo(block, inlineRunStart, child);
914    }
915
916#ifndef NDEBUG
917    for (RenderObject *c = firstChild(); c; c = c->nextSibling())
918        ASSERT(!c->isInline());
919#endif
920
921    repaint();
922}
923
924void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
925{
926    ASSERT(child->isAnonymousBlock());
927    ASSERT(!child->childrenInline());
928
929    if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
930        return;
931
932    RenderObject* firstAnChild = child->m_children.firstChild();
933    RenderObject* lastAnChild = child->m_children.lastChild();
934    if (firstAnChild) {
935        RenderObject* o = firstAnChild;
936        while (o) {
937            o->setParent(this);
938            o = o->nextSibling();
939        }
940        firstAnChild->setPreviousSibling(child->previousSibling());
941        lastAnChild->setNextSibling(child->nextSibling());
942        if (child->previousSibling())
943            child->previousSibling()->setNextSibling(firstAnChild);
944        if (child->nextSibling())
945            child->nextSibling()->setPreviousSibling(lastAnChild);
946
947        if (child == m_children.firstChild())
948            m_children.setFirstChild(firstAnChild);
949        if (child == m_children.lastChild())
950            m_children.setLastChild(lastAnChild);
951    } else {
952        if (child == m_children.firstChild())
953            m_children.setFirstChild(child->nextSibling());
954        if (child == m_children.lastChild())
955            m_children.setLastChild(child->previousSibling());
956
957        if (child->previousSibling())
958            child->previousSibling()->setNextSibling(child->nextSibling());
959        if (child->nextSibling())
960            child->nextSibling()->setPreviousSibling(child->previousSibling());
961    }
962    child->setParent(0);
963    child->setPreviousSibling(0);
964    child->setNextSibling(0);
965
966    child->children()->setFirstChild(0);
967    child->m_next = 0;
968
969    child->destroy();
970}
971
972static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
973{
974    if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
975        return false;
976
977    if (oldChild->parent() && oldChild->parent()->isDetails())
978        return false;
979
980    if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
981        || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
982        return false;
983
984    // FIXME: This check isn't required when inline run-ins can't be split into continuations.
985    if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
986        return false;
987
988    if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
989        || (next && (next->isRubyRun() || next->isRubyBase())))
990        return false;
991
992    if (!prev || !next)
993        return true;
994
995    // Make sure the types of the anonymous blocks match up.
996    return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
997           && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
998}
999
1000void RenderBlock::removeChild(RenderObject* oldChild)
1001{
1002    // If this child is a block, and if our previous and next siblings are
1003    // both anonymous blocks with inline content, then we can go ahead and
1004    // fold the inline content back together.
1005    RenderObject* prev = oldChild->previousSibling();
1006    RenderObject* next = oldChild->nextSibling();
1007    bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
1008    if (canMergeAnonymousBlocks && prev && next) {
1009        prev->setNeedsLayoutAndPrefWidthsRecalc();
1010        RenderBlock* nextBlock = toRenderBlock(next);
1011        RenderBlock* prevBlock = toRenderBlock(prev);
1012
1013        if (prev->childrenInline() != next->childrenInline()) {
1014            RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
1015            RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
1016
1017            // Place the inline children block inside of the block children block instead of deleting it.
1018            // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
1019            // to clear out inherited column properties by just making a new style, and to also clear the
1020            // column span flag if it is set.
1021            ASSERT(!inlineChildrenBlock->continuation());
1022            RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
1023            children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
1024            inlineChildrenBlock->setStyle(newStyle);
1025
1026            // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
1027            blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
1028                                                            inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer());
1029            next->setNeedsLayoutAndPrefWidthsRecalc();
1030
1031            // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
1032            // of "this". we null out prev or next so that is not used later in the function.
1033            if (inlineChildrenBlock == prevBlock)
1034                prev = 0;
1035            else
1036                next = 0;
1037        } else {
1038            // Take all the children out of the |next| block and put them in
1039            // the |prev| block.
1040            nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
1041
1042            // Delete the now-empty block's lines and nuke it.
1043            nextBlock->deleteLineBoxTree();
1044            nextBlock->destroy();
1045            next = 0;
1046        }
1047    }
1048
1049    RenderBox::removeChild(oldChild);
1050
1051    RenderObject* child = prev ? prev : next;
1052    if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
1053        // The removal has knocked us down to containing only a single anonymous
1054        // box.  We can go ahead and pull the content right back up into our
1055        // box.
1056        setNeedsLayoutAndPrefWidthsRecalc();
1057        setChildrenInline(child->childrenInline());
1058        RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer()));
1059        anonBlock->moveAllChildrenTo(this, child->hasLayer());
1060        // Delete the now-empty block's lines and nuke it.
1061        anonBlock->deleteLineBoxTree();
1062        anonBlock->destroy();
1063    }
1064
1065    if (!firstChild() && !documentBeingDestroyed()) {
1066        // If this was our last child be sure to clear out our line boxes.
1067        if (childrenInline())
1068            lineBoxes()->deleteLineBoxes(renderArena());
1069    }
1070}
1071
1072bool RenderBlock::isSelfCollapsingBlock() const
1073{
1074    // We are not self-collapsing if we
1075    // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
1076    // (b) are a table,
1077    // (c) have border/padding,
1078    // (d) have a min-height
1079    // (e) have specified that one of our margins can't collapse using a CSS extension
1080    if (logicalHeight() > 0
1081        || isTable() || borderAndPaddingLogicalHeight()
1082        || style()->logicalMinHeight().isPositive()
1083        || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
1084        return false;
1085
1086    Length logicalHeightLength = style()->logicalHeight();
1087    bool hasAutoHeight = logicalHeightLength.isAuto();
1088    if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) {
1089        hasAutoHeight = true;
1090        for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
1091            if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
1092                hasAutoHeight = false;
1093        }
1094    }
1095
1096    // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
1097    // on whether we have content that is all self-collapsing or not.
1098    if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
1099        // If the block has inline children, see if we generated any line boxes.  If we have any
1100        // line boxes, then we can't be self-collapsing, since we have content.
1101        if (childrenInline())
1102            return !firstLineBox();
1103
1104        // Whether or not we collapse is dependent on whether all our normal flow children
1105        // are also self-collapsing.
1106        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1107            if (child->isFloatingOrPositioned())
1108                continue;
1109            if (!child->isSelfCollapsingBlock())
1110                return false;
1111        }
1112        return true;
1113    }
1114    return false;
1115}
1116
1117void RenderBlock::startDelayUpdateScrollInfo()
1118{
1119    if (gDelayUpdateScrollInfo == 0) {
1120        ASSERT(!gDelayedUpdateScrollInfoSet);
1121        gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
1122    }
1123    ASSERT(gDelayedUpdateScrollInfoSet);
1124    ++gDelayUpdateScrollInfo;
1125}
1126
1127void RenderBlock::finishDelayUpdateScrollInfo()
1128{
1129    --gDelayUpdateScrollInfo;
1130    ASSERT(gDelayUpdateScrollInfo >= 0);
1131    if (gDelayUpdateScrollInfo == 0) {
1132        ASSERT(gDelayedUpdateScrollInfoSet);
1133
1134        OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
1135        gDelayedUpdateScrollInfoSet = 0;
1136
1137        for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
1138            RenderBlock* block = *it;
1139            if (block->hasOverflowClip()) {
1140                block->layer()->updateScrollInfoAfterLayout();
1141            }
1142        }
1143    }
1144}
1145
1146void RenderBlock::updateScrollInfoAfterLayout()
1147{
1148    if (hasOverflowClip()) {
1149        if (gDelayUpdateScrollInfo)
1150            gDelayedUpdateScrollInfoSet->add(this);
1151        else
1152            layer()->updateScrollInfoAfterLayout();
1153    }
1154}
1155
1156void RenderBlock::layout()
1157{
1158    // Update our first letter info now.
1159    updateFirstLetter();
1160
1161    // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
1162    // layoutBlock().
1163    layoutBlock(false);
1164
1165    // It's safe to check for control clip here, since controls can never be table cells.
1166    // If we have a lightweight clip, there can never be any overflow from children.
1167    if (hasControlClip() && m_overflow)
1168        clearLayoutOverflow();
1169}
1170
1171void RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
1172{
1173    ASSERT(needsLayout());
1174
1175    if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
1176        return;                                      // cause us to come in here.  Just bail.
1177
1178    if (!relayoutChildren && simplifiedLayout())
1179        return;
1180
1181    LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
1182
1183    int oldWidth = logicalWidth();
1184    int oldColumnWidth = desiredColumnWidth();
1185
1186    computeLogicalWidth();
1187    calcColumnWidth();
1188
1189    m_overflow.clear();
1190
1191    if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth())
1192        relayoutChildren = true;
1193
1194#ifdef ANDROID_LAYOUT
1195    checkAndSetRelayoutChildren(&relayoutChildren);
1196#endif
1197
1198    clearFloats();
1199
1200    int previousHeight = logicalHeight();
1201    setLogicalHeight(0);
1202    bool hasSpecifiedPageLogicalHeight = false;
1203    bool pageLogicalHeightChanged = false;
1204    ColumnInfo* colInfo = columnInfo();
1205    if (hasColumns()) {
1206        if (!pageLogicalHeight) {
1207            // We need to go ahead and set our explicit page height if one exists, so that we can
1208            // avoid doing two layout passes.
1209            computeLogicalHeight();
1210            int columnHeight = contentLogicalHeight();
1211            if (columnHeight > 0) {
1212                pageLogicalHeight = columnHeight;
1213                hasSpecifiedPageLogicalHeight = true;
1214            }
1215            setLogicalHeight(0);
1216        }
1217        if (colInfo->columnHeight() != pageLogicalHeight && m_everHadLayout) {
1218            colInfo->setColumnHeight(pageLogicalHeight);
1219            pageLogicalHeightChanged = true;
1220        }
1221
1222        if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
1223            colInfo->clearForcedBreaks();
1224    }
1225
1226    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo);
1227
1228    // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
1229    // our current maximal positive and negative margins.  These values are used when we
1230    // are collapsed with adjacent blocks, so for example, if you have block A and B
1231    // collapsing together, then you'd take the maximal positive margin from both A and B
1232    // and subtract it from the maximal negative margin from both A and B to get the
1233    // true collapsed margin.  This algorithm is recursive, so when we finish layout()
1234    // our block knows its current maximal positive/negative values.
1235    //
1236    // Start out by setting our margin values to our current margins.  Table cells have
1237    // no margins, so we don't fill in the values for table cells.
1238    bool isCell = isTableCell();
1239    if (!isCell) {
1240        initMaxMarginValues();
1241
1242        setMarginBeforeQuirk(style()->marginBefore().quirk());
1243        setMarginAfterQuirk(style()->marginAfter().quirk());
1244
1245        Node* n = node();
1246        if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
1247            // See if this form is malformed (i.e., unclosed). If so, don't give the form
1248            // a bottom margin.
1249            setMaxMarginAfterValues(0, 0);
1250        }
1251
1252        setPaginationStrut(0);
1253    }
1254
1255    // For overflow:scroll blocks, ensure we have both scrollbars in place always.
1256    if (scrollsOverflow()) {
1257        if (style()->overflowX() == OSCROLL)
1258            layer()->setHasHorizontalScrollbar(true);
1259        if (style()->overflowY() == OSCROLL)
1260            layer()->setHasVerticalScrollbar(true);
1261    }
1262
1263    int repaintLogicalTop = 0;
1264    int repaintLogicalBottom = 0;
1265    int maxFloatLogicalBottom = 0;
1266    if (!firstChild() && !isAnonymousBlock())
1267        setChildrenInline(true);
1268    if (childrenInline())
1269        layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
1270    else
1271        layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
1272
1273    // Expand our intrinsic height to encompass floats.
1274    int toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
1275    if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
1276        setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
1277
1278    if (layoutColumns(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
1279        return;
1280
1281    // Calculate our new height.
1282    int oldHeight = logicalHeight();
1283    int oldClientAfterEdge = clientLogicalBottom();
1284    computeLogicalHeight();
1285    int newHeight = logicalHeight();
1286    if (oldHeight != newHeight) {
1287        if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
1288            // One of our children's floats may have become an overhanging float for us. We need to look for it.
1289            for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
1290                if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
1291                    RenderBlock* block = toRenderBlock(child);
1292                    if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
1293                        addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false);
1294                }
1295            }
1296        }
1297    }
1298
1299    if (previousHeight != newHeight)
1300        relayoutChildren = true;
1301
1302    layoutPositionedObjects(relayoutChildren || isRoot());
1303
1304    // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
1305    computeOverflow(oldClientAfterEdge);
1306
1307    statePusher.pop();
1308
1309    if (view()->layoutState()->m_pageLogicalHeight)
1310        setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
1311
1312    updateLayerTransform();
1313
1314    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
1315    // we overflow or not.
1316    updateScrollInfoAfterLayout();
1317
1318    // Repaint with our new bounds if they are different from our old bounds.
1319    bool didFullRepaint = repainter.repaintAfterLayout();
1320    if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
1321        // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
1322        // it had to lay out.  We wouldn't need the hasOverflowClip() hack in that case either.
1323        int repaintLogicalLeft = logicalLeftVisualOverflow();
1324        int repaintLogicalRight = logicalRightVisualOverflow();
1325        if (hasOverflowClip()) {
1326            // If we have clipped overflow, we should use layout overflow as well, since visual overflow from lines didn't propagate to our block's overflow.
1327            // Note the old code did this as well but even for overflow:visible.  The addition of hasOverflowClip() at least tightens up the hack a bit.
1328            // layoutInlineChildren should be patched to compute the entire repaint rect.
1329            repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
1330            repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
1331        }
1332
1333        IntRect repaintRect;
1334        if (isHorizontalWritingMode())
1335            repaintRect = IntRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
1336        else
1337            repaintRect = IntRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
1338
1339        // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
1340        adjustRectForColumns(repaintRect);
1341
1342        repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
1343
1344        if (hasOverflowClip()) {
1345            // Adjust repaint rect for scroll offset
1346            repaintRect.move(-layer()->scrolledContentOffset());
1347
1348            // Don't allow this rect to spill out of our overflow box.
1349            repaintRect.intersect(IntRect(0, 0, width(), height()));
1350        }
1351
1352        // Make sure the rect is still non-empty after intersecting for overflow above
1353        if (!repaintRect.isEmpty()) {
1354            repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
1355            if (hasReflection())
1356                repaintRectangle(reflectedRect(repaintRect));
1357        }
1358    }
1359    setNeedsLayout(false);
1360}
1361
1362void RenderBlock::addOverflowFromChildren()
1363{
1364    if (!hasColumns()) {
1365        if (childrenInline())
1366            addOverflowFromInlineChildren();
1367        else
1368            addOverflowFromBlockChildren();
1369    } else {
1370        ColumnInfo* colInfo = columnInfo();
1371        if (columnCount(colInfo)) {
1372            IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
1373            if (isHorizontalWritingMode()) {
1374                int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
1375                int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0;
1376                int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
1377                addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
1378                if (!hasOverflowClip())
1379                    addVisualOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
1380            } else {
1381                IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
1382                int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
1383                int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0;
1384                int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
1385                addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
1386                if (!hasOverflowClip())
1387                    addVisualOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
1388            }
1389        }
1390    }
1391}
1392
1393void RenderBlock::computeOverflow(int oldClientAfterEdge, bool recomputeFloats)
1394{
1395    // Add overflow from children.
1396    addOverflowFromChildren();
1397
1398    if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
1399        addOverflowFromFloats();
1400
1401    // Add in the overflow from positioned objects.
1402    addOverflowFromPositionedObjects();
1403
1404    if (hasOverflowClip()) {
1405        // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1406        // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1407        // be considered reachable.
1408        IntRect clientRect(clientBoxRect());
1409        IntRect rectToApply;
1410        if (isHorizontalWritingMode())
1411            rectToApply = IntRect(clientRect.x(), clientRect.y(), 1, max(0, oldClientAfterEdge - clientRect.y()));
1412        else
1413            rectToApply = IntRect(clientRect.x(), clientRect.y(), max(0, oldClientAfterEdge - clientRect.x()), 1);
1414        addLayoutOverflow(rectToApply);
1415    }
1416
1417    // Add visual overflow from box-shadow and reflections.
1418    addShadowOverflow();
1419}
1420
1421void RenderBlock::addOverflowFromBlockChildren()
1422{
1423    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1424        if (!child->isFloatingOrPositioned())
1425            addOverflowFromChild(child);
1426    }
1427}
1428
1429void RenderBlock::addOverflowFromFloats()
1430{
1431    if (!m_floatingObjects)
1432        return;
1433
1434    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1435    FloatingObjectSetIterator end = floatingObjectSet.end();
1436    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
1437        FloatingObject* r = *it;
1438        if (r->m_isDescendant)
1439            addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
1440    }
1441    return;
1442}
1443
1444void RenderBlock::addOverflowFromPositionedObjects()
1445{
1446    if (!m_positionedObjects)
1447        return;
1448
1449    RenderBox* positionedObject;
1450    Iterator end = m_positionedObjects->end();
1451    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
1452        positionedObject = *it;
1453
1454        // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1455        if (positionedObject->style()->position() != FixedPosition)
1456            addOverflowFromChild(positionedObject);
1457    }
1458}
1459
1460bool RenderBlock::expandsToEncloseOverhangingFloats() const
1461{
1462    return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox())
1463           || hasColumns() || isTableCell() || isFieldset() || isWritingModeRoot();
1464}
1465
1466void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
1467{
1468    bool isHorizontal = isHorizontalWritingMode();
1469    bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
1470    RenderLayer* childLayer = child->layer();
1471
1472    childLayer->setStaticInlinePosition(borderAndPaddingStart());
1473
1474    int logicalTop = logicalHeight();
1475    if (!marginInfo.canCollapseWithMarginBefore()) {
1476        child->computeBlockDirectionMargins(this);
1477        int marginBefore = marginBeforeForChild(child);
1478        int collapsedBeforePos = marginInfo.positiveMargin();
1479        int collapsedBeforeNeg = marginInfo.negativeMargin();
1480        if (marginBefore > 0) {
1481            if (marginBefore > collapsedBeforePos)
1482                collapsedBeforePos = marginBefore;
1483        } else {
1484            if (-marginBefore > collapsedBeforeNeg)
1485                collapsedBeforeNeg = -marginBefore;
1486        }
1487        logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
1488    }
1489    if (childLayer->staticBlockPosition() != logicalTop) {
1490        childLayer->setStaticBlockPosition(logicalTop);
1491        if (hasStaticBlockPosition)
1492            child->setChildNeedsLayout(true, false);
1493    }
1494}
1495
1496void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
1497{
1498    // The float should be positioned taking into account the bottom margin
1499    // of the previous flow.  We add that margin into the height, get the
1500    // float positioned properly, and then subtract the margin out of the
1501    // height again.  In the case of self-collapsing blocks, we always just
1502    // use the top margins, since the self-collapsing block collapsed its
1503    // own bottom margin into its top margin.
1504    //
1505    // Note also that the previous flow may collapse its margin into the top of
1506    // our block.  If this is the case, then we do not add the margin in to our
1507    // height when computing the position of the float.   This condition can be tested
1508    // for by simply calling canCollapseWithMarginBefore.  See
1509    // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
1510    // an example of this scenario.
1511    int marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin();
1512    setLogicalHeight(logicalHeight() + marginOffset);
1513    positionNewFloats();
1514    setLogicalHeight(logicalHeight() - marginOffset);
1515}
1516
1517bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
1518{
1519    // Handle in the given order
1520    return handlePositionedChild(child, marginInfo)
1521        || handleFloatingChild(child, marginInfo)
1522        || handleRunInChild(child);
1523}
1524
1525
1526bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
1527{
1528    if (child->isPositioned()) {
1529        child->containingBlock()->insertPositionedObject(child);
1530        adjustPositionedBlock(child, marginInfo);
1531        return true;
1532    }
1533    return false;
1534}
1535
1536bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
1537{
1538    if (child->isFloating()) {
1539        insertFloatingObject(child);
1540        adjustFloatingBlock(marginInfo);
1541        return true;
1542    }
1543    return false;
1544}
1545
1546bool RenderBlock::handleRunInChild(RenderBox* child)
1547{
1548    // See if we have a run-in element with inline children.  If the
1549    // children aren't inline, then just treat the run-in as a normal
1550    // block.
1551    if (!child->isRunIn() || !child->childrenInline())
1552        return false;
1553    // FIXME: We don't handle non-block elements with run-in for now.
1554    if (!child->isRenderBlock())
1555        return false;
1556
1557    RenderBlock* blockRunIn = toRenderBlock(child);
1558    RenderObject* curr = blockRunIn->nextSibling();
1559    if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned())
1560        return false;
1561
1562    RenderBlock* currBlock = toRenderBlock(curr);
1563
1564    // First we destroy any :before/:after content. It will be regenerated by the new inline.
1565    // Exception is if the run-in itself is generated.
1566    if (child->style()->styleType() != BEFORE && child->style()->styleType() != AFTER) {
1567        RenderObject* generatedContent;
1568        if (child->getCachedPseudoStyle(BEFORE) && (generatedContent = child->beforePseudoElementRenderer()))
1569            generatedContent->destroy();
1570        if (child->getCachedPseudoStyle(AFTER) && (generatedContent = child->afterPseudoElementRenderer()))
1571            generatedContent->destroy();
1572    }
1573
1574    // Remove the old child.
1575    children()->removeChildNode(this, blockRunIn);
1576
1577    // Create an inline.
1578    Node* runInNode = blockRunIn->node();
1579    RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
1580    inlineRunIn->setStyle(blockRunIn->style());
1581
1582    // Move the nodes from the old child to the new child
1583    for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) {
1584        RenderObject* nextSibling = runInChild->nextSibling();
1585        blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
1586        inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
1587        runInChild = nextSibling;
1588    }
1589
1590    // Now insert the new child under |currBlock|. Use addChild instead of insertChildNode since it handles correct placement of the children, esp where we cannot insert
1591    // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
1592    currBlock->addChild(inlineRunIn, currBlock->firstChild());
1593
1594    // If the run-in had an element, we need to set the new renderer.
1595    if (runInNode)
1596        runInNode->setRenderer(inlineRunIn);
1597
1598    // Destroy the block run-in, which includes deleting its line box tree.
1599    blockRunIn->deleteLineBoxTree();
1600    blockRunIn->destroy();
1601
1602    // The block acts like an inline, so just null out its
1603    // position.
1604
1605    return true;
1606}
1607
1608int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
1609{
1610    // Get the four margin values for the child and cache them.
1611    const MarginValues childMargins = marginValuesForChild(child);
1612
1613    // Get our max pos and neg top margins.
1614    int posTop = childMargins.positiveMarginBefore();
1615    int negTop = childMargins.negativeMarginBefore();
1616
1617    // For self-collapsing blocks, collapse our bottom margins into our
1618    // top to get new posTop and negTop values.
1619    if (child->isSelfCollapsingBlock()) {
1620        posTop = max(posTop, childMargins.positiveMarginAfter());
1621        negTop = max(negTop, childMargins.negativeMarginAfter());
1622    }
1623
1624    // See if the top margin is quirky. We only care if this child has
1625    // margins that will collapse with us.
1626    bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD;
1627
1628    if (marginInfo.canCollapseWithMarginBefore()) {
1629        // This child is collapsing with the top of the
1630        // block.  If it has larger margin values, then we need to update
1631        // our own maximal values.
1632        if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
1633            setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
1634
1635        // The minute any of the margins involved isn't a quirk, don't
1636        // collapse it away, even if the margin is smaller (www.webreference.com
1637        // has an example of this, a <dt> with 0.8em author-specified inside
1638        // a <dl> inside a <td>.
1639        if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
1640            setMarginBeforeQuirk(false);
1641            marginInfo.setDeterminedMarginBeforeQuirk(true);
1642        }
1643
1644        if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
1645            // We have no top margin and our top child has a quirky margin.
1646            // We will pick up this quirky margin and pass it through.
1647            // This deals with the <td><div><p> case.
1648            // Don't do this for a block that split two inlines though.  You do
1649            // still apply margins in this case.
1650            setMarginBeforeQuirk(true);
1651    }
1652
1653    if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
1654        marginInfo.setMarginBeforeQuirk(topQuirk);
1655
1656    int beforeCollapseLogicalTop = logicalHeight();
1657    int logicalTop = beforeCollapseLogicalTop;
1658    if (child->isSelfCollapsingBlock()) {
1659        // This child has no height.  We need to compute our
1660        // position before we collapse the child's margins together,
1661        // so that we can get an accurate position for the zero-height block.
1662        int collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
1663        int collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
1664        marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
1665
1666        // Now collapse the child's margins together, which means examining our
1667        // bottom margin values as well.
1668        marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
1669        marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
1670
1671        if (!marginInfo.canCollapseWithMarginBefore())
1672            // We need to make sure that the position of the self-collapsing block
1673            // is correct, since it could have overflowing content
1674            // that needs to be positioned correctly (e.g., a block that
1675            // had a specified height of 0 but that actually had subcontent).
1676            logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
1677    }
1678    else {
1679        if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1680            setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child));
1681            logicalTop = logicalHeight();
1682        }
1683        else if (!marginInfo.atBeforeSideOfBlock() ||
1684            (!marginInfo.canCollapseMarginBeforeWithChildren()
1685             && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) {
1686            // We're collapsing with a previous sibling's margins and not
1687            // with the top of the block.
1688            setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
1689            logicalTop = logicalHeight();
1690        }
1691
1692        marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1693        marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1694
1695        if (marginInfo.margin())
1696            marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD);
1697    }
1698
1699    // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
1700    // collapsed into the page edge.
1701    bool paginated = view()->layoutState()->isPaginated();
1702    if (paginated && logicalTop > beforeCollapseLogicalTop) {
1703        int oldLogicalTop = logicalTop;
1704        logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
1705        setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
1706    }
1707    return logicalTop;
1708}
1709
1710int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
1711{
1712    int heightIncrease = getClearDelta(child, yPos);
1713    if (!heightIncrease)
1714        return yPos;
1715
1716    if (child->isSelfCollapsingBlock()) {
1717        // For self-collapsing blocks that clear, they can still collapse their
1718        // margins with following siblings.  Reset the current margins to represent
1719        // the self-collapsing block's margins only.
1720        // CSS2.1 states:
1721        // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
1722        // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
1723        // self-collapsing block's bottom margin.
1724        bool atBottomOfBlock = true;
1725        for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
1726            if (!curr->isFloatingOrPositioned())
1727                atBottomOfBlock = false;
1728        }
1729
1730        MarginValues childMargins = marginValuesForChild(child);
1731        if (atBottomOfBlock) {
1732            marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1733            marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1734        } else {
1735            marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
1736            marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
1737        }
1738
1739        // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
1740        // of the parent block).
1741        setLogicalHeight(child->y() - max(0, marginInfo.margin()));
1742    } else
1743        // Increase our height by the amount we had to clear.
1744        setLogicalHeight(height() + heightIncrease);
1745
1746    if (marginInfo.canCollapseWithMarginBefore()) {
1747        // We can no longer collapse with the top of the block since a clear
1748        // occurred.  The empty blocks collapse into the cleared block.
1749        // FIXME: This isn't quite correct.  Need clarification for what to do
1750        // if the height the cleared block is offset by is smaller than the
1751        // margins involved.
1752        setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
1753        marginInfo.setAtBeforeSideOfBlock(false);
1754    }
1755
1756    return yPos + heightIncrease;
1757}
1758
1759int RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo)
1760{
1761    // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
1762    // relayout if there are intruding floats.
1763    int logicalTopEstimate = logicalHeight();
1764    if (!marginInfo.canCollapseWithMarginBefore()) {
1765        int childMarginBefore = child->selfNeedsLayout() ? marginBeforeForChild(child) : collapsedMarginBeforeForChild(child);
1766        logicalTopEstimate += max(marginInfo.margin(), childMarginBefore);
1767    }
1768
1769    bool paginated = view()->layoutState()->isPaginated();
1770
1771    // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
1772    // page.
1773    if (paginated && logicalTopEstimate > logicalHeight())
1774        logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
1775
1776    logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
1777
1778    if (paginated) {
1779        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1780        logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
1781
1782        // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1783        logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
1784
1785        if (!child->selfNeedsLayout() && child->isRenderBlock())
1786            logicalTopEstimate += toRenderBlock(child)->paginationStrut();
1787    }
1788
1789    return logicalTopEstimate;
1790}
1791
1792void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child)
1793{
1794    int startPosition = borderStart() + paddingStart();
1795    int totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
1796
1797    // Add in our start margin.
1798    int childMarginStart = marginStartForChild(child);
1799    int newPosition = startPosition + childMarginStart;
1800
1801    // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
1802    // to shift over as necessary to dodge any floats that might get in the way.
1803    if (child->avoidsFloats()) {
1804        int startOff = style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(logicalHeight(), false) : totalAvailableLogicalWidth - logicalRightOffsetForLine(logicalHeight(), false);
1805        if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
1806            if (childMarginStart < 0)
1807                startOff += childMarginStart;
1808            newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
1809        } else if (startOff != startPosition) {
1810            // The object is shifting to the "end" side of the block. The object might be centered, so we need to
1811            // recalculate our inline direction margins. Note that the containing block content
1812            // width computation will take into account the delta between |startOff| and |startPosition|
1813            // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection|
1814            // function.
1815            child->computeInlineDirectionMargins(this, availableLogicalWidthForLine(logicalTopForChild(child), false), logicalWidthForChild(child));
1816            newPosition = startOff + marginStartForChild(child);
1817        }
1818    }
1819
1820    setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta);
1821}
1822
1823void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
1824{
1825    if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
1826        // Update our max pos/neg bottom margins, since we collapsed our bottom margins
1827        // with our children.
1828        setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
1829
1830        if (!marginInfo.marginAfterQuirk())
1831            setMarginAfterQuirk(false);
1832
1833        if (marginInfo.marginAfterQuirk() && marginAfter() == 0)
1834            // We have no bottom margin and our last child has a quirky margin.
1835            // We will pick up this quirky margin and pass it through.
1836            // This deals with the <td><div><p> case.
1837            setMarginAfterQuirk(true);
1838    }
1839}
1840
1841void RenderBlock::handleAfterSideOfBlock(int beforeSide, int afterSide, MarginInfo& marginInfo)
1842{
1843    marginInfo.setAtAfterSideOfBlock(true);
1844
1845    // If we can't collapse with children then go ahead and add in the bottom margin.
1846    if (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
1847        && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk()))
1848        setLogicalHeight(logicalHeight() + marginInfo.margin());
1849
1850    // Now add in our bottom border/padding.
1851    setLogicalHeight(logicalHeight() + afterSide);
1852
1853    // Negative margins can cause our height to shrink below our minimal height (border/padding).
1854    // If this happens, ensure that the computed height is increased to the minimal height.
1855    setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
1856
1857    // Update our bottom collapsed margin info.
1858    setCollapsedBottomMargin(marginInfo);
1859}
1860
1861void RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, ApplyLayoutDeltaMode applyDelta)
1862{
1863    if (isHorizontalWritingMode()) {
1864        if (applyDelta == ApplyLayoutDelta)
1865            view()->addLayoutDelta(IntSize(child->x() - logicalLeft, 0));
1866        child->setX(logicalLeft);
1867    } else {
1868        if (applyDelta == ApplyLayoutDelta)
1869            view()->addLayoutDelta(IntSize(0, child->y() - logicalLeft));
1870        child->setY(logicalLeft);
1871    }
1872}
1873
1874void RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop, ApplyLayoutDeltaMode applyDelta)
1875{
1876    if (isHorizontalWritingMode()) {
1877        if (applyDelta == ApplyLayoutDelta)
1878            view()->addLayoutDelta(IntSize(0, child->y() - logicalTop));
1879        child->setY(logicalTop);
1880    } else {
1881        if (applyDelta == ApplyLayoutDelta)
1882            view()->addLayoutDelta(IntSize(child->x() - logicalTop, 0));
1883        child->setX(logicalTop);
1884    }
1885}
1886
1887void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom)
1888{
1889    if (gPercentHeightDescendantsMap) {
1890        if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
1891            HashSet<RenderBox*>::iterator end = descendants->end();
1892            for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
1893                RenderBox* box = *it;
1894                while (box != this) {
1895                    if (box->normalChildNeedsLayout())
1896                        break;
1897                    box->setChildNeedsLayout(true, false);
1898                    box = box->containingBlock();
1899                    ASSERT(box);
1900                    if (!box)
1901                        break;
1902                }
1903            }
1904        }
1905    }
1906
1907    int beforeEdge = borderBefore() + paddingBefore();
1908    int afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
1909
1910    setLogicalHeight(beforeEdge);
1911
1912    // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
1913    MarginInfo marginInfo(this, beforeEdge, afterEdge);
1914
1915    // Fieldsets need to find their legend and position it inside the border of the object.
1916    // The legend then gets skipped during normal layout.  The same is true for ruby text.
1917    // It doesn't get included in the normal layout process but is instead skipped.
1918    RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
1919
1920    int previousFloatLogicalBottom = 0;
1921    maxFloatLogicalBottom = 0;
1922
1923    RenderBox* next = firstChildBox();
1924
1925    while (next) {
1926        RenderBox* child = next;
1927        next = child->nextSiblingBox();
1928
1929        if (childToExclude == child)
1930            continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
1931
1932        // Make sure we layout children if they need it.
1933        // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
1934        // an auto value.  Add a method to determine this, so that we can avoid the relayout.
1935        if (relayoutChildren || ((child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) && !isRenderView()))
1936            child->setChildNeedsLayout(true, false);
1937
1938        // If relayoutChildren is set and the child has percentage padding, we also need to invalidate the child's pref widths.
1939        if (relayoutChildren && (child->style()->paddingStart().isPercent() || child->style()->paddingEnd().isPercent()))
1940            child->setPreferredLogicalWidthsDirty(true, false);
1941
1942        // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
1943        // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
1944        if (handleSpecialChild(child, marginInfo))
1945            continue;
1946
1947        // Lay out the child.
1948        layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
1949    }
1950
1951    // Now do the handling of the bottom of the block, adding in our bottom border/padding and
1952    // determining the correct collapsed bottom margin information.
1953    handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
1954}
1955
1956void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom)
1957{
1958    int oldPosMarginBefore = maxPositiveMarginBefore();
1959    int oldNegMarginBefore = maxNegativeMarginBefore();
1960
1961    // The child is a normal flow object.  Compute the margins we will use for collapsing now.
1962    child->computeBlockDirectionMargins(this);
1963
1964    // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE.
1965    if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1966        marginInfo.setAtBeforeSideOfBlock(false);
1967        marginInfo.clearMargin();
1968    }
1969
1970    // Try to guess our correct logical top position.  In most cases this guess will
1971    // be correct.  Only if we're wrong (when we compute the real logical top position)
1972    // will we have to potentially relayout.
1973    int logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo);
1974
1975    // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
1976    IntRect oldRect(child->x(), child->y() , child->width(), child->height());
1977    int oldLogicalTop = logicalTopForChild(child);
1978
1979#ifndef NDEBUG
1980    IntSize oldLayoutDelta = view()->layoutDelta();
1981#endif
1982    // Go ahead and position the child as though it didn't collapse with the top.
1983    setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
1984
1985    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
1986    bool markDescendantsWithFloats = false;
1987    if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats())
1988        markDescendantsWithFloats = true;
1989    else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
1990        // If an element might be affected by the presence of floats, then always mark it for
1991        // layout.
1992        int fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
1993        if (fb > logicalTopEstimate)
1994            markDescendantsWithFloats = true;
1995    }
1996
1997    if (childRenderBlock) {
1998        if (markDescendantsWithFloats)
1999            childRenderBlock->markAllDescendantsWithFloatsForLayout();
2000        if (!child->isWritingModeRoot())
2001            previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
2002    }
2003
2004    if (!child->needsLayout())
2005        child->markForPaginationRelayoutIfNeeded();
2006
2007    bool childHadLayout = child->m_everHadLayout;
2008    bool childNeededLayout = child->needsLayout();
2009    if (childNeededLayout)
2010        child->layout();
2011
2012    // Cache if we are at the top of the block right now.
2013    bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
2014
2015    // Now determine the correct ypos based off examination of collapsing margin
2016    // values.
2017    int logicalTopBeforeClear = collapseMargins(child, marginInfo);
2018
2019    // Now check for clear.
2020    int logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
2021
2022    bool paginated = view()->layoutState()->isPaginated();
2023    if (paginated) {
2024        int oldTop = logicalTopAfterClear;
2025
2026        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
2027        logicalTopAfterClear = applyBeforeBreak(child, logicalTopAfterClear);
2028
2029        // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
2030        int logicalTopBeforeUnsplittableAdjustment = logicalTopAfterClear;
2031        int logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, logicalTopAfterClear);
2032
2033        int paginationStrut = 0;
2034        int unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
2035        if (unsplittableAdjustmentDelta)
2036            paginationStrut = unsplittableAdjustmentDelta;
2037        else if (childRenderBlock && childRenderBlock->paginationStrut())
2038            paginationStrut = childRenderBlock->paginationStrut();
2039
2040        if (paginationStrut) {
2041            // We are willing to propagate out to our parent block as long as we were at the top of the block prior
2042            // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
2043            if (atBeforeSideOfBlock && oldTop == logicalTopBeforeClear && !isPositioned() && !isTableCell()) {
2044                // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
2045                // have all the information to do so (the strut only has the remaining amount to push).  Gecko gets this wrong too
2046                // and pushes to the next page anyway, so not too concerned about it.
2047                setPaginationStrut(logicalTopAfterClear + paginationStrut);
2048                if (childRenderBlock)
2049                    childRenderBlock->setPaginationStrut(0);
2050            } else
2051                logicalTopAfterClear += paginationStrut;
2052        }
2053
2054        // Similar to how we apply clearance.  Go ahead and boost height() to be the place where we're going to position the child.
2055        setLogicalHeight(logicalHeight() + (logicalTopAfterClear - oldTop));
2056    }
2057
2058    setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
2059
2060    // Now we have a final top position.  See if it really does end up being different from our estimate.
2061    if (logicalTopAfterClear != logicalTopEstimate) {
2062        if (child->shrinkToAvoidFloats()) {
2063            // The child's width depends on the line width.
2064            // When the child shifts to clear an item, its width can
2065            // change (because it has more available line width).
2066            // So go ahead and mark the item as dirty.
2067            child->setChildNeedsLayout(true, false);
2068        }
2069        if (childRenderBlock) {
2070            if (!child->avoidsFloats() && childRenderBlock->containsFloats())
2071                childRenderBlock->markAllDescendantsWithFloatsForLayout();
2072            if (!child->needsLayout())
2073                child->markForPaginationRelayoutIfNeeded();
2074        }
2075
2076        // Our guess was wrong. Make the child lay itself out again.
2077        child->layoutIfNeeded();
2078    }
2079
2080    // We are no longer at the top of the block if we encounter a non-empty child.
2081    // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
2082    if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
2083        marginInfo.setAtBeforeSideOfBlock(false);
2084
2085    // Now place the child in the correct left position
2086    determineLogicalLeftPositionForChild(child);
2087
2088    // Update our height now that the child has been placed in the correct position.
2089    setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
2090    if (child->style()->marginAfterCollapse() == MSEPARATE) {
2091        setLogicalHeight(logicalHeight() + marginAfterForChild(child));
2092        marginInfo.clearMargin();
2093    }
2094    // If the child has overhanging floats that intrude into following siblings (or possibly out
2095    // of this block), then the parent gets notified of the floats now.
2096    if (childRenderBlock && childRenderBlock->containsFloats())
2097        maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->logicalLeft(), -child->logicalTop(), !childNeededLayout));
2098
2099    IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
2100    if (childOffset.width() || childOffset.height()) {
2101        view()->addLayoutDelta(childOffset);
2102
2103        // If the child moved, we have to repaint it as well as any floating/positioned
2104        // descendants.  An exception is if we need a layout.  In this case, we know we're going to
2105        // repaint ourselves (and the child) anyway.
2106        if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
2107            child->repaintDuringLayoutIfMoved(oldRect);
2108    }
2109
2110    if (!childHadLayout && child->checkForRepaintDuringLayout()) {
2111        child->repaint();
2112        child->repaintOverhangingFloats(true);
2113    }
2114
2115    if (paginated) {
2116        // Check for an after page/column break.
2117        int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
2118        if (newHeight != height())
2119            setLogicalHeight(newHeight);
2120    }
2121
2122    ASSERT(oldLayoutDelta == view()->layoutDelta());
2123}
2124
2125void RenderBlock::simplifiedNormalFlowLayout()
2126{
2127    if (childrenInline()) {
2128        ListHashSet<RootInlineBox*> lineBoxes;
2129        bool endOfInline = false;
2130        RenderObject* o = bidiFirst(this, 0, false);
2131        while (o) {
2132            if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) {
2133                o->layoutIfNeeded();
2134                if (toRenderBox(o)->inlineBoxWrapper()) {
2135                    RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
2136                    lineBoxes.add(box);
2137                }
2138            } else if (o->isText() || (o->isRenderInline() && !endOfInline))
2139                o->setNeedsLayout(false);
2140            o = bidiNext(this, o, 0, false, &endOfInline);
2141        }
2142
2143        // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
2144        GlyphOverflowAndFallbackFontsMap textBoxDataMap;
2145        for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
2146            RootInlineBox* box = *it;
2147            box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
2148        }
2149    } else {
2150        for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
2151            if (!box->isPositioned())
2152                box->layoutIfNeeded();
2153        }
2154    }
2155}
2156
2157bool RenderBlock::simplifiedLayout()
2158{
2159    if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
2160        return false;
2161
2162    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
2163
2164    if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
2165        return false;
2166
2167    // Lay out positioned descendants or objects that just need to recompute overflow.
2168    if (needsSimplifiedNormalFlowLayout())
2169        simplifiedNormalFlowLayout();
2170
2171    // Lay out our positioned objects if our positioned child bit is set.
2172    if (posChildNeedsLayout())
2173        layoutPositionedObjects(false);
2174
2175    // Recompute our overflow information.
2176    // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
2177    // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
2178    // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
2179    // lowestPosition on every relayout so it's not a regression.
2180    m_overflow.clear();
2181    computeOverflow(clientLogicalBottom(), true);
2182
2183    statePusher.pop();
2184
2185    updateLayerTransform();
2186
2187    updateScrollInfoAfterLayout();
2188
2189    setNeedsLayout(false);
2190    return true;
2191}
2192
2193void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
2194{
2195    if (!m_positionedObjects)
2196        return;
2197
2198    if (hasColumns())
2199        view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
2200
2201    RenderBox* r;
2202    Iterator end = m_positionedObjects->end();
2203    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
2204        r = *it;
2205        // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
2206        // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
2207        // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
2208        // positioned explicitly) this should not incur a performance penalty.
2209        if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
2210            r->setChildNeedsLayout(true, false);
2211
2212        // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
2213        if (relayoutChildren && (r->style()->paddingStart().isPercent() || r->style()->paddingEnd().isPercent()))
2214            r->setPreferredLogicalWidthsDirty(true, false);
2215
2216        if (!r->needsLayout())
2217            r->markForPaginationRelayoutIfNeeded();
2218
2219        // We don't have to do a full layout.  We just have to update our position. Try that first. If we have shrink-to-fit width
2220        // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
2221        if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
2222            r->setNeedsLayout(false);
2223        r->layoutIfNeeded();
2224    }
2225
2226    if (hasColumns())
2227        view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
2228}
2229
2230void RenderBlock::markPositionedObjectsForLayout()
2231{
2232    if (m_positionedObjects) {
2233        RenderBox* r;
2234        Iterator end = m_positionedObjects->end();
2235        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
2236            r = *it;
2237            r->setChildNeedsLayout(true);
2238        }
2239    }
2240}
2241
2242void RenderBlock::markForPaginationRelayoutIfNeeded()
2243{
2244    ASSERT(!needsLayout());
2245    if (needsLayout())
2246        return;
2247
2248    if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
2249        setChildNeedsLayout(true, false);
2250}
2251
2252void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
2253{
2254    // Repaint any overhanging floats (if we know we're the one to paint them).
2255    // Otherwise, bail out.
2256    if (!hasOverhangingFloats())
2257        return;
2258
2259    // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
2260    // in this block. Better yet would be to push extra state for the containers of other floats.
2261    view()->disableLayoutState();
2262    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2263    FloatingObjectSetIterator end = floatingObjectSet.end();
2264    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2265        FloatingObject* r = *it;
2266        // Only repaint the object if it is overhanging, is not in its own layer, and
2267        // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
2268        // condition is replaced with being a descendant of us.
2269        if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
2270            r->m_renderer->repaint();
2271            r->m_renderer->repaintOverhangingFloats();
2272        }
2273    }
2274    view()->enableLayoutState();
2275}
2276
2277void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
2278{
2279    tx += x();
2280    ty += y();
2281
2282    PaintPhase phase = paintInfo.phase;
2283
2284    // Check if we need to do anything at all.
2285    // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
2286    // paints the root's background.
2287    if (!isRoot()) {
2288        IntRect overflowBox = visualOverflowRect();
2289        flipForWritingMode(overflowBox);
2290        overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
2291        overflowBox.move(tx, ty);
2292        if (!overflowBox.intersects(paintInfo.rect))
2293            return;
2294    }
2295
2296    bool pushedClip = pushContentsClip(paintInfo, tx, ty);
2297    paintObject(paintInfo, tx, ty);
2298    if (pushedClip)
2299        popContentsClip(paintInfo, phase, tx, ty);
2300
2301    // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
2302    // z-index.  We paint after we painted the background/border, so that the scrollbars will
2303    // sit above the background/border.
2304    if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
2305        layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
2306}
2307
2308void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
2309{
2310    const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
2311    bool ruleTransparent = style()->columnRuleIsTransparent();
2312    EBorderStyle ruleStyle = style()->columnRuleStyle();
2313    int ruleWidth = style()->columnRuleWidth();
2314    int colGap = columnGap();
2315    bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
2316    if (!renderRule)
2317        return;
2318
2319    // We need to do multiple passes, breaking up our child painting into strips.
2320    ColumnInfo* colInfo = columnInfo();
2321    unsigned colCount = columnCount(colInfo);
2322    int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
2323    int ruleAdd = logicalLeftOffsetForContent();
2324    int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
2325    for (unsigned i = 0; i < colCount; i++) {
2326        IntRect colRect = columnRectAt(colInfo, i);
2327
2328        int inlineDirectionSize = isHorizontalWritingMode() ? colRect.width() : colRect.height();
2329
2330        // Move to the next position.
2331        if (style()->isLeftToRightDirection()) {
2332            ruleLogicalLeft += inlineDirectionSize + colGap / 2;
2333            currLogicalLeftOffset += inlineDirectionSize + colGap;
2334        } else {
2335            ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
2336            currLogicalLeftOffset -= (inlineDirectionSize + colGap);
2337        }
2338
2339        // Now paint the column rule.
2340        if (i < colCount - 1) {
2341            int ruleLeft = isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
2342            int ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
2343            int ruleTop = isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
2344            int ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
2345            drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
2346                               style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
2347        }
2348
2349        ruleLogicalLeft = currLogicalLeftOffset;
2350    }
2351}
2352
2353void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
2354{
2355    // We need to do multiple passes, breaking up our child painting into strips.
2356    GraphicsContext* context = paintInfo.context;
2357    ColumnInfo* colInfo = columnInfo();
2358    unsigned colCount = columnCount(colInfo);
2359    if (!colCount)
2360        return;
2361    int currLogicalTopOffset = 0;
2362    for (unsigned i = 0; i < colCount; i++) {
2363        // For each rect, we clip to the rect, and then we adjust our coords.
2364        IntRect colRect = columnRectAt(colInfo, i);
2365        flipForWritingMode(colRect);
2366        int logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
2367        IntSize offset = isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
2368        colRect.move(tx, ty);
2369        PaintInfo info(paintInfo);
2370        info.rect.intersect(colRect);
2371
2372        if (!info.rect.isEmpty()) {
2373            context->save();
2374
2375            // Each strip pushes a clip, since column boxes are specified as being
2376            // like overflow:hidden.
2377            context->clip(colRect);
2378
2379            // Adjust our x and y when painting.
2380            int finalX = tx + offset.width();
2381            int finalY = ty + offset.height();
2382            if (paintingFloats)
2383                paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
2384            else
2385                paintContents(info, finalX, finalY);
2386
2387            context->restore();
2388        }
2389
2390        int blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
2391        if (style()->isFlippedBlocksWritingMode())
2392            currLogicalTopOffset += blockDelta;
2393        else
2394            currLogicalTopOffset -= blockDelta;
2395    }
2396}
2397
2398void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
2399{
2400    // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
2401    // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
2402    // will do a full repaint().
2403    if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
2404        return;
2405
2406    if (childrenInline())
2407        m_lineBoxes.paint(this, paintInfo, tx, ty);
2408    else
2409        paintChildren(paintInfo, tx, ty);
2410}
2411
2412void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
2413{
2414    PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
2415    newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
2416
2417    // We don't paint our own background, but we do let the kids paint their backgrounds.
2418    PaintInfo info(paintInfo);
2419    info.phase = newPhase;
2420    info.updatePaintingRootForChildren(this);
2421
2422    // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
2423    // NSViews.  Do not add any more code for this.
2424    RenderView* renderView = view();
2425    bool usePrintRect = !renderView->printRect().isEmpty();
2426
2427    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
2428        // Check for page-break-before: always, and if it's set, break and bail.
2429        bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
2430        if (checkBeforeAlways
2431            && (ty + child->y()) > paintInfo.rect.y()
2432            && (ty + child->y()) < paintInfo.rect.maxY()) {
2433            view()->setBestTruncatedAt(ty + child->y(), this, true);
2434            return;
2435        }
2436
2437        if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
2438            // Paginate block-level replaced elements.
2439            if (ty + child->y() + child->height() > renderView->printRect().maxY()) {
2440                if (ty + child->y() < renderView->truncatedAt())
2441                    renderView->setBestTruncatedAt(ty + child->y(), child);
2442                // If we were able to truncate, don't paint.
2443                if (ty + child->y() >= renderView->truncatedAt())
2444                    break;
2445            }
2446        }
2447
2448        IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
2449        if (!child->hasSelfPaintingLayer() && !child->isFloating())
2450            child->paint(info, childPoint.x(), childPoint.y());
2451
2452        // Check for page-break-after: always, and if it's set, break and bail.
2453        bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
2454        if (checkAfterAlways
2455            && (ty + child->y() + child->height()) > paintInfo.rect.y()
2456            && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) {
2457            view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true);
2458            return;
2459        }
2460    }
2461}
2462
2463void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
2464{
2465    SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->page()->dragCaretController();
2466
2467    // Paint the caret if the SelectionController says so or if caret browsing is enabled
2468    bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
2469    RenderObject* caretPainter = selection->caretRenderer();
2470    if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
2471        // Convert the painting offset into the local coordinate system of this renderer,
2472        // to match the localCaretRect computed by the SelectionController
2473        offsetForContents(tx, ty);
2474
2475        if (type == CursorCaret)
2476            frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
2477        else
2478            frame()->selection()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
2479    }
2480}
2481
2482void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
2483{
2484    PaintPhase paintPhase = paintInfo.phase;
2485
2486    // 1. paint background, borders etc
2487    if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
2488        if (hasBoxDecorations())
2489            paintBoxDecorations(paintInfo, tx, ty);
2490        if (hasColumns())
2491            paintColumnRules(paintInfo, tx, ty);
2492    }
2493
2494    if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
2495        paintMask(paintInfo, tx, ty);
2496        return;
2497    }
2498
2499    // We're done.  We don't bother painting any children.
2500    if (paintPhase == PaintPhaseBlockBackground)
2501        return;
2502
2503    // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
2504    int scrolledX = tx;
2505    int scrolledY = ty;
2506    if (hasOverflowClip()) {
2507        IntSize offset = layer()->scrolledContentOffset();
2508        scrolledX -= offset.width();
2509        scrolledY -= offset.height();
2510    }
2511
2512    // 2. paint contents
2513    if (paintPhase != PaintPhaseSelfOutline) {
2514        if (hasColumns())
2515            paintColumnContents(paintInfo, scrolledX, scrolledY);
2516        else
2517            paintContents(paintInfo, scrolledX, scrolledY);
2518    }
2519
2520    // 3. paint selection
2521    // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
2522    bool isPrinting = document()->printing();
2523    if (!isPrinting && !hasColumns())
2524        paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
2525
2526    // 4. paint floats.
2527    if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
2528        if (hasColumns())
2529            paintColumnContents(paintInfo, scrolledX, scrolledY, true);
2530        else
2531            paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
2532    }
2533
2534    // 5. paint outline.
2535    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2536        paintOutline(paintInfo.context, tx, ty, width(), height());
2537
2538    // 6. paint continuation outlines.
2539    if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
2540        RenderInline* inlineCont = inlineElementContinuation();
2541        if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
2542            RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
2543            RenderBlock* cb = containingBlock();
2544
2545            bool inlineEnclosedInSelfPaintingLayer = false;
2546            for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
2547                if (box->hasSelfPaintingLayer()) {
2548                    inlineEnclosedInSelfPaintingLayer = true;
2549                    break;
2550                }
2551            }
2552
2553            if (!inlineEnclosedInSelfPaintingLayer)
2554                cb->addContinuationWithOutline(inlineRenderer);
2555            else if (!inlineRenderer->firstLineBox())
2556                inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
2557                                             ty - y() + inlineRenderer->containingBlock()->y());
2558        }
2559        paintContinuationOutlines(paintInfo, tx, ty);
2560    }
2561
2562    // 7. paint caret.
2563    // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
2564    // then paint the caret.
2565    if (paintPhase == PaintPhaseForeground) {
2566        paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
2567        paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
2568    }
2569}
2570
2571IntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const
2572{
2573    if (!style()->isFlippedBlocksWritingMode())
2574        return point;
2575
2576    // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode.  We have to subtract out our left/top offsets twice, since
2577    // it's going to get added back in.  We hide this complication here so that the calling code looks normal for the unflipped
2578    // case.
2579    if (isHorizontalWritingMode())
2580        return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
2581    return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
2582}
2583
2584void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
2585{
2586    if (!m_floatingObjects)
2587        return;
2588
2589    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2590    FloatingObjectSetIterator end = floatingObjectSet.end();
2591    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2592        FloatingObject* r = *it;
2593        // Only paint the object if our m_shouldPaint flag is set.
2594        if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
2595            PaintInfo currentPaintInfo(paintInfo);
2596            currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
2597            IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
2598            r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
2599            if (!preservePhase) {
2600                currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
2601                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
2602                currentPaintInfo.phase = PaintPhaseFloat;
2603                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
2604                currentPaintInfo.phase = PaintPhaseForeground;
2605                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
2606                currentPaintInfo.phase = PaintPhaseOutline;
2607                r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
2608            }
2609        }
2610    }
2611}
2612
2613void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
2614{
2615    if (!paintInfo.shouldPaintWithinRoot(this) || !firstLineBox())
2616        return;
2617
2618    if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
2619        // We can check the first box and last box and avoid painting if we don't
2620        // intersect.
2621        int yPos = ty + firstLineBox()->y();
2622        int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y();
2623        if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y())
2624            return;
2625
2626        // See if our boxes intersect with the dirty rect.  If so, then we paint
2627        // them.  Note that boxes can easily overlap, so we can't make any assumptions
2628        // based off positions of our first line box or our last line box.
2629        for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2630            yPos = ty + curr->y();
2631            h = curr->logicalHeight();
2632            if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y())
2633                curr->paintEllipsisBox(paintInfo, tx, ty, curr->lineTop(), curr->lineBottom());
2634        }
2635    }
2636}
2637
2638RenderInline* RenderBlock::inlineElementContinuation() const
2639{
2640    RenderBoxModelObject* continuation = this->continuation();
2641    return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
2642}
2643
2644RenderBlock* RenderBlock::blockElementContinuation() const
2645{
2646    RenderBoxModelObject* currentContinuation = continuation();
2647    if (!currentContinuation || currentContinuation->isInline())
2648        return 0;
2649    RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2650    if (nextContinuation->isAnonymousBlock())
2651        return nextContinuation->blockElementContinuation();
2652    return nextContinuation;
2653}
2654
2655static ContinuationOutlineTableMap* continuationOutlineTable()
2656{
2657    DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
2658    return &table;
2659}
2660
2661void RenderBlock::addContinuationWithOutline(RenderInline* flow)
2662{
2663    // We can't make this work if the inline is in a layer.  We'll just rely on the broken
2664    // way of painting.
2665    ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
2666
2667    ContinuationOutlineTableMap* table = continuationOutlineTable();
2668    ListHashSet<RenderInline*>* continuations = table->get(this);
2669    if (!continuations) {
2670        continuations = new ListHashSet<RenderInline*>;
2671        table->set(this, continuations);
2672    }
2673
2674    continuations->add(flow);
2675}
2676
2677bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
2678{
2679    ContinuationOutlineTableMap* table = continuationOutlineTable();
2680    if (table->isEmpty())
2681        return false;
2682
2683    ListHashSet<RenderInline*>* continuations = table->get(this);
2684    if (!continuations)
2685        return false;
2686
2687    return continuations->contains(flow);
2688}
2689
2690void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
2691{
2692    ContinuationOutlineTableMap* table = continuationOutlineTable();
2693    if (table->isEmpty())
2694        return;
2695
2696    ListHashSet<RenderInline*>* continuations = table->get(this);
2697    if (!continuations)
2698        return;
2699
2700    // Paint each continuation outline.
2701    ListHashSet<RenderInline*>::iterator end = continuations->end();
2702    for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
2703        // Need to add in the coordinates of the intervening blocks.
2704        RenderInline* flow = *it;
2705        RenderBlock* block = flow->containingBlock();
2706        for ( ; block && block != this; block = block->containingBlock()) {
2707            tx += block->x();
2708            ty += block->y();
2709        }
2710        ASSERT(block);
2711        flow->paintOutline(info.context, tx, ty);
2712    }
2713
2714    // Delete
2715    delete continuations;
2716    table->remove(this);
2717}
2718
2719bool RenderBlock::shouldPaintSelectionGaps() const
2720{
2721    return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
2722}
2723
2724bool RenderBlock::isSelectionRoot() const
2725{
2726    if (!node())
2727        return false;
2728
2729    // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
2730    if (isTable())
2731        return false;
2732
2733    if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
2734        isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
2735        hasReflection() || hasMask() || isWritingModeRoot())
2736        return true;
2737
2738    if (view() && view()->selectionStart()) {
2739        Node* startElement = view()->selectionStart()->node();
2740        if (startElement && startElement->rootEditableElement() == node())
2741            return true;
2742    }
2743
2744    return false;
2745}
2746
2747GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
2748{
2749    ASSERT(!needsLayout());
2750
2751    if (!shouldPaintSelectionGaps())
2752        return GapRects();
2753
2754    // FIXME: this is broken with transforms
2755    TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
2756    mapLocalToContainer(repaintContainer, false, false, transformState);
2757    IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint());
2758
2759    if (hasOverflowClip())
2760        offsetFromRepaintContainer -= layer()->scrolledContentOffset();
2761
2762    int lastTop = 0;
2763    int lastLeft = logicalLeftSelectionOffset(this, lastTop);
2764    int lastRight = logicalRightSelectionOffset(this, lastTop);
2765
2766    return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
2767}
2768
2769void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
2770{
2771    if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2772        int lastTop = 0;
2773        int lastLeft = logicalLeftSelectionOffset(this, lastTop);
2774        int lastRight = logicalRightSelectionOffset(this, lastTop);
2775        paintInfo.context->save();
2776        IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo);
2777        if (!gapRectsBounds.isEmpty()) {
2778            if (RenderLayer* layer = enclosingLayer()) {
2779                gapRectsBounds.move(IntSize(-tx, -ty));
2780                if (!hasLayer()) {
2781                    IntRect localBounds(gapRectsBounds);
2782                    flipForWritingMode(localBounds);
2783                    gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
2784                    gapRectsBounds.move(layer->scrolledContentOffset());
2785                }
2786                layer->addBlockSelectionGapsBounds(gapRectsBounds);
2787            }
2788        }
2789        paintInfo.context->restore();
2790    }
2791}
2792
2793static void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
2794{
2795    if (!positionedObjects)
2796        return;
2797
2798    RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
2799    for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
2800        RenderBox* r = *it;
2801        paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
2802    }
2803}
2804
2805static int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
2806{
2807    return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
2808}
2809
2810static int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
2811{
2812    return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
2813}
2814
2815IntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect)
2816{
2817    IntRect result;
2818    if (isHorizontalWritingMode())
2819        result = logicalRect;
2820    else
2821        result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
2822    flipForWritingMode(result);
2823    result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
2824    return result;
2825}
2826
2827GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
2828                                    int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
2829{
2830    // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
2831    // Clip out floating and positioned objects when painting selection gaps.
2832    if (paintInfo) {
2833        // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
2834        IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
2835        rootBlock->flipForWritingMode(flippedBlockRect);
2836        flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
2837        clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
2838        if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
2839            for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
2840                clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
2841        if (m_floatingObjects) {
2842            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2843            FloatingObjectSetIterator end = floatingObjectSet.end();
2844            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2845                FloatingObject* r = *it;
2846                IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
2847                                           offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
2848                                           r->m_renderer->width(), r->m_renderer->height());
2849                rootBlock->flipForWritingMode(floatBox);
2850                floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
2851                paintInfo->context->clipOut(floatBox);
2852            }
2853        }
2854    }
2855
2856    // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is
2857    // fixed).
2858    GapRects result;
2859    if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
2860        return result;
2861
2862    if (hasColumns() || hasTransform() || style()->columnSpan()) {
2863        // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
2864        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
2865        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
2866        lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
2867        return result;
2868    }
2869
2870    if (childrenInline())
2871        result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
2872    else
2873        result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
2874
2875    // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
2876    if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
2877        result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
2878                                             logicalHeight(), paintInfo));
2879    return result;
2880}
2881
2882GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
2883                                          int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
2884{
2885    GapRects result;
2886
2887    bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
2888
2889    if (!firstLineBox()) {
2890        if (containsStart) {
2891            // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
2892            // case.
2893            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
2894            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
2895            lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
2896        }
2897        return result;
2898    }
2899
2900    RootInlineBox* lastSelectedLine = 0;
2901    RootInlineBox* curr;
2902    for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
2903
2904    // Now paint the gaps for the lines.
2905    for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
2906        int selTop =  curr->selectionTop();
2907        int selHeight = curr->selectionHeight();
2908
2909        if (!containsStart && !lastSelectedLine &&
2910            selectionState() != SelectionStart && selectionState() != SelectionBoth)
2911            result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
2912                                                 selTop, paintInfo));
2913
2914        IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
2915        logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
2916        IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
2917        if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
2918            || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
2919            result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
2920
2921        lastSelectedLine = curr;
2922    }
2923
2924    if (containsStart && !lastSelectedLine)
2925        // VisibleSelection must start just after our last line.
2926        lastSelectedLine = lastRootBox();
2927
2928    if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
2929        // Go ahead and update our lastY to be the bottom of the last selected line.
2930        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
2931        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
2932        lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
2933    }
2934    return result;
2935}
2936
2937GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
2938                                         int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
2939{
2940    GapRects result;
2941
2942    // Go ahead and jump right to the first block child that contains some selected objects.
2943    RenderBox* curr;
2944    for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
2945
2946    for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
2947        SelectionState childState = curr->selectionState();
2948        if (childState == SelectionBoth || childState == SelectionEnd)
2949            sawSelectionEnd = true;
2950
2951        if (curr->isFloatingOrPositioned())
2952            continue; // We must be a normal flow object in order to even be considered.
2953
2954        if (curr->isRelPositioned() && curr->hasLayer()) {
2955            // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
2956            // Just disregard it completely.
2957            IntSize relOffset = curr->layer()->relativePositionOffset();
2958            if (relOffset.width() || relOffset.height())
2959                continue;
2960        }
2961
2962        bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
2963        bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
2964        if (fillBlockGaps) {
2965            // We need to fill the vertical gap above this object.
2966            if (childState == SelectionEnd || childState == SelectionInside)
2967                // Fill the gap above the object.
2968                result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
2969                                                     curr->logicalTop(), paintInfo));
2970
2971            // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past*
2972            // our object.  We know this if the selection did not end inside our object.
2973            if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
2974                childState = SelectionNone;
2975
2976            // Fill side gaps on this object based off its state.
2977            bool leftGap, rightGap;
2978            getSelectionGapInfo(childState, leftGap, rightGap);
2979
2980            if (leftGap)
2981                result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
2982            if (rightGap)
2983                result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
2984
2985            // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
2986            // they can without bumping into floating or positioned objects.  Ideally they will go right up
2987            // to the border of the root selection block.
2988            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
2989            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
2990            lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
2991        } else if (childState != SelectionNone)
2992            // We must be a block that has some selected object inside it.  Go ahead and recur.
2993            result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
2994                                                            lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
2995    }
2996    return result;
2997}
2998
2999IntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
3000                                       int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo)
3001{
3002    int logicalTop = lastLogicalTop;
3003    int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
3004    if (logicalHeight <= 0)
3005        return IntRect();
3006
3007    // Get the selection offsets for the bottom of the gap
3008    int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
3009    int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
3010    int logicalWidth = logicalRight - logicalLeft;
3011    if (logicalWidth <= 0)
3012        return IntRect();
3013
3014    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
3015    if (paintInfo)
3016        paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
3017    return gapRect;
3018}
3019
3020IntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
3021                                             RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
3022{
3023    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
3024    int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
3025    int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
3026    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
3027    if (rootBlockLogicalWidth <= 0)
3028        return IntRect();
3029
3030    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
3031    if (paintInfo)
3032        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
3033    return gapRect;
3034}
3035
3036IntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
3037                                              RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
3038{
3039    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
3040    int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
3041    int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
3042    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
3043    if (rootBlockLogicalWidth <= 0)
3044        return IntRect();
3045
3046    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
3047    if (paintInfo)
3048        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
3049    return gapRect;
3050}
3051
3052void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
3053{
3054    bool ltr = style()->isLeftToRightDirection();
3055    leftGap = (state == RenderObject::SelectionInside) ||
3056              (state == RenderObject::SelectionEnd && ltr) ||
3057              (state == RenderObject::SelectionStart && !ltr);
3058    rightGap = (state == RenderObject::SelectionInside) ||
3059               (state == RenderObject::SelectionStart && ltr) ||
3060               (state == RenderObject::SelectionEnd && !ltr);
3061}
3062
3063int RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, int position)
3064{
3065    int logicalLeft = logicalLeftOffsetForLine(position, false);
3066    if (logicalLeft == logicalLeftOffsetForContent()) {
3067        if (rootBlock != this)
3068            // The border can potentially be further extended by our containingBlock().
3069            return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
3070        return logicalLeft;
3071    } else {
3072        RenderBlock* cb = this;
3073        while (cb != rootBlock) {
3074            logicalLeft += cb->logicalLeft();
3075            cb = cb->containingBlock();
3076        }
3077    }
3078    return logicalLeft;
3079}
3080
3081int RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, int position)
3082{
3083    int logicalRight = logicalRightOffsetForLine(position, false);
3084    if (logicalRight == logicalRightOffsetForContent()) {
3085        if (rootBlock != this)
3086            // The border can potentially be further extended by our containingBlock().
3087            return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
3088        return logicalRight;
3089    } else {
3090        RenderBlock* cb = this;
3091        while (cb != rootBlock) {
3092            logicalRight += cb->logicalLeft();
3093            cb = cb->containingBlock();
3094        }
3095    }
3096    return logicalRight;
3097}
3098
3099void RenderBlock::insertPositionedObject(RenderBox* o)
3100{
3101    // Create the list of special objects if we don't aleady have one
3102    if (!m_positionedObjects)
3103        m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
3104
3105    m_positionedObjects->add(o);
3106}
3107
3108void RenderBlock::removePositionedObject(RenderBox* o)
3109{
3110    if (m_positionedObjects)
3111        m_positionedObjects->remove(o);
3112}
3113
3114void RenderBlock::removePositionedObjects(RenderBlock* o)
3115{
3116    if (!m_positionedObjects)
3117        return;
3118
3119    RenderBox* r;
3120
3121    Iterator end = m_positionedObjects->end();
3122
3123    Vector<RenderBox*, 16> deadObjects;
3124
3125    for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
3126        r = *it;
3127        if (!o || r->isDescendantOf(o)) {
3128            if (o)
3129                r->setChildNeedsLayout(true, false);
3130
3131            // It is parent blocks job to add positioned child to positioned objects list of its containing block
3132            // Parent layout needs to be invalidated to ensure this happens.
3133            RenderObject* p = r->parent();
3134            while (p && !p->isRenderBlock())
3135                p = p->parent();
3136            if (p)
3137                p->setChildNeedsLayout(true);
3138
3139            deadObjects.append(r);
3140        }
3141    }
3142
3143    for (unsigned i = 0; i < deadObjects.size(); i++)
3144        m_positionedObjects->remove(deadObjects.at(i));
3145}
3146
3147RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
3148{
3149    ASSERT(o->isFloating());
3150
3151    // Create the list of special objects if we don't aleady have one
3152    if (!m_floatingObjects)
3153        m_floatingObjects = adoptPtr(new FloatingObjects);
3154    else {
3155        // Don't insert the object again if it's already in the list
3156        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3157        FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
3158        if (it != floatingObjectSet.end())
3159            return *it;
3160    }
3161
3162    // Create the special object entry & append it to the list
3163
3164    FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
3165
3166    // Our location is irrelevant if we're unsplittable or no pagination is in effect.
3167    // Just go ahead and lay out the float.
3168    bool isChildRenderBlock = o->isRenderBlock();
3169    if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
3170        o->setChildNeedsLayout(true, false);
3171
3172    bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageLogicalHeight;
3173    if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
3174        o->layoutIfNeeded();
3175    else {
3176        o->computeLogicalWidth();
3177        o->computeBlockDirectionMargins(this);
3178    }
3179    setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
3180
3181    newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
3182    newObj->m_isDescendant = true;
3183    newObj->m_renderer = o;
3184
3185    m_floatingObjects->increaseObjectsCount(newObj->type());
3186    m_floatingObjects->set().add(newObj);
3187
3188    return newObj;
3189}
3190
3191void RenderBlock::removeFloatingObject(RenderBox* o)
3192{
3193    if (m_floatingObjects) {
3194        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3195        FloatingObjectSet::iterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
3196        if (it != floatingObjectSet.end()) {
3197            FloatingObject* r = *it;
3198            if (childrenInline()) {
3199                int logicalTop = logicalTopForFloat(r);
3200                int logicalBottom = logicalBottomForFloat(r);
3201
3202                // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
3203                if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<int>::max())
3204                    logicalBottom = numeric_limits<int>::max();
3205                else {
3206                    // Special-case zero- and less-than-zero-height floats: those don't touch
3207                    // the line that they're on, but it still needs to be dirtied. This is
3208                    // accomplished by pretending they have a height of 1.
3209                    logicalBottom = max(logicalBottom, logicalTop + 1);
3210                }
3211                if (r->m_originatingLine) {
3212                    ASSERT(r->m_originatingLine->renderer() == this);
3213                    r->m_originatingLine->markDirty();
3214#if !ASSERT_DISABLED
3215                    r->m_originatingLine = 0;
3216#endif
3217                }
3218                markLinesDirtyInBlockRange(0, logicalBottom);
3219            }
3220            m_floatingObjects->decreaseObjectsCount(r->type());
3221            floatingObjectSet.remove(it);
3222            ASSERT(!r->m_originatingLine);
3223            delete r;
3224        }
3225    }
3226}
3227
3228void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
3229{
3230    if (!m_floatingObjects)
3231        return;
3232
3233    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3234    FloatingObject* curr = floatingObjectSet.last();
3235    while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
3236        m_floatingObjects->decreaseObjectsCount(curr->type());
3237        floatingObjectSet.removeLast();
3238        ASSERT(!curr->m_originatingLine);
3239        delete curr;
3240        curr = floatingObjectSet.last();
3241    }
3242}
3243
3244bool RenderBlock::positionNewFloats()
3245{
3246    if (!m_floatingObjects)
3247        return false;
3248
3249    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3250    if (floatingObjectSet.isEmpty())
3251        return false;
3252
3253    // If all floats have already been positioned, then we have no work to do.
3254    if (floatingObjectSet.last()->isPlaced())
3255        return false;
3256
3257    // Move backwards through our floating object list until we find a float that has
3258    // already been positioned.  Then we'll be able to move forward, positioning all of
3259    // the new floats that need it.
3260    FloatingObjectSetIterator it = floatingObjectSet.end();
3261    --it; // Go to last item.
3262    FloatingObjectSetIterator begin = floatingObjectSet.begin();
3263    FloatingObject* lastPlacedFloatingObject = 0;
3264    while (it != begin) {
3265        --it;
3266        if ((*it)->isPlaced()) {
3267            lastPlacedFloatingObject = *it;
3268            ++it;
3269            break;
3270        }
3271    }
3272
3273    int logicalTop = logicalHeight();
3274
3275    // The float cannot start above the top position of the last positioned float.
3276    if (lastPlacedFloatingObject)
3277        logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
3278
3279    FloatingObjectSetIterator end = floatingObjectSet.end();
3280    // Now walk through the set of unpositioned floats and place them.
3281    for (; it != end; ++it) {
3282         FloatingObject* floatingObject = *it;
3283        // The containing block is responsible for positioning floats, so if we have floats in our
3284        // list that come from somewhere else, do not attempt to position them.
3285        if (floatingObject->renderer()->containingBlock() != this)
3286            continue;
3287
3288        RenderBox* childBox = floatingObject->renderer();
3289        int childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
3290
3291        int rightOffset = logicalRightOffsetForContent(); // Constant part of right offset.
3292        int leftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
3293        int floatLogicalWidth = logicalWidthForFloat(floatingObject); // The width we look for.
3294        if (rightOffset - leftOffset < floatLogicalWidth)
3295            floatLogicalWidth = rightOffset - leftOffset; // Never look for more than what will be available.
3296
3297        IntRect oldRect(childBox->x(), childBox->y() , childBox->width(), childBox->height());
3298
3299        if (childBox->style()->clear() & CLEFT)
3300            logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
3301        if (childBox->style()->clear() & CRIGHT)
3302            logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
3303
3304        int floatLogicalLeft;
3305        if (childBox->style()->floating() == FLEFT) {
3306            int heightRemainingLeft = 1;
3307            int heightRemainingRight = 1;
3308            floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
3309            while (logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
3310                logicalTop += min(heightRemainingLeft, heightRemainingRight);
3311                floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
3312            }
3313            floatLogicalLeft = max(0, floatLogicalLeft);
3314        } else {
3315            int heightRemainingLeft = 1;
3316            int heightRemainingRight = 1;
3317            floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
3318            while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
3319                logicalTop += min(heightRemainingLeft, heightRemainingRight);
3320                floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
3321            }
3322            floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable
3323                                                                      // |floatLogicalWidth| was capped to the available line width.
3324                                                                      // See fast/block/float/clamped-right-float.html.
3325        }
3326
3327        setLogicalLeftForFloat(floatingObject, floatLogicalLeft);
3328        setLogicalLeftForChild(childBox, floatLogicalLeft + childLogicalLeftMargin);
3329        setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
3330
3331        if (view()->layoutState()->isPaginated()) {
3332            RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0;
3333
3334            if (!childBox->needsLayout())
3335                childBox->markForPaginationRelayoutIfNeeded();;
3336            childBox->layoutIfNeeded();
3337
3338            // If we are unsplittable and don't fit, then we need to move down.
3339            // We include our margins as part of the unsplittable area.
3340            int newLogicalTop = adjustForUnsplittableChild(childBox, logicalTop, true);
3341
3342            // See if we have a pagination strut that is making us move down further.
3343            // Note that an unsplittable child can't also have a pagination strut, so this is
3344            // exclusive with the case above.
3345            if (childBlock && childBlock->paginationStrut()) {
3346                newLogicalTop += childBlock->paginationStrut();
3347                childBlock->setPaginationStrut(0);
3348            }
3349
3350            if (newLogicalTop != logicalTop) {
3351                floatingObject->m_paginationStrut = newLogicalTop - logicalTop;
3352                logicalTop = newLogicalTop;
3353                setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
3354                if (childBlock)
3355                    childBlock->setChildNeedsLayout(true, false);
3356                childBox->layoutIfNeeded();
3357            }
3358        }
3359
3360        setLogicalTopForFloat(floatingObject, logicalTop);
3361        setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
3362
3363        floatingObject->setIsPlaced();
3364
3365        // If the child moved, we have to repaint it.
3366        if (childBox->checkForRepaintDuringLayout())
3367            childBox->repaintDuringLayoutIfMoved(oldRect);
3368    }
3369    return true;
3370}
3371
3372void RenderBlock::newLine(EClear clear)
3373{
3374    positionNewFloats();
3375    // set y position
3376    int newY = 0;
3377    switch (clear)
3378    {
3379        case CLEFT:
3380            newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
3381            break;
3382        case CRIGHT:
3383            newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
3384            break;
3385        case CBOTH:
3386            newY = lowestFloatLogicalBottom();
3387        default:
3388            break;
3389    }
3390    if (height() < newY)
3391        setLogicalHeight(newY);
3392}
3393
3394void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
3395{
3396    if (!gPercentHeightDescendantsMap) {
3397        gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
3398        gPercentHeightContainerMap = new PercentHeightContainerMap;
3399    }
3400
3401    HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
3402    if (!descendantSet) {
3403        descendantSet = new HashSet<RenderBox*>;
3404        gPercentHeightDescendantsMap->set(this, descendantSet);
3405    }
3406    bool added = descendantSet->add(descendant).second;
3407    if (!added) {
3408        ASSERT(gPercentHeightContainerMap->get(descendant));
3409        ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
3410        return;
3411    }
3412
3413    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
3414    if (!containerSet) {
3415        containerSet = new HashSet<RenderBlock*>;
3416        gPercentHeightContainerMap->set(descendant, containerSet);
3417    }
3418    ASSERT(!containerSet->contains(this));
3419    containerSet->add(this);
3420}
3421
3422void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
3423{
3424    if (!gPercentHeightContainerMap)
3425        return;
3426
3427    HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
3428    if (!containerSet)
3429        return;
3430
3431    HashSet<RenderBlock*>::iterator end = containerSet->end();
3432    for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
3433        RenderBlock* container = *it;
3434        HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
3435        ASSERT(descendantSet);
3436        if (!descendantSet)
3437            continue;
3438        ASSERT(descendantSet->contains(descendant));
3439        descendantSet->remove(descendant);
3440        if (descendantSet->isEmpty()) {
3441            gPercentHeightDescendantsMap->remove(container);
3442            delete descendantSet;
3443        }
3444    }
3445
3446    delete containerSet;
3447}
3448
3449HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
3450{
3451    return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
3452}
3453
3454// FIXME: The logicalLeftOffsetForLine/logicalRightOffsetForLine functions are very slow if there are many floats
3455// present. We need to add a structure to floating objects to represent "lines" of floats.  Then instead of checking
3456// each float individually, we'd just walk backwards through the "lines" and stop when we hit a line that is fully above
3457// the vertical offset that we'd like to check.  Computing the "lines" would be rather complicated, but could replace the left
3458// objects and right objects count hack that is currently used here.
3459int RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
3460{
3461    int left = fixedOffset;
3462    if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
3463        if (heightRemaining)
3464            *heightRemaining = 1;
3465
3466        // We know the list is non-empty, since we have "left" objects to search for.
3467        // Therefore we can assume that begin != end, and that we can do at least one
3468        // decrement.
3469        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3470        FloatingObjectSetIterator begin = floatingObjectSet.begin();
3471        FloatingObjectSetIterator it = floatingObjectSet.end();
3472        do {
3473            --it;
3474            FloatingObject* r = *it;
3475            if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
3476                && r->type() == FloatingObject::FloatLeft
3477                && logicalRightForFloat(r) > left) {
3478                left = max(left, logicalRightForFloat(r));
3479                if (heightRemaining)
3480                    *heightRemaining = logicalBottomForFloat(r) - logicalTop;
3481            }
3482        } while (it != begin);
3483    }
3484
3485    if (applyTextIndent && style()->isLeftToRightDirection()) {
3486        int cw = 0;
3487        if (style()->textIndent().isPercent())
3488            cw = containingBlock()->availableLogicalWidth();
3489        left += style()->textIndent().calcMinValue(cw);
3490    }
3491
3492    return left;
3493}
3494
3495int RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
3496{
3497    int right = fixedOffset;
3498
3499    if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
3500        if (heightRemaining)
3501            *heightRemaining = 1;
3502
3503        // We know the list is non-empty, since we have "right" objects to search for.
3504        // Therefore we can assume that begin != end, and that we can do at least one
3505        // decrement.
3506        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3507        FloatingObjectSetIterator begin = floatingObjectSet.begin();
3508        FloatingObjectSetIterator it = floatingObjectSet.end();
3509        do {
3510            --it;
3511            FloatingObject* r = *it;
3512            if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
3513                && r->type() == FloatingObject::FloatRight
3514                && logicalLeftForFloat(r) < right) {
3515                right = min(right, logicalLeftForFloat(r));
3516                if (heightRemaining)
3517                    *heightRemaining = logicalBottomForFloat(r) - logicalTop;
3518            }
3519        } while (it != begin);
3520    }
3521
3522    if (applyTextIndent && !style()->isLeftToRightDirection()) {
3523        int cw = 0;
3524        if (style()->textIndent().isPercent())
3525            cw = containingBlock()->availableLogicalWidth();
3526        right -= style()->textIndent().calcMinValue(cw);
3527    }
3528
3529    return right;
3530}
3531
3532int RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
3533{
3534    int result = logicalRightOffsetForLine(position, firstLine) - logicalLeftOffsetForLine(position, firstLine);
3535    return (result < 0) ? 0 : result;
3536}
3537
3538int RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const
3539{
3540    if (!m_floatingObjects)
3541        return 0;
3542
3543    int bottom = INT_MAX;
3544    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3545    FloatingObjectSetIterator end = floatingObjectSet.end();
3546    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
3547        FloatingObject* r = *it;
3548        int floatBottom = logicalBottomForFloat(r);
3549        if (floatBottom > logicalHeight)
3550            bottom = min(floatBottom, bottom);
3551    }
3552
3553    return bottom == INT_MAX ? 0 : bottom;
3554}
3555
3556int RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
3557{
3558    if (!m_floatingObjects)
3559        return 0;
3560    int lowestFloatBottom = 0;
3561    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3562    FloatingObjectSetIterator end = floatingObjectSet.end();
3563    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
3564        FloatingObject* r = *it;
3565        if (r->isPlaced() && r->type() & floatType)
3566            lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
3567    }
3568    return lowestFloatBottom;
3569}
3570
3571void RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest)
3572{
3573    if (logicalTop >= logicalBottom)
3574        return;
3575
3576    RootInlineBox* lowestDirtyLine = lastRootBox();
3577    RootInlineBox* afterLowest = lowestDirtyLine;
3578    while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) {
3579        afterLowest = lowestDirtyLine;
3580        lowestDirtyLine = lowestDirtyLine->prevRootBox();
3581    }
3582
3583    while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) {
3584        afterLowest->markDirty();
3585        afterLowest = afterLowest->prevRootBox();
3586    }
3587}
3588
3589void RenderBlock::clearFloats()
3590{
3591    // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
3592    if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
3593        if (m_floatingObjects) {
3594            deleteAllValues(m_floatingObjects->set());
3595            m_floatingObjects->clear();
3596        }
3597        return;
3598    }
3599
3600    typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap;
3601    RendererToFloatInfoMap floatMap;
3602
3603    if (m_floatingObjects) {
3604        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3605        if (childrenInline()) {
3606            FloatingObjectSet::iterator end = floatingObjectSet.end();
3607            for (FloatingObjectSet::iterator it = floatingObjectSet.begin(); it != end; ++it) {
3608                FloatingObject* f = *it;
3609                floatMap.add(f->m_renderer, f);
3610            }
3611        } else
3612            deleteAllValues(floatingObjectSet);
3613        m_floatingObjects->clear();
3614    }
3615
3616    // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
3617    // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
3618    // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
3619    if (!parent() || !parent()->isRenderBlock())
3620        return;
3621
3622    // Attempt to locate a previous sibling with overhanging floats.  We skip any elements that are
3623    // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
3624    // to avoid floats.
3625    bool parentHasFloats = false;
3626    RenderBlock* parentBlock = toRenderBlock(parent());
3627    RenderObject* prev = previousSibling();
3628    while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
3629        if (prev->isFloating())
3630            parentHasFloats = true;
3631         prev = prev->previousSibling();
3632    }
3633
3634    // First add in floats from the parent.
3635    int logicalTopOffset = logicalTop();
3636    if (parentHasFloats)
3637        addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset);
3638
3639    int logicalLeftOffset = 0;
3640    if (prev)
3641        logicalTopOffset -= toRenderBox(prev)->logicalTop();
3642    else {
3643        prev = parentBlock;
3644        logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
3645    }
3646
3647    // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
3648    if (!prev || !prev->isRenderBlock())
3649        return;
3650
3651    RenderBlock* block = toRenderBlock(prev);
3652    if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
3653        addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
3654
3655    if (childrenInline()) {
3656        int changeLogicalTop = numeric_limits<int>::max();
3657        int changeLogicalBottom = numeric_limits<int>::min();
3658        if (m_floatingObjects) {
3659            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3660            FloatingObjectSetIterator end = floatingObjectSet.end();
3661            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
3662                FloatingObject* f = *it;
3663                FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
3664                int logicalBottom = logicalBottomForFloat(f);
3665                if (oldFloatingObject) {
3666                    int oldLogicalBottom = logicalBottomForFloat(oldFloatingObject);
3667                    if (logicalWidthForFloat(f) != logicalWidthForFloat(oldFloatingObject) || logicalLeftForFloat(f) != logicalLeftForFloat(oldFloatingObject)) {
3668                        changeLogicalTop = 0;
3669                        changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
3670                    } else if (logicalBottom != oldLogicalBottom) {
3671                        changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom));
3672                        changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
3673                    }
3674
3675                    floatMap.remove(f->m_renderer);
3676                    if (oldFloatingObject->m_originatingLine) {
3677                        ASSERT(oldFloatingObject->m_originatingLine->renderer() == this);
3678                        oldFloatingObject->m_originatingLine->markDirty();
3679                    }
3680                    delete oldFloatingObject;
3681                } else {
3682                    changeLogicalTop = 0;
3683                    changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
3684                }
3685            }
3686        }
3687
3688        RendererToFloatInfoMap::iterator end = floatMap.end();
3689        for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
3690            FloatingObject* floatingObject = (*it).second;
3691            if (!floatingObject->m_isDescendant) {
3692                changeLogicalTop = 0;
3693                changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
3694            }
3695        }
3696        deleteAllValues(floatMap);
3697
3698        markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
3699    }
3700}
3701
3702int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats)
3703{
3704    // Prevent floats from being added to the canvas by the root element, e.g., <html>.
3705    if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
3706        return 0;
3707
3708    int childLogicalTop = child->logicalTop();
3709    int lowestFloatLogicalBottom = 0;
3710
3711    // Floats that will remain the child's responsibility to paint should factor into its
3712    // overflow.
3713    FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
3714    for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
3715        FloatingObject* r = *childIt;
3716        int logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<int>::max() - childLogicalTop);
3717        int logicalBottom = childLogicalTop + logicalBottomForFloat;
3718        lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
3719
3720        if (logicalBottom > logicalHeight()) {
3721            // If the object is not in the list, we add it now.
3722            if (!containsFloat(r->m_renderer)) {
3723                int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
3724                int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
3725                FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
3726                floatingObj->m_renderer = r->m_renderer;
3727
3728                // The nearest enclosing layer always paints the float (so that zindex and stacking
3729                // behaves properly).  We always want to propagate the desire to paint the float as
3730                // far out as we can, to the outermost block that overlaps the float, stopping only
3731                // if we hit a self-painting layer boundary.
3732                if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer())
3733                    r->m_shouldPaint = false;
3734                else
3735                    floatingObj->m_shouldPaint = false;
3736
3737                floatingObj->m_isDescendant = true;
3738
3739                // We create the floating object list lazily.
3740                if (!m_floatingObjects)
3741                    m_floatingObjects = adoptPtr(new FloatingObjects);
3742
3743                m_floatingObjects->increaseObjectsCount(floatingObj->type());
3744                m_floatingObjects->set().add(floatingObj);
3745            }
3746        } else {
3747            if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
3748                r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
3749                // The float is not overhanging from this block, so if it is a descendant of the child, the child should
3750                // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
3751                // layer.
3752                // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
3753                // it should paint.
3754                r->m_shouldPaint = true;
3755            }
3756
3757            // Since the float doesn't overhang, it didn't get put into our list.  We need to go ahead and add its overflow in to the
3758            // child now.
3759            if (r->m_isDescendant)
3760                child->addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
3761        }
3762    }
3763    return lowestFloatLogicalBottom;
3764}
3765
3766bool RenderBlock::hasOverhangingFloat(RenderBox* renderer)
3767{
3768    if (!m_floatingObjects || hasColumns() || !parent())
3769        return false;
3770
3771    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3772    FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(renderer);
3773    if (it == floatingObjectSet.end())
3774        return false;
3775
3776    return logicalBottomForFloat(*it) > logicalHeight();
3777}
3778
3779void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset)
3780{
3781    // If the parent or previous sibling doesn't have any floats to add, don't bother.
3782    if (!prev->m_floatingObjects)
3783        return;
3784
3785    logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop());
3786
3787    FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
3788    FloatingObjectSetIterator prevEnd = prevSet.end();
3789    for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
3790        FloatingObject* r = *prevIt;
3791        if (logicalBottomForFloat(r) > logicalTopOffset) {
3792            if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
3793                int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
3794                int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
3795
3796                FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
3797
3798                // Applying the child's margin makes no sense in the case where the child was passed in.
3799                // since this margin was added already through the modification of the |logicalLeftOffset| variable
3800                // above.  |logicalLeftOffset| will equal the margin in this case, so it's already been taken
3801                // into account.  Only apply this code if prev is the parent, since otherwise the left margin
3802                // will get applied twice.
3803                if (prev != parent()) {
3804                    if (isHorizontalWritingMode())
3805                        floatingObj->setX(floatingObj->x() + prev->marginLeft());
3806                    else
3807                        floatingObj->setY(floatingObj->y() + prev->marginTop());
3808                }
3809
3810                floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
3811                floatingObj->m_renderer = r->m_renderer;
3812
3813                // We create the floating object list lazily.
3814                if (!m_floatingObjects)
3815                    m_floatingObjects = adoptPtr(new FloatingObjects);
3816                m_floatingObjects->increaseObjectsCount(floatingObj->type());
3817                m_floatingObjects->set().add(floatingObj);
3818            }
3819        }
3820    }
3821}
3822
3823bool RenderBlock::avoidsFloats() const
3824{
3825    // Floats can't intrude into our box if we have a non-auto column count or width.
3826    return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
3827}
3828
3829bool RenderBlock::containsFloat(RenderBox* renderer)
3830{
3831    return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
3832}
3833
3834void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
3835{
3836    if (!m_everHadLayout)
3837        return;
3838
3839    setChildNeedsLayout(true, !inLayout);
3840
3841    if (floatToRemove)
3842        removeFloatingObject(floatToRemove);
3843
3844    // Iterate over our children and mark them as needed.
3845    if (!childrenInline()) {
3846        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
3847            if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
3848                continue;
3849            RenderBlock* childBlock = toRenderBlock(child);
3850            if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
3851                childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
3852        }
3853    }
3854}
3855
3856void RenderBlock::markSiblingsWithFloatsForLayout()
3857{
3858    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3859    FloatingObjectSetIterator end = floatingObjectSet.end();
3860    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
3861        if (logicalBottomForFloat(*it) > logicalHeight()) {
3862            RenderBox* floatingBox = (*it)->renderer();
3863
3864            RenderObject* next = nextSibling();
3865            while (next) {
3866                if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) {
3867                    RenderBlock* nextBlock = toRenderBlock(next);
3868                    if (nextBlock->containsFloat(floatingBox))
3869                        nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox);
3870                    else
3871                        break;
3872                }
3873
3874                next = next->nextSibling();
3875            }
3876        }
3877    }
3878}
3879
3880int RenderBlock::getClearDelta(RenderBox* child, int yPos)
3881{
3882    // There is no need to compute clearance if we have no floats.
3883    if (!containsFloats())
3884        return 0;
3885
3886    // At least one float is present.  We need to perform the clearance computation.
3887    bool clearSet = child->style()->clear() != CNONE;
3888    int bottom = 0;
3889    switch (child->style()->clear()) {
3890        case CNONE:
3891            break;
3892        case CLEFT:
3893            bottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
3894            break;
3895        case CRIGHT:
3896            bottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
3897            break;
3898        case CBOTH:
3899            bottom = lowestFloatLogicalBottom();
3900            break;
3901    }
3902
3903    // We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default).
3904    int result = clearSet ? max(0, bottom - yPos) : 0;
3905    if (!result && child->avoidsFloats()) {
3906        int y = yPos;
3907        while (true) {
3908            int widthAtY = availableLogicalWidthForLine(y, false);
3909            if (widthAtY == availableLogicalWidth())
3910                return y - yPos;
3911
3912            int oldChildY = child->y();
3913            int oldChildWidth = child->width();
3914            child->setY(y);
3915            child->computeLogicalWidth();
3916            int childWidthAtY = child->width();
3917            child->setY(oldChildY);
3918            child->setWidth(oldChildWidth);
3919
3920            if (childWidthAtY <= widthAtY)
3921                return y - yPos;
3922
3923            y = nextFloatLogicalBottomBelow(y);
3924            ASSERT(y >= yPos);
3925            if (y < yPos)
3926                break;
3927        }
3928        ASSERT_NOT_REACHED();
3929    }
3930    return result;
3931}
3932
3933bool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty)
3934{
3935    if (!scrollsOverflow())
3936        return false;
3937
3938    return layer()->hitTestOverflowControls(result, IntPoint(_x - _tx, _y - _ty));
3939}
3940
3941bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
3942{
3943    int tx = _tx + x();
3944    int ty = _ty + y();
3945
3946    if (!isRenderView()) {
3947        // Check if we need to do anything at all.
3948        IntRect overflowBox = visualOverflowRect();
3949        overflowBox.move(tx, ty);
3950        if (!overflowBox.intersects(result.rectForPoint(_x, _y)))
3951            return false;
3952    }
3953
3954    if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
3955        updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
3956        // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
3957        if (!result.addNodeToRectBasedTestResult(node(), _x, _y))
3958           return true;
3959    }
3960
3961    // If we have clipping, then we can't have any spillout.
3962    bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
3963    bool useClip = (hasControlClip() || useOverflowClip);
3964    IntRect hitTestArea(result.rectForPoint(_x, _y));
3965    bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty, IncludeOverlayScrollbarSize).intersects(hitTestArea));
3966    if (checkChildren) {
3967        // Hit test descendants first.
3968        int scrolledX = tx;
3969        int scrolledY = ty;
3970        if (hasOverflowClip()) {
3971            IntSize offset = layer()->scrolledContentOffset();
3972            scrolledX -= offset.width();
3973            scrolledY -= offset.height();
3974        }
3975
3976        // Hit test contents if we don't have columns.
3977        if (!hasColumns()) {
3978            if (hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
3979                updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
3980                return true;
3981            }
3982            if (hitTestAction == HitTestFloat && hitTestFloats(request, result, _x, _y, scrolledX, scrolledY))
3983                return true;
3984        } else if (hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
3985            updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
3986            return true;
3987        }
3988    }
3989
3990    // Now hit test our background
3991    if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
3992        IntRect boundsRect(tx, ty, width(), height());
3993        if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(_x, _y))) {
3994            updateHitTestResult(result, flipForWritingMode(IntPoint(_x - tx, _y - ty)));
3995            if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect))
3996                return true;
3997        }
3998    }
3999
4000    return false;
4001}
4002
4003bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
4004{
4005    if (!m_floatingObjects)
4006        return false;
4007
4008    if (isRenderView()) {
4009        tx += toRenderView(this)->frameView()->scrollX();
4010        ty += toRenderView(this)->frameView()->scrollY();
4011    }
4012
4013    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
4014    FloatingObjectSetIterator begin = floatingObjectSet.begin();
4015    for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
4016        --it;
4017        FloatingObject* floatingObject = *it;
4018        if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
4019            int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
4020            int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
4021            IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset));
4022            if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) {
4023                updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y()));
4024                return true;
4025            }
4026        }
4027    }
4028
4029    return false;
4030}
4031
4032bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
4033{
4034    // We need to do multiple passes, breaking up our hit testing into strips.
4035    ColumnInfo* colInfo = columnInfo();
4036    int colCount = columnCount(colInfo);
4037    if (!colCount)
4038        return false;
4039    int logicalLeft = logicalLeftOffsetForContent();
4040    int currLogicalTopOffset = 0;
4041    int i;
4042    bool isHorizontal = isHorizontalWritingMode();
4043    for (i = 0; i < colCount; i++) {
4044        IntRect colRect = columnRectAt(colInfo, i);
4045        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
4046        if (style()->isFlippedBlocksWritingMode())
4047            currLogicalTopOffset += blockDelta;
4048        else
4049            currLogicalTopOffset -= blockDelta;
4050    }
4051    for (i = colCount - 1; i >= 0; i--) {
4052        IntRect colRect = columnRectAt(colInfo, i);
4053        flipForWritingMode(colRect);
4054        int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
4055        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
4056        if (style()->isFlippedBlocksWritingMode())
4057            currLogicalTopOffset -= blockDelta;
4058        else
4059            currLogicalTopOffset += blockDelta;
4060        colRect.move(tx, ty);
4061
4062        if (colRect.intersects(result.rectForPoint(x, y))) {
4063            // The point is inside this column.
4064            // Adjust tx and ty to change where we hit test.
4065
4066            IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
4067            int finalX = tx + offset.width();
4068            int finalY = ty + offset.height();
4069            if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y)))
4070                hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
4071            else
4072                return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, x, y, finalX, finalY));
4073        }
4074    }
4075
4076    return false;
4077}
4078
4079bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
4080{
4081    if (childrenInline() && !isTable()) {
4082        // We have to hit-test our line boxes.
4083        if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction))
4084            return true;
4085    } else {
4086        // Hit test our children.
4087        HitTestAction childHitTest = hitTestAction;
4088        if (hitTestAction == HitTestChildBlockBackgrounds)
4089            childHitTest = HitTestChildBlockBackground;
4090        for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
4091            IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
4092            if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, childPoint.x(), childPoint.y(), childHitTest))
4093                return true;
4094        }
4095    }
4096
4097    return false;
4098}
4099
4100Position RenderBlock::positionForBox(InlineBox *box, bool start) const
4101{
4102    if (!box)
4103        return Position();
4104
4105    if (!box->renderer()->node())
4106        return Position(node(), start ? caretMinOffset() : caretMaxOffset());
4107
4108    if (!box->isInlineTextBox())
4109        return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
4110
4111    InlineTextBox *textBox = static_cast<InlineTextBox *>(box);
4112    return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
4113}
4114
4115// FIXME: This function should go on RenderObject as an instance method. Then
4116// all cases in which positionForPoint recurs could call this instead to
4117// prevent crossing editable boundaries. This would require many tests.
4118static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
4119{
4120    // FIXME: This is wrong if the child's writing-mode is different from the parent's.
4121    IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
4122
4123    // If this is an anonymous renderer, we just recur normally
4124    Node* childNode = child->node();
4125    if (!childNode)
4126        return child->positionForPoint(pointInChildCoordinates);
4127
4128    // Otherwise, first make sure that the editability of the parent and child agree.
4129    // If they don't agree, then we return a visible position just before or after the child
4130    RenderObject* ancestor = parent;
4131    while (ancestor && !ancestor->node())
4132        ancestor = ancestor->parent();
4133
4134    // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
4135    if (!ancestor || ancestor->node()->rendererIsEditable() == childNode->rendererIsEditable())
4136        return child->positionForPoint(pointInChildCoordinates);
4137
4138    // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
4139    int childMiddle = parent->logicalWidthForChild(child) / 2;
4140    int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
4141    if (logicalLeft < childMiddle)
4142        return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
4143    return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
4144}
4145
4146VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInLogicalContents)
4147{
4148    ASSERT(childrenInline());
4149
4150    if (!firstRootBox())
4151        return createVisiblePosition(0, DOWNSTREAM);
4152
4153    // look for the closest line box in the root box which is at the passed-in y coordinate
4154    InlineBox* closestBox = 0;
4155    RootInlineBox* firstRootBoxWithChildren = 0;
4156    RootInlineBox* lastRootBoxWithChildren = 0;
4157    for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
4158        if (!root->firstLeafChild())
4159            continue;
4160        if (!firstRootBoxWithChildren)
4161            firstRootBoxWithChildren = root;
4162        lastRootBoxWithChildren = root;
4163
4164        // check if this root line box is located at this y coordinate
4165        if (pointInLogicalContents.y() < root->selectionBottom()) {
4166            closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
4167            if (closestBox)
4168                break;
4169        }
4170    }
4171
4172    bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
4173
4174    if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
4175        // y coordinate is below last root line box, pretend we hit it
4176        closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
4177    }
4178
4179    if (closestBox) {
4180        if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()) {
4181            // y coordinate is above first root line box, so return the start of the first
4182            return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
4183        }
4184
4185        // pass the box a top position that is inside it
4186        IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
4187        if (!isHorizontalWritingMode())
4188            point = point.transposedPoint();
4189        if (closestBox->renderer()->isReplaced())
4190            return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
4191        return closestBox->renderer()->positionForPoint(point);
4192    }
4193
4194    if (lastRootBoxWithChildren) {
4195        // We hit this case for Mac behavior when the Y coordinate is below the last box.
4196        ASSERT(moveCaretToBoundary);
4197        InlineBox* logicallyLastBox;
4198        if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
4199            return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
4200    }
4201
4202    // Can't reach this. We have a root line box, but it has no kids.
4203    // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
4204    // seems to hit this code path.
4205    return createVisiblePosition(0, DOWNSTREAM);
4206}
4207
4208static inline bool isChildHitTestCandidate(RenderBox* box)
4209{
4210    return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrPositioned();
4211}
4212
4213VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
4214{
4215    if (isTable())
4216        return RenderBox::positionForPoint(point);
4217
4218    if (isReplaced()) {
4219        // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
4220        int pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
4221        int pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
4222
4223        if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
4224            return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
4225        if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
4226            return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
4227    }
4228
4229    int contentsX = point.x();
4230    int contentsY = point.y();
4231    offsetForContents(contentsX, contentsY);
4232    IntPoint pointInContents(contentsX, contentsY);
4233    IntPoint pointInLogicalContents(pointInContents);
4234    if (!isHorizontalWritingMode())
4235        pointInLogicalContents = pointInLogicalContents.transposedPoint();
4236
4237    if (childrenInline())
4238        return positionForPointWithInlineChildren(pointInLogicalContents);
4239
4240    if (lastChildBox() && pointInContents.y() > lastChildBox()->logicalTop()) {
4241        for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) {
4242            if (isChildHitTestCandidate(childBox))
4243                return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
4244        }
4245    } else {
4246        for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
4247            // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
4248            if (isChildHitTestCandidate(childBox) && pointInContents.y() < childBox->logicalBottom())
4249                return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
4250        }
4251    }
4252
4253    // We only get here if there are no hit test candidate children below the click.
4254    return RenderBox::positionForPoint(point);
4255}
4256
4257void RenderBlock::offsetForContents(int& tx, int& ty) const
4258{
4259    IntPoint contentsPoint(tx, ty);
4260
4261    if (hasOverflowClip())
4262        contentsPoint += layer()->scrolledContentOffset();
4263
4264    if (hasColumns())
4265        adjustPointToColumnContents(contentsPoint);
4266
4267    tx = contentsPoint.x();
4268    ty = contentsPoint.y();
4269}
4270
4271int RenderBlock::availableLogicalWidth() const
4272{
4273    // If we have multiple columns, then the available logical width is reduced to our column width.
4274    if (hasColumns())
4275        return desiredColumnWidth();
4276    return RenderBox::availableLogicalWidth();
4277}
4278
4279int RenderBlock::columnGap() const
4280{
4281    if (style()->hasNormalColumnGap())
4282        return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
4283    return static_cast<int>(style()->columnGap());
4284}
4285
4286void RenderBlock::calcColumnWidth()
4287{
4288    // Calculate our column width and column count.
4289    unsigned desiredColumnCount = 1;
4290    int desiredColumnWidth = contentLogicalWidth();
4291
4292    // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
4293    if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
4294        setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
4295        return;
4296    }
4297
4298    int availWidth = desiredColumnWidth;
4299    int colGap = columnGap();
4300    int colWidth = max(1, static_cast<int>(style()->columnWidth()));
4301    int colCount = max(1, static_cast<int>(style()->columnCount()));
4302
4303    if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
4304        desiredColumnCount = colCount;
4305        desiredColumnWidth = max<int>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
4306    } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
4307        desiredColumnCount = max<int>(1, (float)(availWidth + colGap) / (colWidth + colGap));
4308        desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
4309    } else {
4310        desiredColumnCount = max(min<int>(colCount, (float)(availWidth + colGap) / (colWidth + colGap)), 1);
4311        desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
4312    }
4313    setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
4314}
4315
4316void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
4317{
4318    bool destroyColumns = !firstChild()
4319                          || (count == 1 && style()->hasAutoColumnWidth())
4320                          || firstChild()->isAnonymousColumnsBlock()
4321                          || firstChild()->isAnonymousColumnSpanBlock();
4322    if (destroyColumns) {
4323        if (hasColumns()) {
4324            delete gColumnInfoMap->take(this);
4325            setHasColumns(false);
4326        }
4327    } else {
4328        ColumnInfo* info;
4329        if (hasColumns())
4330            info = gColumnInfoMap->get(this);
4331        else {
4332            if (!gColumnInfoMap)
4333                gColumnInfoMap = new ColumnInfoMap;
4334            info = new ColumnInfo;
4335            gColumnInfoMap->add(this, info);
4336            setHasColumns(true);
4337        }
4338        info->setDesiredColumnCount(count);
4339        info->setDesiredColumnWidth(width);
4340    }
4341}
4342
4343int RenderBlock::desiredColumnWidth() const
4344{
4345    if (!hasColumns())
4346        return contentLogicalWidth();
4347    return gColumnInfoMap->get(this)->desiredColumnWidth();
4348}
4349
4350unsigned RenderBlock::desiredColumnCount() const
4351{
4352    if (!hasColumns())
4353        return 1;
4354    return gColumnInfoMap->get(this)->desiredColumnCount();
4355}
4356
4357ColumnInfo* RenderBlock::columnInfo() const
4358{
4359    if (!hasColumns())
4360        return 0;
4361    return gColumnInfoMap->get(this);
4362}
4363
4364unsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
4365{
4366    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
4367    return colInfo->columnCount();
4368}
4369
4370IntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
4371{
4372    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
4373
4374    // Compute the appropriate rect based off our information.
4375    int colLogicalWidth = colInfo->desiredColumnWidth();
4376    int colLogicalHeight = colInfo->columnHeight();
4377    int colLogicalTop = borderBefore() + paddingBefore();
4378    int colGap = columnGap();
4379    int colLogicalLeft = style()->isLeftToRightDirection() ?
4380                          logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
4381                        : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
4382    IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
4383    if (isHorizontalWritingMode())
4384        return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
4385    return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
4386}
4387
4388bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher)
4389{
4390    if (!hasColumns())
4391        return false;
4392
4393    // FIXME: We don't balance properly at all in the presence of forced page breaks.  We need to understand what
4394    // the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
4395    ColumnInfo* colInfo = columnInfo();
4396    int desiredColumnCount = colInfo->desiredColumnCount();
4397    if (!hasSpecifiedPageLogicalHeight) {
4398        int columnHeight = pageLogicalHeight;
4399        int minColumnCount = colInfo->forcedBreaks() + 1;
4400        if (minColumnCount >= desiredColumnCount) {
4401            // The forced page breaks are in control of the balancing.  Just set the column height to the
4402            // maximum page break distance.
4403            if (!pageLogicalHeight) {
4404                int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(),
4405                                                view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
4406                columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
4407            }
4408        } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
4409            // Now that we know the intrinsic height of the columns, we have to rebalance them.
4410            columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount));
4411        }
4412
4413        if (columnHeight && columnHeight != pageLogicalHeight) {
4414            statePusher.pop();
4415            m_everHadLayout = true;
4416            layoutBlock(false, columnHeight);
4417            return true;
4418        }
4419    }
4420
4421    if (pageLogicalHeight)
4422        colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight);
4423
4424    if (columnCount(colInfo)) {
4425        setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
4426        m_overflow.clear();
4427    }
4428
4429    return false;
4430}
4431
4432void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
4433{
4434    // Just bail if we have no columns.
4435    if (!hasColumns())
4436        return;
4437
4438    ColumnInfo* colInfo = columnInfo();
4439    if (!columnCount(colInfo))
4440        return;
4441
4442    // Determine which columns we intersect.
4443    int colGap = columnGap();
4444    int halfColGap = colGap / 2;
4445    IntPoint columnPoint(columnRectAt(colInfo, 0).location());
4446    int logicalOffset = 0;
4447    for (unsigned i = 0; i < colInfo->columnCount(); i++) {
4448        // Add in half the column gap to the left and right of the rect.
4449        IntRect colRect = columnRectAt(colInfo, i);
4450        if (isHorizontalWritingMode()) {
4451            IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
4452            if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
4453                // FIXME: The clamping that follows is not completely right for right-to-left
4454                // content.
4455                // Clamp everything above the column to its top left.
4456                if (point.y() < gapAndColumnRect.y())
4457                    point = gapAndColumnRect.location();
4458                // Clamp everything below the column to the next column's top left. If there is
4459                // no next column, this still maps to just after this column.
4460                else if (point.y() >= gapAndColumnRect.maxY()) {
4461                    point = gapAndColumnRect.location();
4462                    point.move(0, gapAndColumnRect.height());
4463                }
4464
4465                // We're inside the column.  Translate the x and y into our column coordinate space.
4466                point.move(columnPoint.x() - colRect.x(), logicalOffset);
4467                return;
4468            }
4469
4470            // Move to the next position.
4471            logicalOffset += colRect.height();
4472        } else {
4473            IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
4474            if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
4475                // FIXME: The clamping that follows is not completely right for right-to-left
4476                // content.
4477                // Clamp everything above the column to its top left.
4478                if (point.x() < gapAndColumnRect.x())
4479                    point = gapAndColumnRect.location();
4480                // Clamp everything below the column to the next column's top left. If there is
4481                // no next column, this still maps to just after this column.
4482                else if (point.x() >= gapAndColumnRect.maxX()) {
4483                    point = gapAndColumnRect.location();
4484                    point.move(gapAndColumnRect.width(), 0);
4485                }
4486
4487                // We're inside the column.  Translate the x and y into our column coordinate space.
4488                point.move(logicalOffset, columnPoint.y() - colRect.y());
4489                return;
4490            }
4491
4492            // Move to the next position.
4493            logicalOffset += colRect.width();
4494        }
4495    }
4496}
4497
4498void RenderBlock::adjustRectForColumns(IntRect& r) const
4499{
4500    // Just bail if we have no columns.
4501    if (!hasColumns())
4502        return;
4503
4504    ColumnInfo* colInfo = columnInfo();
4505
4506    // Begin with a result rect that is empty.
4507    IntRect result;
4508
4509    // Determine which columns we intersect.
4510    unsigned colCount = columnCount(colInfo);
4511    if (!colCount)
4512        return;
4513
4514    int logicalLeft = logicalLeftOffsetForContent();
4515    int currLogicalOffset = 0;
4516
4517    for (unsigned i = 0; i < colCount; i++) {
4518        IntRect colRect = columnRectAt(colInfo, i);
4519        IntRect repaintRect = r;
4520        if (isHorizontalWritingMode()) {
4521            int currXOffset = colRect.x() - logicalLeft;
4522            repaintRect.move(currXOffset, currLogicalOffset);
4523            currLogicalOffset -= colRect.height();
4524        } else {
4525            int currYOffset = colRect.y() - logicalLeft;
4526            repaintRect.move(currLogicalOffset, currYOffset);
4527            currLogicalOffset -= colRect.width();
4528        }
4529        repaintRect.intersect(colRect);
4530        result.unite(repaintRect);
4531    }
4532
4533    r = result;
4534}
4535
4536IntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const
4537{
4538    ASSERT(hasColumns());
4539    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
4540        return point;
4541    ColumnInfo* colInfo = columnInfo();
4542    int columnLogicalHeight = colInfo->columnHeight();
4543    int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
4544    if (isHorizontalWritingMode())
4545        return IntPoint(point.x(), expandedLogicalHeight - point.y());
4546    return IntPoint(expandedLogicalHeight - point.x(), point.y());
4547}
4548
4549void RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
4550{
4551    ASSERT(hasColumns());
4552    if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
4553        return;
4554
4555    ColumnInfo* colInfo = columnInfo();
4556    int columnLogicalHeight = colInfo->columnHeight();
4557    int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
4558    if (isHorizontalWritingMode())
4559        rect.setY(expandedLogicalHeight - rect.maxY());
4560    else
4561        rect.setX(expandedLogicalHeight - rect.maxX());
4562}
4563
4564void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
4565{
4566    if (!hasColumns())
4567        return;
4568
4569    ColumnInfo* colInfo = columnInfo();
4570
4571    int logicalLeft = logicalLeftOffsetForContent();
4572    size_t colCount = columnCount(colInfo);
4573    int colLogicalWidth = colInfo->desiredColumnWidth();
4574    int colLogicalHeight = colInfo->columnHeight();
4575
4576    for (size_t i = 0; i < colCount; ++i) {
4577        // Compute the edges for a given column in the block progression direction.
4578        IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
4579        if (!isHorizontalWritingMode())
4580            sliceRect = sliceRect.transposedRect();
4581
4582        // If we have a flipped blocks writing mode, then convert the column so that it's coming from the after edge (either top or left edge).
4583        flipForWritingModeIncludingColumns(sliceRect);
4584
4585        int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
4586
4587        // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
4588        if (isHorizontalWritingMode()) {
4589            if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
4590                offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
4591                return;
4592            }
4593        } else {
4594            if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
4595                offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
4596                return;
4597            }
4598        }
4599    }
4600}
4601
4602void RenderBlock::computePreferredLogicalWidths()
4603{
4604    ASSERT(preferredLogicalWidthsDirty());
4605
4606    updateFirstLetter();
4607
4608    if (!isTableCell() && style()->logicalWidth().isFixed() && style()->logicalWidth().value() > 0)
4609        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->logicalWidth().value());
4610    else {
4611        m_minPreferredLogicalWidth = 0;
4612        m_maxPreferredLogicalWidth = 0;
4613
4614        if (childrenInline())
4615            computeInlinePreferredLogicalWidths();
4616        else
4617            computeBlockPreferredLogicalWidths();
4618
4619        m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
4620
4621        if (!style()->autoWrap() && childrenInline()) {
4622            m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
4623
4624            // A horizontal marquee with inline children has no minimum width.
4625            if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
4626                m_minPreferredLogicalWidth = 0;
4627        }
4628
4629        int scrollbarWidth = 0;
4630        if (hasOverflowClip() && style()->overflowY() == OSCROLL) {
4631            layer()->setHasVerticalScrollbar(true);
4632            scrollbarWidth = verticalScrollbarWidth();
4633            m_maxPreferredLogicalWidth += scrollbarWidth;
4634        }
4635
4636        if (isTableCell()) {
4637            Length w = toRenderTableCell(this)->styleOrColLogicalWidth();
4638            if (w.isFixed() && w.value() > 0) {
4639                m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value()));
4640                scrollbarWidth = 0;
4641            }
4642        }
4643
4644        m_minPreferredLogicalWidth += scrollbarWidth;
4645    }
4646
4647    if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) {
4648        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
4649        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
4650    }
4651
4652    if (style()->logicalMaxWidth().isFixed() && style()->logicalMaxWidth().value() != undefinedLength) {
4653        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
4654        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
4655    }
4656
4657    int borderAndPadding = borderAndPaddingLogicalWidth();
4658    m_minPreferredLogicalWidth += borderAndPadding;
4659    m_maxPreferredLogicalWidth += borderAndPadding;
4660
4661    setPreferredLogicalWidthsDirty(false);
4662}
4663
4664struct InlineMinMaxIterator {
4665/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
4666   inline min/max width calculations.  Note the following about the way it walks:
4667   (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
4668   (2) We do not drill into the children of floats or replaced elements, since you can't break
4669       in the middle of such an element.
4670   (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
4671       distinct borders/margin/padding that contribute to the min/max width.
4672*/
4673    RenderObject* parent;
4674    RenderObject* current;
4675    bool endOfInline;
4676
4677    InlineMinMaxIterator(RenderObject* p, bool end = false)
4678        :parent(p), current(p), endOfInline(end) {}
4679
4680    RenderObject* next();
4681};
4682
4683RenderObject* InlineMinMaxIterator::next()
4684{
4685    RenderObject* result = 0;
4686    bool oldEndOfInline = endOfInline;
4687    endOfInline = false;
4688    while (current || current == parent) {
4689        if (!oldEndOfInline &&
4690            (current == parent ||
4691             (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
4692            result = current->firstChild();
4693        if (!result) {
4694            // We hit the end of our inline. (It was empty, e.g., <span></span>.)
4695            if (!oldEndOfInline && current->isRenderInline()) {
4696                result = current;
4697                endOfInline = true;
4698                break;
4699            }
4700
4701            while (current && current != parent) {
4702                result = current->nextSibling();
4703                if (result) break;
4704                current = current->parent();
4705                if (current && current != parent && current->isRenderInline()) {
4706                    result = current;
4707                    endOfInline = true;
4708                    break;
4709                }
4710            }
4711        }
4712
4713        if (!result)
4714            break;
4715
4716        if (!result->isPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
4717             break;
4718
4719        current = result;
4720        result = 0;
4721    }
4722
4723    // Update our position.
4724    current = result;
4725    return current;
4726}
4727
4728static int getBPMWidth(int childValue, Length cssUnit)
4729{
4730    if (cssUnit.type() != Auto)
4731        return (cssUnit.isFixed() ? cssUnit.value() : childValue);
4732    return 0;
4733}
4734
4735static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
4736{
4737    RenderStyle* cstyle = child->style();
4738    if (endOfInline)
4739        return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) +
4740               getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) +
4741               child->borderEnd();
4742    return getBPMWidth(child->marginStart(), cstyle->marginStart()) +
4743               getBPMWidth(child->paddingStart(), cstyle->paddingStart()) +
4744               child->borderStart();
4745}
4746
4747static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
4748                                      RenderObject* trailingSpaceChild)
4749{
4750    if (trailingSpaceChild && trailingSpaceChild->isText()) {
4751        // Collapse away the trailing space at the end of a block.
4752        RenderText* t = toRenderText(trailingSpaceChild);
4753        const UChar space = ' ';
4754        const Font& font = t->style()->font(); // FIXME: This ignores first-line.
4755        float spaceWidth = font.width(TextRun(&space, 1));
4756        inlineMax -= spaceWidth + font.wordSpacing();
4757        if (inlineMin > inlineMax)
4758            inlineMin = inlineMax;
4759    }
4760}
4761
4762static inline void updatePreferredWidth(int& preferredWidth, float& result)
4763{
4764    int snappedResult = ceilf(result);
4765    preferredWidth = max(snappedResult, preferredWidth);
4766}
4767
4768void RenderBlock::computeInlinePreferredLogicalWidths()
4769{
4770    float inlineMax = 0;
4771    float inlineMin = 0;
4772
4773    int cw = containingBlock()->contentLogicalWidth();
4774
4775    // If we are at the start of a line, we want to ignore all white-space.
4776    // Also strip spaces if we previously had text that ended in a trailing space.
4777    bool stripFrontSpaces = true;
4778    RenderObject* trailingSpaceChild = 0;
4779
4780    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
4781    // very specific cirucumstances (in order to match common WinIE renderings).
4782    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
4783    bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
4784
4785    bool autoWrap, oldAutoWrap;
4786    autoWrap = oldAutoWrap = style()->autoWrap();
4787
4788    InlineMinMaxIterator childIterator(this);
4789    bool addedTextIndent = false; // Only gets added in once.
4790    RenderObject* prevFloat = 0;
4791    while (RenderObject* child = childIterator.next()) {
4792        autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
4793            child->style()->autoWrap();
4794
4795        if (!child->isBR()) {
4796            // Step One: determine whether or not we need to go ahead and
4797            // terminate our current line.  Each discrete chunk can become
4798            // the new min-width, if it is the widest chunk seen so far, and
4799            // it can also become the max-width.
4800
4801            // Children fall into three categories:
4802            // (1) An inline flow object.  These objects always have a min/max of 0,
4803            // and are included in the iteration solely so that their margins can
4804            // be added in.
4805            //
4806            // (2) An inline non-text non-flow object, e.g., an inline replaced element.
4807            // These objects can always be on a line by themselves, so in this situation
4808            // we need to go ahead and break the current line, and then add in our own
4809            // margins and min/max width on its own line, and then terminate the line.
4810            //
4811            // (3) A text object.  Text runs can have breakable characters at the start,
4812            // the middle or the end.  They may also lose whitespace off the front if
4813            // we're already ignoring whitespace.  In order to compute accurate min-width
4814            // information, we need three pieces of information.
4815            // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
4816            // starts with whitespace.
4817            // (b) the min-width of the last non-breakable run. Should be 0 if the text string
4818            // ends with whitespace.
4819            // (c) the min/max width of the string (trimmed for whitespace).
4820            //
4821            // If the text string starts with whitespace, then we need to go ahead and
4822            // terminate our current line (unless we're already in a whitespace stripping
4823            // mode.
4824            //
4825            // If the text string has a breakable character in the middle, but didn't start
4826            // with whitespace, then we add the width of the first non-breakable run and
4827            // then end the current line.  We then need to use the intermediate min/max width
4828            // values (if any of them are larger than our current min/max).  We then look at
4829            // the width of the last non-breakable run and use that to start a new line
4830            // (unless we end in whitespace).
4831            RenderStyle* cstyle = child->style();
4832            float childMin = 0;
4833            float childMax = 0;
4834
4835            if (!child->isText()) {
4836                // Case (1) and (2).  Inline replaced and inline flow elements.
4837                if (child->isRenderInline()) {
4838                    // Add in padding/border/margin from the appropriate side of
4839                    // the element.
4840                    float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
4841                    childMin += bpm;
4842                    childMax += bpm;
4843
4844                    inlineMin += childMin;
4845                    inlineMax += childMax;
4846
4847                    child->setPreferredLogicalWidthsDirty(false);
4848                } else {
4849                    // Inline replaced elts add in their margins to their min/max values.
4850                    float margins = 0;
4851                    Length startMargin = cstyle->marginStart();
4852                    Length endMargin = cstyle->marginEnd();
4853                    if (startMargin.isFixed())
4854                        margins += startMargin.value();
4855                    if (endMargin.isFixed())
4856                        margins += endMargin.value();
4857                    childMin += margins;
4858                    childMax += margins;
4859                }
4860            }
4861
4862            if (!child->isRenderInline() && !child->isText()) {
4863                // Case (2). Inline replaced elements and floats.
4864                // Go ahead and terminate the current line as far as
4865                // minwidth is concerned.
4866                childMin += child->minPreferredLogicalWidth();
4867                childMax += child->maxPreferredLogicalWidth();
4868
4869                bool clearPreviousFloat;
4870                if (child->isFloating()) {
4871                    clearPreviousFloat = (prevFloat
4872                        && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT))
4873                            || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT))));
4874                    prevFloat = child;
4875                } else
4876                    clearPreviousFloat = false;
4877
4878                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
4879                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
4880                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
4881                    inlineMin = 0;
4882                }
4883
4884                // If we're supposed to clear the previous float, then terminate maxwidth as well.
4885                if (clearPreviousFloat) {
4886                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
4887                    inlineMax = 0;
4888                }
4889
4890                // Add in text-indent.  This is added in only once.
4891                int ti = 0;
4892                if (!addedTextIndent) {
4893                    addedTextIndent = true;
4894                    ti = style()->textIndent().calcMinValue(cw);
4895                    childMin += ti;
4896                    childMax += ti;
4897                }
4898
4899                // Add our width to the max.
4900                inlineMax += childMax;
4901
4902                if (!autoWrap || !canBreakReplacedElement) {
4903                    if (child->isFloating())
4904                        updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
4905                    else
4906                        inlineMin += childMin;
4907                } else {
4908                    // Now check our line.
4909                    updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
4910
4911                    // Now start a new line.
4912                    inlineMin = 0;
4913                }
4914
4915                // We are no longer stripping whitespace at the start of
4916                // a line.
4917                if (!child->isFloating()) {
4918                    stripFrontSpaces = false;
4919                    trailingSpaceChild = 0;
4920                }
4921            } else if (child->isText()) {
4922                // Case (3). Text.
4923                RenderText* t = toRenderText(child);
4924
4925                if (t->isWordBreak()) {
4926                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
4927                    inlineMin = 0;
4928                    continue;
4929                }
4930
4931                if (t->style()->hasTextCombine() && t->isCombineText())
4932                    toRenderCombineText(t)->combineText();
4933
4934                // Determine if we have a breakable character.  Pass in
4935                // whether or not we should ignore any spaces at the front
4936                // of the string.  If those are going to be stripped out,
4937                // then they shouldn't be considered in the breakable char
4938                // check.
4939                bool hasBreakableChar, hasBreak;
4940                float beginMin, endMin;
4941                bool beginWS, endWS;
4942                float beginMax, endMax;
4943                t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
4944                                     hasBreakableChar, hasBreak, beginMax, endMax,
4945                                     childMin, childMax, stripFrontSpaces);
4946
4947                // This text object will not be rendered, but it may still provide a breaking opportunity.
4948                if (!hasBreak && childMax == 0) {
4949                    if (autoWrap && (beginWS || endWS)) {
4950                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
4951                        inlineMin = 0;
4952                    }
4953                    continue;
4954                }
4955
4956                if (stripFrontSpaces)
4957                    trailingSpaceChild = child;
4958                else
4959                    trailingSpaceChild = 0;
4960
4961                // Add in text-indent.  This is added in only once.
4962                int ti = 0;
4963                if (!addedTextIndent) {
4964                    addedTextIndent = true;
4965                    ti = style()->textIndent().calcMinValue(cw);
4966                    childMin+=ti; beginMin += ti;
4967                    childMax+=ti; beginMax += ti;
4968                }
4969
4970                // If we have no breakable characters at all,
4971                // then this is the easy case. We add ourselves to the current
4972                // min and max and continue.
4973                if (!hasBreakableChar) {
4974                    inlineMin += childMin;
4975                } else {
4976                    // We have a breakable character.  Now we need to know if
4977                    // we start and end with whitespace.
4978                    if (beginWS)
4979                        // Go ahead and end the current line.
4980                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
4981                    else {
4982                        inlineMin += beginMin;
4983                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
4984                        childMin -= ti;
4985                    }
4986
4987                    inlineMin = childMin;
4988
4989                    if (endWS) {
4990                        // We end in whitespace, which means we can go ahead
4991                        // and end our current line.
4992                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
4993                        inlineMin = 0;
4994                    } else {
4995                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
4996                        inlineMin = endMin;
4997                    }
4998                }
4999
5000                if (hasBreak) {
5001                    inlineMax += beginMax;
5002                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
5003                    updatePreferredWidth(m_maxPreferredLogicalWidth, childMax);
5004                    inlineMax = endMax;
5005                } else
5006                    inlineMax += childMax;
5007            }
5008
5009            // Ignore spaces after a list marker.
5010            if (child->isListMarker())
5011                stripFrontSpaces = true;
5012        } else {
5013            updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
5014            updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
5015            inlineMin = inlineMax = 0;
5016            stripFrontSpaces = true;
5017            trailingSpaceChild = 0;
5018        }
5019
5020        oldAutoWrap = autoWrap;
5021    }
5022
5023    if (style()->collapseWhiteSpace())
5024        stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
5025
5026    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
5027    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
5028}
5029
5030// Use a very large value (in effect infinite).
5031#define BLOCK_MAX_WIDTH 15000
5032
5033void RenderBlock::computeBlockPreferredLogicalWidths()
5034{
5035    bool nowrap = style()->whiteSpace() == NOWRAP;
5036
5037    RenderObject *child = firstChild();
5038    int floatLeftWidth = 0, floatRightWidth = 0;
5039    while (child) {
5040        // Positioned children don't affect the min/max width
5041        if (child->isPositioned()) {
5042            child = child->nextSibling();
5043            continue;
5044        }
5045
5046        if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
5047            int floatTotalWidth = floatLeftWidth + floatRightWidth;
5048            if (child->style()->clear() & CLEFT) {
5049                m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
5050                floatLeftWidth = 0;
5051            }
5052            if (child->style()->clear() & CRIGHT) {
5053                m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
5054                floatRightWidth = 0;
5055            }
5056        }
5057
5058        // A margin basically has three types: fixed, percentage, and auto (variable).
5059        // Auto and percentage margins simply become 0 when computing min/max width.
5060        // Fixed margins can be added in as is.
5061        Length startMarginLength = child->style()->marginStart();
5062        Length endMarginLength = child->style()->marginEnd();
5063        int margin = 0;
5064        int marginStart = 0;
5065        int marginEnd = 0;
5066        if (startMarginLength.isFixed())
5067            marginStart += startMarginLength.value();
5068        if (endMarginLength.isFixed())
5069            marginEnd += endMarginLength.value();
5070        margin = marginStart + marginEnd;
5071
5072        int w = child->minPreferredLogicalWidth() + margin;
5073        m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
5074
5075        // IE ignores tables for calculation of nowrap. Makes some sense.
5076        if (nowrap && !child->isTable())
5077            m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
5078
5079        w = child->maxPreferredLogicalWidth() + margin;
5080
5081        if (!child->isFloating()) {
5082            if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
5083                // Determine a left and right max value based off whether or not the floats can fit in the
5084                // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
5085                // is smaller than the float width.
5086                bool ltr = containingBlock()->style()->isLeftToRightDirection();
5087                int marginLogicalLeft = ltr ? marginStart : marginEnd;
5088                int marginLogicalRight = ltr ? marginEnd : marginStart;
5089                int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
5090                int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
5091                w = child->maxPreferredLogicalWidth() + maxLeft + maxRight;
5092                w = max(w, floatLeftWidth + floatRightWidth);
5093            }
5094            else
5095                m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
5096            floatLeftWidth = floatRightWidth = 0;
5097        }
5098
5099        if (child->isFloating()) {
5100            if (style()->floating() == FLEFT)
5101                floatLeftWidth += w;
5102            else
5103                floatRightWidth += w;
5104        } else
5105            m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
5106
5107        // A very specific WinIE quirk.
5108        // Example:
5109        /*
5110           <div style="position:absolute; width:100px; top:50px;">
5111              <div style="position:absolute;left:0px;top:50px;height:50px;background-color:green">
5112                <table style="width:100%"><tr><td></table>
5113              </div>
5114           </div>
5115        */
5116        // In the above example, the inner absolute positioned block should have a computed width
5117        // of 100px because of the table.
5118        // We can achieve this effect by making the maxwidth of blocks that contain tables
5119        // with percentage widths be infinite (as long as they are not inside a table cell).
5120        if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() &&
5121            !isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) {
5122            RenderBlock* cb = containingBlock();
5123            while (!cb->isRenderView() && !cb->isTableCell())
5124                cb = cb->containingBlock();
5125            if (!cb->isTableCell())
5126                m_maxPreferredLogicalWidth = BLOCK_MAX_WIDTH;
5127        }
5128
5129        child = child->nextSibling();
5130    }
5131
5132    // Always make sure these values are non-negative.
5133    m_minPreferredLogicalWidth = max(0, m_minPreferredLogicalWidth);
5134    m_maxPreferredLogicalWidth = max(0, m_maxPreferredLogicalWidth);
5135
5136    m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
5137}
5138
5139bool RenderBlock::hasLineIfEmpty() const
5140{
5141    if (!node())
5142        return false;
5143
5144    if (node()->rendererIsEditable() && node()->rootEditableElement() == node())
5145        return true;
5146
5147    if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag)))
5148        return true;
5149
5150    return false;
5151}
5152
5153int RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
5154{
5155    // Inline blocks are replaced elements. Otherwise, just pass off to
5156    // the base class.  If we're being queried as though we're the root line
5157    // box, then the fact that we're an inline-block is irrelevant, and we behave
5158    // just like a block.
5159    if (isReplaced() && linePositionMode == PositionOnContainingLine)
5160        return RenderBox::lineHeight(firstLine, direction, linePositionMode);
5161
5162    if (firstLine && document()->usesFirstLineRules()) {
5163        RenderStyle* s = style(firstLine);
5164        if (s != style())
5165            return s->computedLineHeight();
5166    }
5167
5168    if (m_lineHeight == -1)
5169        m_lineHeight = style()->computedLineHeight();
5170
5171    return m_lineHeight;
5172}
5173
5174int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
5175{
5176    // Inline blocks are replaced elements. Otherwise, just pass off to
5177    // the base class.  If we're being queried as though we're the root line
5178    // box, then the fact that we're an inline-block is irrelevant, and we behave
5179    // just like a block.
5180    if (isReplaced() && linePositionMode == PositionOnContainingLine) {
5181        // For "leaf" theme objects, let the theme decide what the baseline position is.
5182        // FIXME: Might be better to have a custom CSS property instead, so that if the theme
5183        // is turned off, checkboxes/radios will still have decent baselines.
5184        // FIXME: Need to patch form controls to deal with vertical lines.
5185        if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
5186            return theme()->baselinePosition(this);
5187
5188        // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
5189        // the normal flow.  We make an exception for marquees, since their baselines are meaningless
5190        // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
5191        // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
5192        // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
5193        // of our content box.
5194        bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
5195            : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
5196
5197        int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline();
5198
5199        int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
5200        if (baselinePos != -1 && baselinePos <= bottomOfContent)
5201            return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
5202
5203        return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
5204    }
5205
5206    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
5207    return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
5208}
5209
5210int RenderBlock::firstLineBoxBaseline() const
5211{
5212    if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
5213        return -1;
5214
5215    if (childrenInline()) {
5216        if (firstLineBox())
5217            return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
5218        else
5219            return -1;
5220    }
5221    else {
5222        for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
5223            if (!curr->isFloatingOrPositioned()) {
5224                int result = curr->firstLineBoxBaseline();
5225                if (result != -1)
5226                    return curr->logicalTop() + result; // Translate to our coordinate space.
5227            }
5228        }
5229    }
5230
5231    return -1;
5232}
5233
5234int RenderBlock::lastLineBoxBaseline() const
5235{
5236    if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
5237        return -1;
5238
5239    LineDirectionMode lineDirection = isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
5240
5241    if (childrenInline()) {
5242        if (!firstLineBox() && hasLineIfEmpty()) {
5243            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
5244            return fontMetrics.ascent()
5245                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
5246                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
5247        }
5248        if (lastLineBox())
5249            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
5250        return -1;
5251    } else {
5252        bool haveNormalFlowChild = false;
5253        for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
5254            if (!curr->isFloatingOrPositioned()) {
5255                haveNormalFlowChild = true;
5256                int result = curr->lastLineBoxBaseline();
5257                if (result != -1)
5258                    return curr->logicalTop() + result; // Translate to our coordinate space.
5259            }
5260        }
5261        if (!haveNormalFlowChild && hasLineIfEmpty()) {
5262            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
5263            return fontMetrics.ascent()
5264                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
5265                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
5266        }
5267    }
5268
5269    return -1;
5270}
5271
5272bool RenderBlock::containsNonZeroBidiLevel() const
5273{
5274    for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
5275        for (InlineBox* box = root->firstLeafChild(); box; box = box->nextLeafChild()) {
5276            if (box->bidiLevel())
5277                return true;
5278        }
5279    }
5280    return false;
5281}
5282
5283RenderBlock* RenderBlock::firstLineBlock() const
5284{
5285    RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
5286    bool hasPseudo = false;
5287    while (true) {
5288        hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
5289        if (hasPseudo)
5290            break;
5291        RenderObject* parentBlock = firstLineBlock->parent();
5292        if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() ||
5293            !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
5294            break;
5295        ASSERT(parentBlock->isRenderBlock());
5296        firstLineBlock = toRenderBlock(parentBlock);
5297    }
5298
5299    if (!hasPseudo)
5300        return 0;
5301
5302    return firstLineBlock;
5303}
5304
5305static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
5306{
5307    RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
5308    // Force inline display (except for floating first-letters).
5309    pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
5310    // CSS2 says first-letter can't be positioned.
5311    pseudoStyle->setPosition(StaticPosition);
5312    return pseudoStyle;
5313}
5314
5315// CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
5316// "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
5317// "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
5318static inline bool isPunctuationForFirstLetter(UChar c)
5319{
5320    CharCategory charCategory = category(c);
5321    return charCategory == Punctuation_Open
5322        || charCategory == Punctuation_Close
5323        || charCategory == Punctuation_InitialQuote
5324        || charCategory == Punctuation_FinalQuote
5325        || charCategory == Punctuation_Other;
5326}
5327
5328static inline bool shouldSkipForFirstLetter(UChar c)
5329{
5330    return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
5331}
5332
5333void RenderBlock::updateFirstLetter()
5334{
5335    if (!document()->usesFirstLetterRules())
5336        return;
5337    // Don't recur
5338    if (style()->styleType() == FIRST_LETTER)
5339        return;
5340
5341    // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
5342    // an efficient way to check for that situation though before implementing anything.
5343    RenderObject* firstLetterBlock = this;
5344    bool hasPseudoStyle = false;
5345    while (true) {
5346        // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
5347        // prevents form controls from honoring first-letter.
5348        hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
5349            && firstLetterBlock->canHaveChildren();
5350        if (hasPseudoStyle)
5351            break;
5352        RenderObject* parentBlock = firstLetterBlock->parent();
5353        if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
5354            !parentBlock->isBlockFlow())
5355            break;
5356        firstLetterBlock = parentBlock;
5357    }
5358
5359    if (!hasPseudoStyle)
5360        return;
5361
5362    // Drill into inlines looking for our first text child.
5363    RenderObject* currChild = firstLetterBlock->firstChild();
5364    while (currChild && ((!currChild->isReplaced() && !currChild->isRenderButton() && !currChild->isMenuList()) || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
5365        if (currChild->isFloatingOrPositioned()) {
5366            if (currChild->style()->styleType() == FIRST_LETTER) {
5367                currChild = currChild->firstChild();
5368                break;
5369            }
5370            currChild = currChild->nextSibling();
5371        } else
5372            currChild = currChild->firstChild();
5373    }
5374
5375    // Get list markers out of the way.
5376    while (currChild && currChild->isListMarker())
5377        currChild = currChild->nextSibling();
5378
5379    if (!currChild)
5380        return;
5381
5382    // If the child already has style, then it has already been created, so we just want
5383    // to update it.
5384    if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
5385        RenderObject* firstLetter = currChild->parent();
5386        RenderObject* firstLetterContainer = firstLetter->parent();
5387        RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
5388
5389        if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
5390            // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
5391            RenderObject* newFirstLetter;
5392            if (pseudoStyle->display() == INLINE)
5393                newFirstLetter = new (renderArena()) RenderInline(document());
5394            else
5395                newFirstLetter = new (renderArena()) RenderBlock(document());
5396            newFirstLetter->setStyle(pseudoStyle);
5397
5398            // Move the first letter into the new renderer.
5399            view()->disableLayoutState();
5400            while (RenderObject* child = firstLetter->firstChild()) {
5401                if (child->isText())
5402                    toRenderText(child)->removeAndDestroyTextBoxes();
5403                firstLetter->removeChild(child);
5404                newFirstLetter->addChild(child, 0);
5405            }
5406
5407            RenderTextFragment* remainingText = 0;
5408            RenderObject* nextSibling = firstLetter->nextSibling();
5409            RenderObject* next = nextSibling;
5410            while (next) {
5411                if (next->isText() && toRenderText(next)->isTextFragment()) {
5412                    remainingText = toRenderTextFragment(next);
5413                    break;
5414                }
5415                next = next->nextSibling();
5416            }
5417            if (remainingText) {
5418                ASSERT(remainingText->node()->renderer() == remainingText);
5419                // Replace the old renderer with the new one.
5420                remainingText->setFirstLetter(newFirstLetter);
5421            }
5422            firstLetter->destroy();
5423            firstLetter = newFirstLetter;
5424            firstLetterContainer->addChild(firstLetter, nextSibling);
5425            view()->enableLayoutState();
5426        } else
5427            firstLetter->setStyle(pseudoStyle);
5428
5429        for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
5430            if (genChild->isText())
5431                genChild->setStyle(pseudoStyle);
5432        }
5433
5434        return;
5435    }
5436
5437    if (!currChild->isText() || currChild->isBR())
5438        return;
5439
5440    // If the child does not already have style, we create it here.
5441    RenderObject* firstLetterContainer = currChild->parent();
5442
5443    // Our layout state is not valid for the repaints we are going to trigger by
5444    // adding and removing children of firstLetterContainer.
5445    view()->disableLayoutState();
5446
5447    RenderText* textObj = toRenderText(currChild);
5448
5449    // Create our pseudo style now that we have our firstLetterContainer determined.
5450    RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
5451
5452    RenderObject* firstLetter = 0;
5453    if (pseudoStyle->display() == INLINE)
5454        firstLetter = new (renderArena()) RenderInline(document());
5455    else
5456        firstLetter = new (renderArena()) RenderBlock(document());
5457    firstLetter->setStyle(pseudoStyle);
5458    firstLetterContainer->addChild(firstLetter, currChild);
5459
5460    // The original string is going to be either a generated content string or a DOM node's
5461    // string.  We want the original string before it got transformed in case first-letter has
5462    // no text-transform or a different text-transform applied to it.
5463    RefPtr<StringImpl> oldText = textObj->originalText();
5464    ASSERT(oldText);
5465
5466    if (oldText && oldText->length() > 0) {
5467        unsigned length = 0;
5468
5469        // Account for leading spaces and punctuation.
5470        while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[length]))
5471            length++;
5472
5473        // Account for first letter.
5474        length++;
5475
5476        // Keep looking for whitespace and allowed punctuation, but avoid
5477        // accumulating just whitespace into the :first-letter.
5478        for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLength) {
5479            UChar c = (*oldText)[scanLength];
5480
5481            if (!shouldSkipForFirstLetter(c))
5482                break;
5483
5484            if (isPunctuationForFirstLetter(c))
5485                length = scanLength + 1;
5486         }
5487
5488        // Construct a text fragment for the text after the first letter.
5489        // This text fragment might be empty.
5490        RenderTextFragment* remainingText =
5491            new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
5492        remainingText->setStyle(textObj->style());
5493        if (remainingText->node())
5494            remainingText->node()->setRenderer(remainingText);
5495
5496        firstLetterContainer->addChild(remainingText, textObj);
5497        firstLetterContainer->removeChild(textObj);
5498        remainingText->setFirstLetter(firstLetter);
5499
5500        // construct text fragment for the first letter
5501        RenderTextFragment* letter =
5502            new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
5503        letter->setStyle(pseudoStyle);
5504        firstLetter->addChild(letter);
5505
5506        textObj->destroy();
5507    }
5508    view()->enableLayoutState();
5509}
5510
5511// Helper methods for obtaining the last line, computing line counts and heights for line counts
5512// (crawling into blocks).
5513static bool shouldCheckLines(RenderObject* obj)
5514{
5515    return !obj->isFloatingOrPositioned() && !obj->isRunIn() &&
5516            obj->isBlockFlow() && obj->style()->height().isAuto() &&
5517            (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
5518}
5519
5520static RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count)
5521{
5522    if (block->style()->visibility() == VISIBLE) {
5523        if (block->childrenInline()) {
5524            for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
5525                if (count++ == i)
5526                    return box;
5527            }
5528        }
5529        else {
5530            for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) {
5531                if (shouldCheckLines(obj)) {
5532                    RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count);
5533                    if (box)
5534                        return box;
5535                }
5536            }
5537        }
5538    }
5539    return 0;
5540}
5541
5542static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
5543{
5544    if (block->style()->visibility() == VISIBLE) {
5545        if (block->childrenInline()) {
5546            for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
5547                if (++count == l)
5548                    return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
5549            }
5550        }
5551        else {
5552            RenderBox* normalFlowChildWithoutLines = 0;
5553            for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
5554                if (shouldCheckLines(obj)) {
5555                    int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
5556                    if (result != -1)
5557                        return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
5558                }
5559                else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
5560                    normalFlowChildWithoutLines = obj;
5561            }
5562            if (normalFlowChildWithoutLines && l == 0)
5563                return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
5564        }
5565    }
5566
5567    return -1;
5568}
5569
5570RootInlineBox* RenderBlock::lineAtIndex(int i)
5571{
5572    int count = 0;
5573    return getLineAtIndex(this, i, count);
5574}
5575
5576int RenderBlock::lineCount()
5577{
5578    int count = 0;
5579    if (style()->visibility() == VISIBLE) {
5580        if (childrenInline())
5581            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
5582                count++;
5583        else
5584            for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
5585                if (shouldCheckLines(obj))
5586                    count += toRenderBlock(obj)->lineCount();
5587    }
5588    return count;
5589}
5590
5591int RenderBlock::heightForLineCount(int l)
5592{
5593    int count = 0;
5594    return getHeightForLineCount(this, l, true, count);
5595}
5596
5597void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
5598{
5599    // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
5600    // for either overflow or translations via relative positioning.
5601    if (style()->visibility() == VISIBLE) {
5602        if (childrenInline()) {
5603            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
5604                if (box->firstChild())
5605                    left = min(left, x + static_cast<int>(box->firstChild()->x()));
5606                if (box->lastChild())
5607                    right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight())));
5608            }
5609        }
5610        else {
5611            for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
5612                if (!obj->isFloatingOrPositioned()) {
5613                    if (obj->isBlockFlow() && !obj->hasOverflowClip())
5614                        toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
5615                    else if (obj->style()->visibility() == VISIBLE) {
5616                        // We are a replaced element or some kind of non-block-flow object.
5617                        left = min(left, x + obj->x());
5618                        right = max(right, x + obj->x() + obj->width());
5619                    }
5620                }
5621            }
5622        }
5623
5624        if (m_floatingObjects) {
5625            FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
5626            FloatingObjectSetIterator end = floatingObjectSet.end();
5627            for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
5628                FloatingObject* r = *it;
5629                // Only examine the object if our m_shouldPaint flag is set.
5630                if (r->m_shouldPaint) {
5631                    int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
5632                    int floatRight = floatLeft + r->m_renderer->width();
5633                    left = min(left, floatLeft);
5634                    right = max(right, floatRight);
5635                }
5636            }
5637        }
5638    }
5639}
5640
5641void RenderBlock::borderFitAdjust(int& x, int& w) const
5642{
5643    if (style()->borderFit() == BorderFitBorder)
5644        return;
5645
5646    // Walk any normal flow lines to snugly fit.
5647    int left = INT_MAX;
5648    int right = INT_MIN;
5649    int oldWidth = w;
5650    adjustForBorderFit(0, left, right);
5651    if (left != INT_MAX) {
5652        left -= (borderLeft() + paddingLeft());
5653        if (left > 0) {
5654            x += left;
5655            w -= left;
5656        }
5657    }
5658    if (right != INT_MIN) {
5659        right += (borderRight() + paddingRight());
5660        if (right < oldWidth)
5661            w -= (oldWidth - right);
5662    }
5663}
5664
5665void RenderBlock::clearTruncation()
5666{
5667    if (style()->visibility() == VISIBLE) {
5668        if (childrenInline() && hasMarkupTruncation()) {
5669            setHasMarkupTruncation(false);
5670            for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
5671                box->clearTruncation();
5672        }
5673        else
5674            for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
5675                if (shouldCheckLines(obj))
5676                    toRenderBlock(obj)->clearTruncation();
5677    }
5678}
5679
5680void RenderBlock::setMaxMarginBeforeValues(int pos, int neg)
5681{
5682    if (!m_rareData) {
5683        if (pos == RenderBlockRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockRareData::negativeMarginBeforeDefault(this))
5684            return;
5685        m_rareData = new RenderBlockRareData(this);
5686    }
5687    m_rareData->m_margins.setPositiveMarginBefore(pos);
5688    m_rareData->m_margins.setNegativeMarginBefore(neg);
5689}
5690
5691void RenderBlock::setMaxMarginAfterValues(int pos, int neg)
5692{
5693    if (!m_rareData) {
5694        if (pos == RenderBlockRareData::positiveMarginAfterDefault(this) && neg == RenderBlockRareData::negativeMarginAfterDefault(this))
5695            return;
5696        m_rareData = new RenderBlockRareData(this);
5697    }
5698    m_rareData->m_margins.setPositiveMarginAfter(pos);
5699    m_rareData->m_margins.setNegativeMarginAfter(neg);
5700}
5701
5702void RenderBlock::setPaginationStrut(int strut)
5703{
5704    if (!m_rareData) {
5705        if (!strut)
5706            return;
5707        m_rareData = new RenderBlockRareData(this);
5708    }
5709    m_rareData->m_paginationStrut = strut;
5710}
5711
5712void RenderBlock::setPageLogicalOffset(int logicalOffset)
5713{
5714    if (!m_rareData) {
5715        if (!logicalOffset)
5716            return;
5717        m_rareData = new RenderBlockRareData(this);
5718    }
5719    m_rareData->m_pageLogicalOffset = logicalOffset;
5720}
5721
5722void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
5723{
5724    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
5725    // inline boxes above and below us (thus getting merged with them to form a single irregular
5726    // shape).
5727    if (isAnonymousBlockContinuation()) {
5728        // FIXME: This is wrong for block-flows that are horizontal.
5729        // https://bugs.webkit.org/show_bug.cgi?id=46781
5730        rects.append(IntRect(tx, ty - collapsedMarginBefore(),
5731                             width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
5732        continuation()->absoluteRects(rects,
5733                                      tx - x() + inlineElementContinuation()->containingBlock()->x(),
5734                                      ty - y() + inlineElementContinuation()->containingBlock()->y());
5735    } else
5736        rects.append(IntRect(tx, ty, width(), height()));
5737}
5738
5739void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
5740{
5741    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
5742    // inline boxes above and below us (thus getting merged with them to form a single irregular
5743    // shape).
5744    if (isAnonymousBlockContinuation()) {
5745        // FIXME: This is wrong for block-flows that are horizontal.
5746        // https://bugs.webkit.org/show_bug.cgi?id=46781
5747        FloatRect localRect(0, -collapsedMarginBefore(),
5748                            width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
5749        quads.append(localToAbsoluteQuad(localRect));
5750        continuation()->absoluteQuads(quads);
5751    } else
5752        quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
5753}
5754
5755IntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
5756{
5757    IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
5758    if (isAnonymousBlockContinuation())
5759        r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
5760    return r;
5761}
5762
5763RenderObject* RenderBlock::hoverAncestor() const
5764{
5765    return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
5766}
5767
5768void RenderBlock::updateDragState(bool dragOn)
5769{
5770    RenderBox::updateDragState(dragOn);
5771    if (continuation())
5772        continuation()->updateDragState(dragOn);
5773}
5774
5775RenderStyle* RenderBlock::outlineStyleForRepaint() const
5776{
5777    return isAnonymousBlockContinuation() ? continuation()->style() : style();
5778}
5779
5780void RenderBlock::childBecameNonInline(RenderObject*)
5781{
5782    makeChildrenNonInline();
5783    if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
5784        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
5785    // |this| may be dead here
5786}
5787
5788void RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
5789{
5790    if (result.innerNode())
5791        return;
5792
5793    Node* n = node();
5794    if (isAnonymousBlockContinuation())
5795        // We are in the margins of block elements that are part of a continuation.  In
5796        // this case we're actually still inside the enclosing element that was
5797        // split.  Go ahead and set our inner node accordingly.
5798        n = continuation()->node();
5799
5800    if (n) {
5801        result.setInnerNode(n);
5802        if (!result.innerNonSharedNode())
5803            result.setInnerNonSharedNode(n);
5804        result.setLocalPoint(point);
5805    }
5806}
5807
5808IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
5809{
5810    // Do the normal calculation in most cases.
5811    if (firstChild())
5812        return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
5813
5814    // This is a special case:
5815    // The element is not an inline element, and it's empty. So we have to
5816    // calculate a fake position to indicate where objects are to be inserted.
5817
5818    // FIXME: This does not take into account either :first-line or :first-letter
5819    // However, as soon as some content is entered, the line boxes will be
5820    // constructed and this kludge is not called any more. So only the caret size
5821    // of an empty :first-line'd block is wrong. I think we can live with that.
5822    RenderStyle* currentStyle = firstLineStyle();
5823    int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
5824
5825    enum CaretAlignment { alignLeft, alignRight, alignCenter };
5826
5827    CaretAlignment alignment = alignLeft;
5828
5829    switch (currentStyle->textAlign()) {
5830        case TAAUTO:
5831        case JUSTIFY:
5832            if (!currentStyle->isLeftToRightDirection())
5833                alignment = alignRight;
5834            break;
5835        case LEFT:
5836        case WEBKIT_LEFT:
5837            break;
5838        case CENTER:
5839        case WEBKIT_CENTER:
5840            alignment = alignCenter;
5841            break;
5842        case RIGHT:
5843        case WEBKIT_RIGHT:
5844            alignment = alignRight;
5845            break;
5846        case TASTART:
5847            if (!currentStyle->isLeftToRightDirection())
5848                alignment = alignRight;
5849            break;
5850        case TAEND:
5851            if (currentStyle->isLeftToRightDirection())
5852                alignment = alignRight;
5853            break;
5854    }
5855
5856    int x = borderLeft() + paddingLeft();
5857    int w = width();
5858
5859    switch (alignment) {
5860        case alignLeft:
5861            break;
5862        case alignCenter:
5863            x = (x + w - (borderRight() + paddingRight())) / 2;
5864            break;
5865        case alignRight:
5866            x = w - (borderRight() + paddingRight()) - caretWidth;
5867            break;
5868    }
5869
5870    if (extraWidthToEndOfLine) {
5871        if (isRenderBlock()) {
5872            *extraWidthToEndOfLine = w - (x + caretWidth);
5873        } else {
5874            // FIXME: This code looks wrong.
5875            // myRight and containerRight are set up, but then clobbered.
5876            // So *extraWidthToEndOfLine will always be 0 here.
5877
5878            int myRight = x + caretWidth;
5879            // FIXME: why call localToAbsoluteForContent() twice here, too?
5880            FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
5881
5882            int containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
5883            FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
5884
5885            *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
5886        }
5887    }
5888
5889    int y = paddingTop() + borderTop();
5890
5891    return IntRect(x, y, caretWidth, height);
5892}
5893
5894void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
5895{
5896    // For blocks inside inlines, we go ahead and include margins so that we run right up to the
5897    // inline boxes above and below us (thus getting merged with them to form a single irregular
5898    // shape).
5899    if (inlineElementContinuation()) {
5900        // FIXME: This check really isn't accurate.
5901        bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
5902        // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
5903        // FIXME: This is wrong for block-flows that are horizontal.
5904        // https://bugs.webkit.org/show_bug.cgi?id=46781
5905        bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
5906        int topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : 0;
5907        int bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : 0;
5908        IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
5909        if (!rect.isEmpty())
5910            rects.append(rect);
5911    } else if (width() && height())
5912        rects.append(IntRect(tx, ty, width(), height()));
5913
5914    if (!hasOverflowClip() && !hasControlClip()) {
5915        for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
5916            int top = max(curr->lineTop(), curr->logicalTop());
5917            int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight());
5918            IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
5919            if (!rect.isEmpty())
5920                rects.append(rect);
5921        }
5922
5923        for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
5924            if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
5925                RenderBox* box = toRenderBox(curr);
5926                FloatPoint pos;
5927                // FIXME: This doesn't work correctly with transforms.
5928                if (box->layer())
5929                    pos = curr->localToAbsolute();
5930                else
5931                    pos = FloatPoint(tx + box->x(), ty + box->y());
5932                box->addFocusRingRects(rects, pos.x(), pos.y());
5933            }
5934        }
5935    }
5936
5937    if (inlineElementContinuation())
5938        inlineElementContinuation()->addFocusRingRects(rects,
5939                                                       tx - x() + inlineElementContinuation()->containingBlock()->x(),
5940                                                       ty - y() + inlineElementContinuation()->containingBlock()->y());
5941}
5942
5943RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
5944{
5945    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
5946
5947    RenderBlock* newBox = 0;
5948    if (isFlexibleBox) {
5949        newStyle->setDisplay(BOX);
5950        newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */);
5951    } else {
5952        newStyle->setDisplay(BLOCK);
5953        newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
5954    }
5955
5956    newBox->setStyle(newStyle.release());
5957    return newBox;
5958}
5959
5960RenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const
5961{
5962    if (otherAnonymousBlock->isAnonymousColumnsBlock())
5963        return createAnonymousColumnsBlock();
5964    if (otherAnonymousBlock->isAnonymousColumnSpanBlock())
5965        return createAnonymousColumnSpanBlock();
5966    return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX);
5967}
5968
5969RenderBlock* RenderBlock::createAnonymousColumnsBlock() const
5970{
5971    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
5972    newStyle->inheritColumnPropertiesFrom(style());
5973    newStyle->setDisplay(BLOCK);
5974
5975    RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
5976    newBox->setStyle(newStyle.release());
5977    return newBox;
5978}
5979
5980RenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
5981{
5982    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
5983    newStyle->setColumnSpan(true);
5984    newStyle->setDisplay(BLOCK);
5985
5986    RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
5987    newBox->setStyle(newStyle.release());
5988    return newBox;
5989}
5990
5991int RenderBlock::nextPageLogicalTop(int logicalOffset) const
5992{
5993    LayoutState* layoutState = view()->layoutState();
5994    if (!layoutState->m_pageLogicalHeight)
5995        return logicalOffset;
5996
5997    // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
5998    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
5999    IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
6000    int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
6001    int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
6002    return logicalOffset + remainingLogicalHeight;
6003}
6004
6005static bool inNormalFlow(RenderBox* child)
6006{
6007    RenderBlock* curr = child->containingBlock();
6008    RenderBlock* initialBlock = child->view();
6009    while (curr && curr != initialBlock) {
6010        if (curr->hasColumns())
6011            return true;
6012        if (curr->isFloatingOrPositioned())
6013            return false;
6014        curr = curr->containingBlock();
6015    }
6016    return true;
6017}
6018
6019int RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset)
6020{
6021    // FIXME: Add page break checking here when we support printing.
6022    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
6023    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
6024    bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
6025    if (checkBeforeAlways && inNormalFlow(child)) {
6026        if (checkColumnBreaks)
6027            view()->layoutState()->addForcedColumnBreak(logicalOffset);
6028        return nextPageLogicalTop(logicalOffset);
6029    }
6030    return logicalOffset;
6031}
6032
6033int RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo)
6034{
6035    // FIXME: Add page break checking here when we support printing.
6036    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
6037    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
6038    bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
6039    if (checkAfterAlways && inNormalFlow(child)) {
6040        marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content.
6041        if (checkColumnBreaks)
6042            view()->layoutState()->addForcedColumnBreak(logicalOffset);
6043        return nextPageLogicalTop(logicalOffset);
6044    }
6045    return logicalOffset;
6046}
6047
6048int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
6049{
6050    bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
6051    if (!isUnsplittable)
6052        return logicalOffset;
6053    int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
6054    LayoutState* layoutState = view()->layoutState();
6055    if (layoutState->m_columnInfo)
6056        layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
6057    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
6058    if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
6059        return logicalOffset;
6060    IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
6061    int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
6062    int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
6063    if (remainingLogicalHeight < childLogicalHeight)
6064        return logicalOffset + remainingLogicalHeight;
6065    return logicalOffset;
6066}
6067
6068void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
6069{
6070    // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
6071    // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
6072    // the line on the top of the next page will appear too far down relative to the same kind of line at the top
6073    // of the first column.
6074    //
6075    // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow
6076    // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
6077    // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
6078    // for overflow to occur), and then cache visible overflow for each column rect.
6079    //
6080    // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
6081    // content that paints in a previous column (and content that paints in the following column).
6082    //
6083    // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
6084    // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
6085    // line and all following lines.
6086    LayoutState* layoutState = view()->layoutState();
6087    int pageLogicalHeight = layoutState->m_pageLogicalHeight;
6088    IntRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
6089    int logicalOffset = logicalVisualOverflow.y();
6090    int lineHeight = logicalVisualOverflow.maxY() - logicalOffset;
6091    if (layoutState->m_columnInfo)
6092        layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
6093    logicalOffset += delta;
6094    lineBox->setPaginationStrut(0);
6095    if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
6096        return;
6097    IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
6098    int offset = isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
6099    int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
6100    if (remainingLogicalHeight < lineHeight) {
6101        int totalLogicalHeight = lineHeight + max(0, logicalOffset);
6102        if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
6103            setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset));
6104        else {
6105            delta += remainingLogicalHeight;
6106            lineBox->setPaginationStrut(remainingLogicalHeight);
6107        }
6108    }
6109}
6110
6111int RenderBlock::collapsedMarginBeforeForChild(RenderBox* child) const
6112{
6113    // If the child has the same directionality as we do, then we can just return its
6114    // collapsed margin.
6115    if (!child->isWritingModeRoot())
6116        return child->collapsedMarginBefore();
6117
6118    // The child has a different directionality.  If the child is parallel, then it's just
6119    // flipped relative to us.  We can use the collapsed margin for the opposite edge.
6120    if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
6121        return child->collapsedMarginAfter();
6122
6123    // The child is perpendicular to us, which means its margins don't collapse but are on the
6124    // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
6125    return marginBeforeForChild(child);
6126}
6127
6128int RenderBlock::collapsedMarginAfterForChild(RenderBox* child) const
6129{
6130    // If the child has the same directionality as we do, then we can just return its
6131    // collapsed margin.
6132    if (!child->isWritingModeRoot())
6133        return child->collapsedMarginAfter();
6134
6135    // The child has a different directionality.  If the child is parallel, then it's just
6136    // flipped relative to us.  We can use the collapsed margin for the opposite edge.
6137    if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
6138        return child->collapsedMarginBefore();
6139
6140    // The child is perpendicular to us, which means its margins don't collapse but are on the
6141    // "logical left/right" side of the child box.  We can just return the raw margin in this case.
6142    return marginAfterForChild(child);
6143}
6144
6145int RenderBlock::marginBeforeForChild(RenderBoxModelObject* child) const
6146{
6147    switch (style()->writingMode()) {
6148    case TopToBottomWritingMode:
6149        return child->marginTop();
6150    case BottomToTopWritingMode:
6151        return child->marginBottom();
6152    case LeftToRightWritingMode:
6153        return child->marginLeft();
6154    case RightToLeftWritingMode:
6155        return child->marginRight();
6156    }
6157    ASSERT_NOT_REACHED();
6158    return child->marginTop();
6159}
6160
6161int RenderBlock::marginAfterForChild(RenderBoxModelObject* child) const
6162{
6163    switch (style()->writingMode()) {
6164    case TopToBottomWritingMode:
6165        return child->marginBottom();
6166    case BottomToTopWritingMode:
6167        return child->marginTop();
6168    case LeftToRightWritingMode:
6169        return child->marginRight();
6170    case RightToLeftWritingMode:
6171        return child->marginLeft();
6172    }
6173    ASSERT_NOT_REACHED();
6174    return child->marginBottom();
6175}
6176
6177int RenderBlock::marginStartForChild(RenderBoxModelObject* child) const
6178{
6179    if (isHorizontalWritingMode())
6180        return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight();
6181    return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom();
6182}
6183
6184int RenderBlock::marginEndForChild(RenderBoxModelObject* child) const
6185{
6186    if (isHorizontalWritingMode())
6187        return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft();
6188    return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop();
6189}
6190
6191void RenderBlock::setMarginStartForChild(RenderBox* child, int margin)
6192{
6193    if (isHorizontalWritingMode()) {
6194        if (style()->isLeftToRightDirection())
6195            child->setMarginLeft(margin);
6196        else
6197            child->setMarginRight(margin);
6198    } else {
6199        if (style()->isLeftToRightDirection())
6200            child->setMarginTop(margin);
6201        else
6202            child->setMarginBottom(margin);
6203    }
6204}
6205
6206void RenderBlock::setMarginEndForChild(RenderBox* child, int margin)
6207{
6208    if (isHorizontalWritingMode()) {
6209        if (style()->isLeftToRightDirection())
6210            child->setMarginRight(margin);
6211        else
6212            child->setMarginLeft(margin);
6213    } else {
6214        if (style()->isLeftToRightDirection())
6215            child->setMarginBottom(margin);
6216        else
6217            child->setMarginTop(margin);
6218    }
6219}
6220
6221void RenderBlock::setMarginBeforeForChild(RenderBox* child, int margin)
6222{
6223    switch (style()->writingMode()) {
6224    case TopToBottomWritingMode:
6225        child->setMarginTop(margin);
6226        break;
6227    case BottomToTopWritingMode:
6228        child->setMarginBottom(margin);
6229        break;
6230    case LeftToRightWritingMode:
6231        child->setMarginLeft(margin);
6232        break;
6233    case RightToLeftWritingMode:
6234        child->setMarginRight(margin);
6235        break;
6236    }
6237}
6238
6239void RenderBlock::setMarginAfterForChild(RenderBox* child, int margin)
6240{
6241    switch (style()->writingMode()) {
6242    case TopToBottomWritingMode:
6243        child->setMarginBottom(margin);
6244        break;
6245    case BottomToTopWritingMode:
6246        child->setMarginTop(margin);
6247        break;
6248    case LeftToRightWritingMode:
6249        child->setMarginRight(margin);
6250        break;
6251    case RightToLeftWritingMode:
6252        child->setMarginLeft(margin);
6253        break;
6254    }
6255}
6256
6257RenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
6258{
6259    int childBeforePositive = 0;
6260    int childBeforeNegative = 0;
6261    int childAfterPositive = 0;
6262    int childAfterNegative = 0;
6263
6264    int beforeMargin = 0;
6265    int afterMargin = 0;
6266
6267    RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
6268
6269    // If the child has the same directionality as we do, then we can just return its
6270    // margins in the same direction.
6271    if (!child->isWritingModeRoot()) {
6272        if (childRenderBlock) {
6273            childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
6274            childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
6275            childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
6276            childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
6277        } else {
6278            beforeMargin = child->marginBefore();
6279            afterMargin = child->marginAfter();
6280        }
6281    } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
6282        // The child has a different directionality.  If the child is parallel, then it's just
6283        // flipped relative to us.  We can use the margins for the opposite edges.
6284        if (childRenderBlock) {
6285            childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
6286            childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
6287            childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
6288            childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
6289        } else {
6290            beforeMargin = child->marginAfter();
6291            afterMargin = child->marginBefore();
6292        }
6293    } else {
6294        // The child is perpendicular to us, which means its margins don't collapse but are on the
6295        // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
6296        beforeMargin = marginBeforeForChild(child);
6297        afterMargin = marginAfterForChild(child);
6298    }
6299
6300    // Resolve uncollapsing margins into their positive/negative buckets.
6301    if (beforeMargin) {
6302        if (beforeMargin > 0)
6303            childBeforePositive = beforeMargin;
6304        else
6305            childBeforeNegative = -beforeMargin;
6306    }
6307    if (afterMargin) {
6308        if (afterMargin > 0)
6309            childAfterPositive = afterMargin;
6310        else
6311            childAfterNegative = -afterMargin;
6312    }
6313
6314    return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
6315}
6316
6317const char* RenderBlock::renderName() const
6318{
6319    if (isBody())
6320        return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
6321
6322    if (isFloating())
6323        return "RenderBlock (floating)";
6324    if (isPositioned())
6325        return "RenderBlock (positioned)";
6326    if (isAnonymousColumnsBlock())
6327        return "RenderBlock (anonymous multi-column)";
6328    if (isAnonymousColumnSpanBlock())
6329        return "RenderBlock (anonymous multi-column span)";
6330    if (isAnonymousBlock())
6331        return "RenderBlock (anonymous)";
6332    else if (isAnonymous())
6333        return "RenderBlock (generated)";
6334    if (isRelPositioned())
6335        return "RenderBlock (relative positioned)";
6336    if (isRunIn())
6337        return "RenderBlock (run-in)";
6338    return "RenderBlock";
6339}
6340
6341inline void RenderBlock::FloatingObjects::clear()
6342{
6343    m_set.clear();
6344    m_leftObjectsCount = 0;
6345    m_rightObjectsCount = 0;
6346}
6347
6348inline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
6349{
6350    if (type == FloatingObject::FloatLeft)
6351        m_leftObjectsCount++;
6352    else
6353        m_rightObjectsCount++;
6354}
6355
6356inline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
6357{
6358    if (type == FloatingObject::FloatLeft)
6359        m_leftObjectsCount--;
6360    else
6361        m_rightObjectsCount--;
6362}
6363
6364} // namespace WebCore
6365