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