Rename InlineBox::remove() to removeFromParent
[WebKit-https.git] / Source / WebCore / rendering / RenderBlock.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2007 David Smith (catfish.man@gmail.com)
5  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "RenderBlock.h"
26
27 #include "AXObjectCache.h"
28 #include "ColumnInfo.h"
29 #include "Document.h"
30 #include "Editor.h"
31 #include "Element.h"
32 #include "FloatQuad.h"
33 #include "Frame.h"
34 #include "FrameSelection.h"
35 #include "FrameView.h"
36 #include "GraphicsContext.h"
37 #include "HTMLInputElement.h"
38 #include "HTMLNames.h"
39 #include "HitTestLocation.h"
40 #include "HitTestResult.h"
41 #include "InlineIterator.h"
42 #include "InlineTextBox.h"
43 #include "LayoutRepainter.h"
44 #include "LogicalSelectionOffsetCaches.h"
45 #include "OverflowEvent.h"
46 #include "Page.h"
47 #include "PaintInfo.h"
48 #include "RenderBoxRegionInfo.h"
49 #include "RenderCombineText.h"
50 #include "RenderDeprecatedFlexibleBox.h"
51 #include "RenderFlexibleBox.h"
52 #include "RenderInline.h"
53 #include "RenderLayer.h"
54 #include "RenderMarquee.h"
55 #include "RenderNamedFlowThread.h"
56 #include "RenderRegion.h"
57 #include "RenderTableCell.h"
58 #include "RenderTextFragment.h"
59 #include "RenderTheme.h"
60 #include "RenderView.h"
61 #include "SVGTextRunRenderingContext.h"
62 #include "Settings.h"
63 #include "ShadowRoot.h"
64 #include "TransformState.h"
65 #include <wtf/StackStats.h>
66 #include <wtf/TemporaryChange.h>
67
68 #if ENABLE(CSS_SHAPES)
69 #include "ShapeInsideInfo.h"
70 #include "ShapeOutsideInfo.h"
71 #endif
72
73 #if ENABLE(IOS_TEXT_AUTOSIZING)
74 #include "HTMLElement.h"
75 #endif
76
77 using namespace std;
78 using namespace WTF;
79 using namespace Unicode;
80
81 namespace WebCore {
82
83 using namespace HTMLNames;
84
85 struct SameSizeAsRenderBlock : public RenderBox {
86     void* pointers[1];
87     RenderLineBoxList lineBoxes;
88     uint32_t bitfields;
89 };
90
91 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
92
93 typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
94 static ColumnInfoMap* gColumnInfoMap = 0;
95
96 static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
97 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
98
99 static TrackedContainerMap* gPositionedContainerMap = 0;
100 static TrackedContainerMap* gPercentHeightContainerMap = 0;
101     
102 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > ContinuationOutlineTableMap;
103
104 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
105 static int gDelayUpdateScrollInfo = 0;
106 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
107
108 static bool gColumnFlowSplitEnabled = true;
109
110 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
111 // only works on RenderBlocks. If this change, this class should be shared with other RenderBoxes.
112 class OverflowEventDispatcher {
113     WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
114 public:
115     OverflowEventDispatcher(const RenderBlock* block)
116         : m_block(block)
117         , m_hadHorizontalLayoutOverflow(false)
118         , m_hadVerticalLayoutOverflow(false)
119     {
120         m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER);
121         if (m_shouldDispatchEvent) {
122             m_hadHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
123             m_hadVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
124         }
125     }
126
127     ~OverflowEventDispatcher()
128     {
129         if (!m_shouldDispatchEvent)
130             return;
131
132         bool hasHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
133         bool hasVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
134
135         bool horizontalLayoutOverflowChanged = hasHorizontalLayoutOverflow != m_hadHorizontalLayoutOverflow;
136         bool verticalLayoutOverflowChanged = hasVerticalLayoutOverflow != m_hadVerticalLayoutOverflow;
137         if (horizontalLayoutOverflowChanged || verticalLayoutOverflowChanged)
138             m_block->view().frameView().scheduleEvent(OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow), m_block->element());
139     }
140
141 private:
142     const RenderBlock* m_block;
143     bool m_shouldDispatchEvent;
144     bool m_hadHorizontalLayoutOverflow;
145     bool m_hadVerticalLayoutOverflow;
146 };
147
148 // -------------------------------------------------------------------------------------------------------
149
150 RenderBlock::RenderBlock(Element* element, unsigned baseTypeFlags)
151     : RenderBox(element, baseTypeFlags | RenderBlockFlag)
152     , m_lineHeight(-1)
153     , m_hasMarginBeforeQuirk(false)
154     , m_hasMarginAfterQuirk(false)
155     , m_beingDestroyed(false)
156     , m_hasMarkupTruncation(false)
157     , m_hasBorderOrPaddingLogicalWidthChanged(false)
158 #if ENABLE(IOS_TEXT_AUTOSIZING)
159     , m_widthForTextAutosizing(-1)
160     , m_lineCountForTextAutosizing(NOT_SET)
161 #endif
162 {
163     setChildrenInline(true);
164 }
165
166 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
167 {
168     if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(block)) {
169         TrackedRendererListHashSet::iterator end = descendantSet->end();
170         for (TrackedRendererListHashSet::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
171             TrackedContainerMap::iterator it = containerMap->find(*descendant);
172             ASSERT(it != containerMap->end());
173             if (it == containerMap->end())
174                 continue;
175             HashSet<RenderBlock*>* containerSet = it->value.get();
176             ASSERT(containerSet->contains(block));
177             containerSet->remove(block);
178             if (containerSet->isEmpty())
179                 containerMap->remove(it);
180         }
181     }
182 }
183
184 RenderBlock::~RenderBlock()
185 {
186     if (hasColumns())
187         gColumnInfoMap->take(this);
188     if (gPercentHeightDescendantsMap)
189         removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
190     if (gPositionedDescendantsMap)
191         removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
192 }
193
194 RenderBlock* RenderBlock::createAnonymous(Document& document)
195 {
196     RenderBlock* renderer = new (*document.renderArena()) RenderBlockFlow(0);
197     renderer->setDocumentForAnonymous(document);
198     return renderer;
199 }
200
201 void RenderBlock::willBeDestroyed()
202 {
203     // Mark as being destroyed to avoid trouble with merges in removeChild().
204     m_beingDestroyed = true;
205
206     if (!documentBeingDestroyed()) {
207         if (firstChild() && firstChild()->isRunIn())
208             moveRunInToOriginalPosition(firstChild());
209     }
210
211     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
212     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
213     destroyLeftoverChildren();
214
215     // Destroy our continuation before anything other than anonymous children.
216     // The reason we don't destroy it before anonymous children is that they may
217     // have continuations of their own that are anonymous children of our continuation.
218     RenderBoxModelObject* continuation = this->continuation();
219     if (continuation) {
220         continuation->destroy();
221         setContinuation(0);
222     }
223     
224     if (!documentBeingDestroyed()) {
225         if (firstLineBox()) {
226             // We can't wait for RenderBox::destroy to clear the selection,
227             // because by then we will have nuked the line boxes.
228             // FIXME: The FrameSelection should be responsible for this when it
229             // is notified of DOM mutations.
230             if (isSelectionBorder())
231                 view().clearSelection();
232
233             // If we are an anonymous block, then our line boxes might have children
234             // that will outlast this block. In the non-anonymous block case those
235             // children will be destroyed by the time we return from this function.
236             if (isAnonymousBlock()) {
237                 for (auto box = firstLineBox(); box; box = box->nextLineBox()) {
238                     while (auto childBox = box->firstChild())
239                         childBox->removeFromParent();
240                 }
241             }
242         } else if (parent())
243             parent()->dirtyLinesFromChangedChild(this);
244     }
245
246     m_lineBoxes.deleteLineBoxes(renderArena());
247
248     if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
249         gDelayedUpdateScrollInfoSet->remove(this);
250
251     RenderBox::willBeDestroyed();
252 }
253
254 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
255 {
256     RenderStyle* oldStyle = style();
257
258     setReplaced(newStyle->isDisplayInlineType());
259     
260     if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle->position()) {
261         if (newStyle->position() == StaticPosition)
262             // Clear our positioned objects list. Our absolutely positioned descendants will be
263             // inserted into our containing block's positioned objects list during layout.
264             removePositionedObjects(0, NewContainingBlock);
265         else if (oldStyle->position() == StaticPosition) {
266             // Remove our absolutely positioned descendants from their current containing block.
267             // They will be inserted into our positioned objects list during layout.
268             RenderObject* cb = parent();
269             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
270                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
271                     cb = cb->containingBlock();
272                     break;
273                 }
274                 cb = cb->parent();
275             }
276             
277             if (cb->isRenderBlock())
278                 toRenderBlock(cb)->removePositionedObjects(this, NewContainingBlock);
279         }
280     }
281
282     RenderBox::styleWillChange(diff, newStyle);
283 }
284
285 static bool borderOrPaddingLogicalWidthChanged(const RenderStyle* oldStyle, const RenderStyle* newStyle)
286 {
287     if (newStyle->isHorizontalWritingMode())
288         return oldStyle->borderLeftWidth() != newStyle->borderLeftWidth()
289             || oldStyle->borderRightWidth() != newStyle->borderRightWidth()
290             || oldStyle->paddingLeft() != newStyle->paddingLeft()
291             || oldStyle->paddingRight() != newStyle->paddingRight();
292
293     return oldStyle->borderTopWidth() != newStyle->borderTopWidth()
294         || oldStyle->borderBottomWidth() != newStyle->borderBottomWidth()
295         || oldStyle->paddingTop() != newStyle->paddingTop()
296         || oldStyle->paddingBottom() != newStyle->paddingBottom();
297 }
298
299 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
300 {
301     RenderBox::styleDidChange(diff, oldStyle);
302     
303     RenderStyle* newStyle = style();
304     
305 #if ENABLE(CSS_SHAPES)
306     updateShapeInsideInfoAfterStyleChange(newStyle->resolvedShapeInside(), oldStyle ? oldStyle->resolvedShapeInside() : 0);
307 #endif
308
309     if (!isAnonymousBlock()) {
310         // Ensure that all of our continuation blocks pick up the new style.
311         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
312             RenderBoxModelObject* nextCont = currCont->continuation();
313             currCont->setContinuation(0);
314             currCont->setStyle(newStyle);
315             currCont->setContinuation(nextCont);
316         }
317     }
318
319     propagateStyleToAnonymousChildren(PropagateToBlockChildrenOnly);
320     m_lineHeight = -1;
321     
322     // It's possible for our border/padding to change, but for the overall logical width of the block to
323     // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
324     m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff == StyleDifferenceLayout && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle);
325 }
326
327 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
328 {
329     if (beforeChild && beforeChild->parent() == this)
330         return this;
331
332     RenderBlock* curr = toRenderBlock(continuation());
333     RenderBlock* nextToLast = this;
334     RenderBlock* last = this;
335     while (curr) {
336         if (beforeChild && beforeChild->parent() == curr) {
337             if (curr->firstChild() == beforeChild)
338                 return last;
339             return curr;
340         }
341
342         nextToLast = last;
343         last = curr;
344         curr = toRenderBlock(curr->continuation());
345     }
346
347     if (!beforeChild && !last->firstChild())
348         return nextToLast;
349     return last;
350 }
351
352 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
353 {
354     RenderBlock* flow = continuationBefore(beforeChild);
355     ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
356     RenderBoxModelObject* beforeChildParent = 0;
357     if (beforeChild)
358         beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
359     else {
360         RenderBoxModelObject* cont = flow->continuation();
361         if (cont)
362             beforeChildParent = cont;
363         else
364             beforeChildParent = flow;
365     }
366
367     if (newChild->isFloatingOrOutOfFlowPositioned()) {
368         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
369         return;
370     }
371
372     // A continuation always consists of two potential candidates: a block or an anonymous
373     // column span box holding column span children.
374     bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
375     bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
376     bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
377
378     if (flow == beforeChildParent) {
379         flow->addChildIgnoringContinuation(newChild, beforeChild);
380         return;
381     }
382     
383     // The goal here is to match up if we can, so that we can coalesce and create the
384     // minimal # of continuations needed for the inline.
385     if (childIsNormal == bcpIsNormal) {
386         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
387         return;
388     }
389     if (flowIsNormal == childIsNormal) {
390         flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
391         return;
392     }
393     beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
394 }
395
396
397 void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
398 {
399     ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
400         
401     // The goal is to locate a suitable box in which to place our child.
402     RenderBlock* beforeChildParent = 0;
403     if (beforeChild) {
404         RenderObject* curr = beforeChild;
405         while (curr && curr->parent() != this)
406             curr = curr->parent();
407         beforeChildParent = toRenderBlock(curr);
408         ASSERT(beforeChildParent);
409         ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent->isAnonymousColumnSpanBlock());
410     } else
411         beforeChildParent = toRenderBlock(lastChild());
412
413     // If the new child is floating or positioned it can just go in that block.
414     if (newChild->isFloatingOrOutOfFlowPositioned()) {
415         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
416         return;
417     }
418
419     // See if the child can be placed in the box.
420     bool newChildHasColumnSpan = !newChild->isInline() && newChild->style()->columnSpan();
421     bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
422
423     if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
424         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
425         return;
426     }
427
428     if (!beforeChild) {
429         // Create a new block of the correct type.
430         RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
431         insertChildInternal(newBox, nullptr, NotifyChildren);
432         newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
433         return;
434     }
435
436     RenderObject* immediateChild = beforeChild;
437     bool isPreviousBlockViable = true;
438     while (immediateChild->parent() != this) {
439         if (isPreviousBlockViable)
440             isPreviousBlockViable = !immediateChild->previousSibling();
441         immediateChild = immediateChild->parent();
442     }
443     if (isPreviousBlockViable && immediateChild->previousSibling()) {
444         toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
445         return;
446     }
447         
448     // Split our anonymous blocks.
449     RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
450
451     
452     // Create a new anonymous box of the appropriate type.
453     RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
454     insertChildInternal(newBox, newBeforeChild, NotifyChildren);
455     newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
456     return;
457 }
458
459 RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
460 {
461     RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
462     for (RenderObject* curr = this; curr; curr = curr->parent()) {
463         if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
464             || curr->isInlineBlockOrInlineTable())
465             return 0;
466
467         // FIXME: Tables, RenderButtons, and RenderListItems all do special management
468         // of their children that breaks when the flow is split through them. Disabling
469         // multi-column for them to avoid this problem.
470         if (curr->isTable() || curr->isRenderButton() || curr->isListItem())
471             return 0;
472         
473         RenderBlock* currBlock = toRenderBlock(curr);
474         if (!currBlock->createsAnonymousWrapper())
475             firstChildIgnoringAnonymousWrappers = currBlock;
476
477         if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
478             return firstChildIgnoringAnonymousWrappers;
479             
480         if (currBlock->isAnonymousColumnSpanBlock())
481             return 0;
482     }
483     return 0;
484 }
485
486 RenderBlock* RenderBlock::clone() const
487 {
488     RenderBlock* cloneBlock;
489     if (isAnonymousBlock()) {
490         cloneBlock = createAnonymousBlock();
491         cloneBlock->setChildrenInline(childrenInline());
492     } else {
493         RenderObject* cloneRenderer = element()->createRenderer(renderArena(), *style());
494         cloneBlock = toRenderBlock(cloneRenderer);
495         cloneBlock->setStyle(style());
496
497         // This takes care of setting the right value of childrenInline in case
498         // generated content is added to cloneBlock and 'this' does not have
499         // generated content added yet.
500         cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->firstChild()->isInline() : childrenInline());
501     }
502     cloneBlock->setFlowThreadState(flowThreadState());
503     return cloneBlock;
504 }
505
506 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
507                               RenderBlock* middleBlock,
508                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
509 {
510     // Create a clone of this inline.
511     RenderBlock* cloneBlock = clone();
512     if (!isAnonymousBlock())
513         cloneBlock->setContinuation(oldCont);
514
515     if (!beforeChild && isAfterContent(lastChild()))
516         beforeChild = lastChild();
517
518     // If we are moving inline children from |this| to cloneBlock, then we need
519     // to clear our line box tree.
520     if (beforeChild && childrenInline())
521         deleteLineBoxTree();
522
523     // Now take all of the children from beforeChild to the end and remove
524     // them from |this| and place them in the clone.
525     moveChildrenTo(cloneBlock, beforeChild, 0, true);
526     
527     // Hook |clone| up as the continuation of the middle block.
528     if (!cloneBlock->isAnonymousBlock())
529         middleBlock->setContinuation(cloneBlock);
530
531     // We have been reparented and are now under the fromBlock.  We need
532     // to walk up our block parent chain until we hit the containing anonymous columns block.
533     // Once we hit the anonymous columns block we're done.
534     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
535     RenderBoxModelObject* currChild = this;
536     RenderObject* currChildNextSibling = currChild->nextSibling();
537
538     while (curr && curr != fromBlock) {
539         ASSERT_WITH_SECURITY_IMPLICATION(curr->isRenderBlock());
540         
541         RenderBlock* blockCurr = toRenderBlock(curr);
542         
543         // Create a new clone.
544         RenderBlock* cloneChild = cloneBlock;
545         cloneBlock = blockCurr->clone();
546
547         // Insert our child clone as the first child.
548         cloneBlock->addChildIgnoringContinuation(cloneChild, 0);
549
550         // Hook the clone up as a continuation of |curr|.  Note we do encounter
551         // anonymous blocks possibly as we walk up the block chain.  When we split an
552         // anonymous block, there's no need to do any continuation hookup, since we haven't
553         // actually split a real element.
554         if (!blockCurr->isAnonymousBlock()) {
555             oldCont = blockCurr->continuation();
556             blockCurr->setContinuation(cloneBlock);
557             cloneBlock->setContinuation(oldCont);
558         }
559
560         // Now we need to take all of the children starting from the first child
561         // *after* currChild and append them all to the clone.
562         blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);
563
564         // Keep walking up the chain.
565         currChild = curr;
566         currChildNextSibling = currChild->nextSibling();
567         curr = toRenderBoxModelObject(curr->parent());
568     }
569
570     // Now we are at the columns block level. We need to put the clone into the toBlock.
571     toBlock->insertChildInternal(cloneBlock, nullptr, NotifyChildren);
572
573     // Now take all the children after currChild and remove them from the fromBlock
574     // and put them in the toBlock.
575     fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true);
576 }
577
578 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
579                             RenderObject* newChild, RenderBoxModelObject* oldCont)
580 {
581     RenderBlock* pre = 0;
582     RenderBlock* block = containingColumnsBlock();
583     
584     // Delete our line boxes before we do the inline split into continuations.
585     block->deleteLineBoxTree();
586     
587     bool madeNewBeforeBlock = false;
588     if (block->isAnonymousColumnsBlock()) {
589         // We can reuse this block and make it the preBlock of the next continuation.
590         pre = block;
591         pre->removePositionedObjects(0);
592         // FIXME-BLOCKFLOW remove this when splitFlow is moved to RenderBlockFlow.
593         if (pre->isRenderBlockFlow())
594             toRenderBlockFlow(pre)->removeFloatingObjects();
595         block = toRenderBlock(block->parent());
596     } else {
597         // No anonymous block available for use.  Make one.
598         pre = block->createAnonymousColumnsBlock();
599         pre->setChildrenInline(false);
600         madeNewBeforeBlock = true;
601     }
602
603     RenderBlock* post = block->createAnonymousColumnsBlock();
604     post->setChildrenInline(false);
605
606     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
607     if (madeNewBeforeBlock)
608         block->insertChildInternal(pre, boxFirst, NotifyChildren);
609     block->insertChildInternal(newBlockBox, boxFirst, NotifyChildren);
610     block->insertChildInternal(post, boxFirst, NotifyChildren);
611     block->setChildrenInline(false);
612     
613     if (madeNewBeforeBlock)
614         block->moveChildrenTo(pre, boxFirst, 0, true);
615
616     splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
617
618     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
619     // time in makeChildrenNonInline by just setting this explicitly up front.
620     newBlockBox->setChildrenInline(false);
621
622     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
623     // connected, thus allowing newChild access to a renderArena should it need
624     // to wrap itself in additional boxes (e.g., table construction).
625     newBlockBox->addChild(newChild);
626
627     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
628     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
629     // make new line boxes instead of leaving the old line boxes around.
630     pre->setNeedsLayoutAndPrefWidthsRecalc();
631     block->setNeedsLayoutAndPrefWidthsRecalc();
632     post->setNeedsLayoutAndPrefWidthsRecalc();
633 }
634
635 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
636 {
637     RenderBlock* pre = 0;
638     RenderBlock* post = 0;
639     RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
640                                // so that we don't have to patch all of the rest of the code later on.
641     
642     // Delete the block's line boxes before we do the split.
643     block->deleteLineBoxTree();
644
645     if (beforeChild && beforeChild->parent() != this)
646         beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
647
648     if (beforeChild != firstChild()) {
649         pre = block->createAnonymousColumnsBlock();
650         pre->setChildrenInline(block->childrenInline());
651     }
652
653     if (beforeChild) {
654         post = block->createAnonymousColumnsBlock();
655         post->setChildrenInline(block->childrenInline());
656     }
657
658     RenderObject* boxFirst = block->firstChild();
659     if (pre)
660         block->insertChildInternal(pre, boxFirst, NotifyChildren);
661     block->insertChildInternal(newBlockBox, boxFirst, NotifyChildren);
662     if (post)
663         block->insertChildInternal(post, boxFirst, NotifyChildren);
664     block->setChildrenInline(false);
665     
666     // 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).
667     block->moveChildrenTo(pre, boxFirst, beforeChild, true);
668     block->moveChildrenTo(post, beforeChild, 0, true);
669
670     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
671     // time in makeChildrenNonInline by just setting this explicitly up front.
672     newBlockBox->setChildrenInline(false);
673
674     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
675     // connected, thus allowing newChild access to a renderArena should it need
676     // to wrap itself in additional boxes (e.g., table construction).
677     newBlockBox->addChild(newChild);
678
679     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
680     // get deleted properly.  Because objects moved from the pre block into the post block, we want to
681     // make new line boxes instead of leaving the old line boxes around.
682     if (pre)
683         pre->setNeedsLayoutAndPrefWidthsRecalc();
684     block->setNeedsLayoutAndPrefWidthsRecalc();
685     if (post)
686         post->setNeedsLayoutAndPrefWidthsRecalc();
687 }
688
689 RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
690 {
691     // FIXME: This function is the gateway for the addition of column-span support.  It will
692     // be added to in three stages:
693     // (1) Immediate children of a multi-column block can span.
694     // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
695     // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
696     // cross the streams and have to cope with both types of continuations mixed together).
697     // This function currently supports (1) and (2).
698     RenderBlock* columnsBlockAncestor = 0;
699     if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
700         && !newChild->isFloatingOrOutOfFlowPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
701         columnsBlockAncestor = containingColumnsBlock(false);
702         if (columnsBlockAncestor) {
703             // Make sure that none of the parent ancestors have a continuation.
704             // If yes, we do not want split the block into continuations.
705             RenderObject* curr = this;
706             while (curr && curr != columnsBlockAncestor) {
707                 if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
708                     columnsBlockAncestor = 0;
709                     break;
710                 }
711                 curr = curr->parent();
712             }
713         }
714     }
715     return columnsBlockAncestor;
716 }
717
718 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
719 {
720     if (beforeChild && beforeChild->parent() != this) {
721         RenderElement* beforeChildContainer = beforeChild->parent();
722         while (beforeChildContainer->parent() != this)
723             beforeChildContainer = beforeChildContainer->parent();
724         ASSERT(beforeChildContainer);
725
726         if (beforeChildContainer->isAnonymous()) {
727             // If the requested beforeChild is not one of our children, then this is because
728             // there is an anonymous container within this object that contains the beforeChild.
729             RenderElement* beforeChildAnonymousContainer = beforeChildContainer;
730             if (beforeChildAnonymousContainer->isAnonymousBlock()
731 #if ENABLE(FULLSCREEN_API)
732                 // Full screen renderers and full screen placeholders act as anonymous blocks, not tables:
733                 || beforeChildAnonymousContainer->isRenderFullScreen()
734                 || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
735 #endif
736                 ) {
737                 // Insert the child into the anonymous block box instead of here.
738                 if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
739                     beforeChild->parent()->addChild(newChild, beforeChild);
740                 else
741                     addChild(newChild, beforeChild->parent());
742                 return;
743             }
744
745             ASSERT(beforeChildAnonymousContainer->isTable());
746             if (newChild->isTablePart()) {
747                 // Insert into the anonymous table.
748                 beforeChildAnonymousContainer->addChild(newChild, beforeChild);
749                 return;
750             }
751
752             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
753
754             ASSERT(beforeChild->parent() == this);
755             if (beforeChild->parent() != this) {
756                 // We should never reach here. If we do, we need to use the
757                 // safe fallback to use the topmost beforeChild container.
758                 beforeChild = beforeChildContainer;
759             }
760         } else {
761             // We will reach here when beforeChild is a run-in element.
762             // If run-in element precedes a block-level element, it becomes the
763             // the first inline child of that block level element. The insertion
764             // point will be before that block-level element.
765             ASSERT(beforeChild->isRunIn());
766             beforeChild = beforeChildContainer;
767         }
768     }
769
770     // Nothing goes before the intruded run-in.
771     if (beforeChild && beforeChild->isRunIn() && runInIsPlacedIntoSiblingBlock(beforeChild))
772         beforeChild = beforeChild->nextSibling();
773
774     // Check for a spanning element in columns.
775     if (gColumnFlowSplitEnabled) {
776         RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
777         if (columnsBlockAncestor) {
778             TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
779             // We are placing a column-span element inside a block.
780             RenderBlock* newBox = createAnonymousColumnSpanBlock();
781         
782             if (columnsBlockAncestor != this && !isRenderFlowThread()) {
783                 // We are nested inside a multi-column element and are being split by the span. We have to break up
784                 // our block into continuations.
785                 RenderBoxModelObject* oldContinuation = continuation();
786
787                 // When we split an anonymous block, there's no need to do any continuation hookup,
788                 // since we haven't actually split a real element.
789                 if (!isAnonymousBlock())
790                     setContinuation(newBox);
791
792                 splitFlow(beforeChild, newBox, newChild, oldContinuation);
793                 return;
794             }
795
796             // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
797             // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
798             // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
799             makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
800             return;
801         }
802     }
803
804     bool madeBoxesNonInline = false;
805
806     // A block has to either have all of its children inline, or all of its children as blocks.
807     // So, if our children are currently inline and a block child has to be inserted, we move all our
808     // inline children into anonymous block boxes.
809     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned()) {
810         // This is a block with inline content. Wrap the inline content in anonymous blocks.
811         makeChildrenNonInline(beforeChild);
812         madeBoxesNonInline = true;
813
814         if (beforeChild && beforeChild->parent() != this) {
815             beforeChild = beforeChild->parent();
816             ASSERT(beforeChild->isAnonymousBlock());
817             ASSERT(beforeChild->parent() == this);
818         }
819     } else if (!childrenInline() && (newChild->isFloatingOrOutOfFlowPositioned() || newChild->isInline())) {
820         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
821         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
822         // a new one is created and inserted into our list of children in the appropriate position.
823         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
824
825         if (afterChild && afterChild->isAnonymousBlock()) {
826             toRenderBlock(afterChild)->addChild(newChild);
827             return;
828         }
829
830         if (newChild->isInline()) {
831             // No suitable existing anonymous box - create a new one.
832             RenderBlock* newBox = createAnonymousBlock();
833             RenderBox::addChild(newBox, beforeChild);
834             newBox->addChild(newChild);
835             return;
836         }
837     }
838
839     RenderBox::addChild(newChild, beforeChild);
840  
841     // Handle placement of run-ins.
842     placeRunInIfNeeded(newChild);
843
844     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
845         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
846     // this object may be dead here
847 }
848
849 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
850 {
851     if (continuation() && !isAnonymousBlock())
852         addChildToContinuation(newChild, beforeChild);
853     else
854         addChildIgnoringContinuation(newChild, beforeChild);
855 }
856
857 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
858 {
859     if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
860         addChildToAnonymousColumnBlocks(newChild, beforeChild);
861     else
862         addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
863 }
864
865 static void getInlineRun(RenderObject* start, RenderObject* boundary,
866                          RenderObject*& inlineRunStart,
867                          RenderObject*& inlineRunEnd)
868 {
869     // Beginning at |start| we find the largest contiguous run of inlines that
870     // we can.  We denote the run with start and end points, |inlineRunStart|
871     // and |inlineRunEnd|.  Note that these two values may be the same if
872     // we encounter only one inline.
873     //
874     // We skip any non-inlines we encounter as long as we haven't found any
875     // inlines yet.
876     //
877     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
878     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
879     // a non-inline.
880     
881     // Start by skipping as many non-inlines as we can.
882     RenderObject * curr = start;
883     bool sawInline;
884     do {
885         while (curr && !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()))
886             curr = curr->nextSibling();
887         
888         inlineRunStart = inlineRunEnd = curr;
889         
890         if (!curr)
891             return; // No more inline children to be found.
892         
893         sawInline = curr->isInline();
894         
895         curr = curr->nextSibling();
896         while (curr && (curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()) && (curr != boundary)) {
897             inlineRunEnd = curr;
898             if (curr->isInline())
899                 sawInline = true;
900             curr = curr->nextSibling();
901         }
902     } while (!sawInline);
903 }
904
905 void RenderBlock::deleteLineBoxTree()
906 {
907     m_lineBoxes.deleteLineBoxTree(renderArena());
908
909     if (AXObjectCache* cache = document().existingAXObjectCache())
910         cache->recomputeIsIgnored(this);
911 }
912
913 RootInlineBox* RenderBlock::createRootInlineBox()
914 {
915     return new (renderArena()) RootInlineBox(*this);
916 }
917
918 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
919 {
920     RootInlineBox* rootBox = createRootInlineBox();
921     m_lineBoxes.appendLineBox(rootBox);
922
923     if (UNLIKELY(AXObjectCache::accessibilityEnabled()) && m_lineBoxes.firstLineBox() == rootBox) {
924         if (AXObjectCache* cache = document().existingAXObjectCache())
925             cache->recomputeIsIgnored(this);
926     }
927
928     return rootBox;
929 }
930
931 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
932 {    
933     // makeChildrenNonInline takes a block whose children are *all* inline and it
934     // makes sure that inline children are coalesced under anonymous
935     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
936     // the new block child that is causing us to have to wrap all the inlines.  This
937     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
938     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
939     // splitting them.
940     ASSERT(isInlineBlockOrInlineTable() || !isInline());
941     ASSERT(!insertionPoint || insertionPoint->parent() == this);
942
943     setChildrenInline(false);
944
945     RenderObject *child = firstChild();
946     if (!child)
947         return;
948
949     deleteLineBoxTree();
950
951     // Since we are going to have block children, we have to move
952     // back the run-in to its original place.
953     if (child->isRunIn()) {
954         moveRunInToOriginalPosition(child);
955         child = firstChild();
956     }
957
958     while (child) {
959         RenderObject *inlineRunStart, *inlineRunEnd;
960         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
961
962         if (!inlineRunStart)
963             break;
964
965         child = inlineRunEnd->nextSibling();
966
967         RenderBlock* block = createAnonymousBlock();
968         insertChildInternal(block, inlineRunStart, NotifyChildren);
969         moveChildrenTo(block, inlineRunStart, child);
970     }
971
972 #ifndef NDEBUG
973     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
974         ASSERT(!c->isInline());
975 #endif
976
977     repaint();
978 }
979
980 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
981 {
982     ASSERT(child->isAnonymousBlock());
983     ASSERT(!child->childrenInline());
984     
985     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
986         return;
987     
988     RenderObject* firstAnChild = child->firstChild();
989     RenderObject* lastAnChild = child->lastChild();
990     if (firstAnChild) {
991         RenderObject* o = firstAnChild;
992         while (o) {
993             o->setParent(this);
994             o = o->nextSibling();
995         }
996         firstAnChild->setPreviousSibling(child->previousSibling());
997         lastAnChild->setNextSibling(child->nextSibling());
998         if (child->previousSibling())
999             child->previousSibling()->setNextSibling(firstAnChild);
1000         if (child->nextSibling())
1001             child->nextSibling()->setPreviousSibling(lastAnChild);
1002             
1003         if (child == firstChild())
1004             setFirstChild(firstAnChild);
1005         if (child == lastChild())
1006             setLastChild(lastAnChild);
1007     } else {
1008         if (child == firstChild())
1009             setFirstChild(child->nextSibling());
1010         if (child == lastChild())
1011             setLastChild(child->previousSibling());
1012
1013         if (child->previousSibling())
1014             child->previousSibling()->setNextSibling(child->nextSibling());
1015         if (child->nextSibling())
1016             child->nextSibling()->setPreviousSibling(child->previousSibling());
1017     }
1018
1019     child->setFirstChild(0);
1020     child->m_next = 0;
1021
1022     // Remove all the information in the flow thread associated with the leftover anonymous block.
1023     child->removeFromRenderFlowThread();
1024
1025     child->setParent(0);
1026     child->setPreviousSibling(0);
1027     child->setNextSibling(0);
1028
1029     child->destroy();
1030 }
1031
1032 static bool canMergeAnonymousBlock(RenderBlock* anonymousBlock)
1033 {
1034     if (anonymousBlock->beingDestroyed() || anonymousBlock->continuation())
1035         return false;
1036     if (anonymousBlock->isRubyRun() || anonymousBlock->isRubyBase())
1037         return false;
1038     return true;
1039 }
1040
1041 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* previous, RenderObject* next)
1042 {
1043     if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
1044         return false;
1045
1046     if (previous) {
1047         if (!previous->isAnonymousBlock())
1048             return false;
1049         RenderBlock* previousAnonymousBlock = toRenderBlock(previous);
1050         if (!canMergeAnonymousBlock(previousAnonymousBlock))
1051             return false;
1052         // FIXME: This check isn't required when inline run-ins can't be split into continuations.
1053         RenderObject* child = previousAnonymousBlock->firstChild();
1054         if (child && child->isInline() && child->isRunIn())
1055             return false;
1056     }
1057     if (next) {
1058         if (!next->isAnonymousBlock())
1059             return false;
1060         RenderBlock* nextAnonymousBlock = toRenderBlock(next);
1061         if (!canMergeAnonymousBlock(nextAnonymousBlock))
1062             return false;
1063     }
1064     if (!previous || !next)
1065         return true;
1066
1067     // Make sure the types of the anonymous blocks match up.
1068     return previous->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
1069         && previous->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
1070 }
1071
1072 void RenderBlock::collapseAnonymousBoxChild(RenderBlock* parent, RenderBlock* child)
1073 {
1074     parent->setNeedsLayoutAndPrefWidthsRecalc();
1075     parent->setChildrenInline(child->childrenInline());
1076     RenderObject* nextSibling = child->nextSibling();
1077
1078     RenderFlowThread* childFlowThread = child->flowThreadContainingBlock();
1079     CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);
1080
1081     parent->removeChildInternal(child, child->hasLayer() ? NotifyChildren : DontNotifyChildren);
1082     child->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
1083     // Delete the now-empty block's lines and nuke it.
1084     child->deleteLineBoxTree();
1085     if (childFlowThread && childFlowThread->isRenderNamedFlowThread())
1086         toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(child);
1087     child->destroy();
1088 }
1089
1090 void RenderBlock::removeChild(RenderObject* oldChild)
1091 {
1092     // No need to waste time in merging or removing empty anonymous blocks.
1093     // We can just bail out if our document is getting destroyed.
1094     if (documentBeingDestroyed()) {
1095         RenderBox::removeChild(oldChild);
1096         return;
1097     }
1098
1099     // This protects against column split flows when anonymous blocks are getting merged.
1100     TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
1101
1102     // If this child is a block, and if our previous and next siblings are
1103     // both anonymous blocks with inline content, then we can go ahead and
1104     // fold the inline content back together.
1105     RenderObject* prev = oldChild->previousSibling();
1106     RenderObject* next = oldChild->nextSibling();
1107     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
1108     if (canMergeAnonymousBlocks && prev && next) {
1109         prev->setNeedsLayoutAndPrefWidthsRecalc();
1110         RenderBlock* nextBlock = toRenderBlock(next);
1111         RenderBlock* prevBlock = toRenderBlock(prev);
1112        
1113         if (prev->childrenInline() != next->childrenInline()) {
1114             RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
1115             RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
1116             
1117             // Place the inline children block inside of the block children block instead of deleting it.
1118             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
1119             // to clear out inherited column properties by just making a new style, and to also clear the
1120             // column span flag if it is set.
1121             ASSERT(!inlineChildrenBlock->continuation());
1122             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
1123             // Cache this value as it might get changed in setStyle() call.
1124             bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer();
1125             inlineChildrenBlock->setStyle(newStyle);
1126             removeChildInternal(inlineChildrenBlock, inlineChildrenBlockHasLayer ? NotifyChildren : DontNotifyChildren);
1127             
1128             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
1129             RenderObject* beforeChild = prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : nullptr;
1130             blockChildrenBlock->insertChildInternal(inlineChildrenBlock, beforeChild,
1131                 (inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer()) ? NotifyChildren : DontNotifyChildren);
1132             next->setNeedsLayoutAndPrefWidthsRecalc();
1133             
1134             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
1135             // of "this". we null out prev or next so that is not used later in the function.
1136             if (inlineChildrenBlock == prevBlock)
1137                 prev = 0;
1138             else
1139                 next = 0;
1140         } else {
1141             // Take all the children out of the |next| block and put them in
1142             // the |prev| block.
1143             nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
1144             
1145             // Delete the now-empty block's lines and nuke it.
1146             nextBlock->deleteLineBoxTree();
1147             nextBlock->destroy();
1148             next = 0;
1149         }
1150     }
1151
1152     RenderBox::removeChild(oldChild);
1153
1154     RenderObject* child = prev ? prev : next;
1155     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canCollapseAnonymousBlockChild()) {
1156         // The removal has knocked us down to containing only a single anonymous
1157         // box.  We can go ahead and pull the content right back up into our
1158         // box.
1159         collapseAnonymousBoxChild(this, toRenderBlock(child));
1160     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canCollapseAnonymousBlockChild()) {
1161         // It's possible that the removal has knocked us down to a single anonymous
1162         // block with pseudo-style element siblings (e.g. first-letter). If these
1163         // are floating, then we need to pull the content up also.
1164         RenderBlock* anonBlock = toRenderBlock((prev && prev->isAnonymousBlock()) ? prev : next);
1165         if ((anonBlock->previousSibling() || anonBlock->nextSibling())
1166             && (!anonBlock->previousSibling() || (anonBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonBlock->previousSibling()->isFloating() && !anonBlock->previousSibling()->previousSibling()))
1167             && (!anonBlock->nextSibling() || (anonBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonBlock->nextSibling()->isFloating() && !anonBlock->nextSibling()->nextSibling()))) {
1168             collapseAnonymousBoxChild(this, anonBlock);
1169         }
1170     }
1171
1172     if (!firstChild()) {
1173         // If this was our last child be sure to clear out our line boxes.
1174         if (childrenInline())
1175             deleteLineBoxTree();
1176
1177         // If we are an empty anonymous block in the continuation chain,
1178         // we need to remove ourself and fix the continuation chain.
1179         if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->isListMarker()) {
1180             RenderObject* containingBlockIgnoringAnonymous = containingBlock();
1181             while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
1182                 containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
1183             for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
1184                 if (curr->virtualContinuation() != this)
1185                     continue;
1186
1187                 // Found our previous continuation. We just need to point it to
1188                 // |this|'s next continuation.
1189                 RenderBoxModelObject* nextContinuation = continuation();
1190                 if (curr->isRenderInline())
1191                     toRenderInline(curr)->setContinuation(nextContinuation);
1192                 else if (curr->isRenderBlock())
1193                     toRenderBlock(curr)->setContinuation(nextContinuation);
1194                 else
1195                     ASSERT_NOT_REACHED();
1196
1197                 break;
1198             }
1199             setContinuation(0);
1200             destroy();
1201         }
1202     }
1203 }
1204
1205 bool RenderBlock::isSelfCollapsingBlock() const
1206 {
1207     // We are not self-collapsing if we
1208     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
1209     // (b) are a table,
1210     // (c) have border/padding,
1211     // (d) have a min-height
1212     // (e) have specified that one of our margins can't collapse using a CSS extension
1213     if (logicalHeight() > 0
1214         || isTable() || borderAndPaddingLogicalHeight()
1215         || style()->logicalMinHeight().isPositive()
1216         || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
1217         return false;
1218
1219     Length logicalHeightLength = style()->logicalHeight();
1220     bool hasAutoHeight = logicalHeightLength.isAuto();
1221     if (logicalHeightLength.isPercent() && !document().inQuirksMode()) {
1222         hasAutoHeight = true;
1223         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
1224             if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
1225                 hasAutoHeight = false;
1226         }
1227     }
1228
1229     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
1230     // on whether we have content that is all self-collapsing or not.
1231     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
1232         // If the block has inline children, see if we generated any line boxes.  If we have any
1233         // line boxes, then we can't be self-collapsing, since we have content.
1234         if (childrenInline())
1235             return !firstLineBox();
1236         
1237         // Whether or not we collapse is dependent on whether all our normal flow children
1238         // are also self-collapsing.
1239         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1240             if (child->isFloatingOrOutOfFlowPositioned())
1241                 continue;
1242             if (!child->isSelfCollapsingBlock())
1243                 return false;
1244         }
1245         return true;
1246     }
1247     return false;
1248 }
1249
1250 void RenderBlock::startDelayUpdateScrollInfo()
1251 {
1252     if (gDelayUpdateScrollInfo == 0) {
1253         ASSERT(!gDelayedUpdateScrollInfoSet);
1254         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
1255     }
1256     ASSERT(gDelayedUpdateScrollInfoSet);
1257     ++gDelayUpdateScrollInfo;
1258 }
1259
1260 void RenderBlock::finishDelayUpdateScrollInfo()
1261 {
1262     --gDelayUpdateScrollInfo;
1263     ASSERT(gDelayUpdateScrollInfo >= 0);
1264     if (gDelayUpdateScrollInfo == 0) {
1265         ASSERT(gDelayedUpdateScrollInfoSet);
1266
1267         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet));
1268         gDelayedUpdateScrollInfoSet = 0;
1269
1270         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
1271             RenderBlock* block = *it;
1272             if (block->hasOverflowClip()) {
1273                 block->layer()->updateScrollInfoAfterLayout();
1274                 block->clearLayoutOverflow();
1275             }
1276         }
1277     }
1278 }
1279
1280 void RenderBlock::updateScrollInfoAfterLayout()
1281 {
1282     if (hasOverflowClip()) {
1283         if (style()->isFlippedBlocksWritingMode()) {
1284             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=97937
1285             // Workaround for now. We cannot delay the scroll info for overflow
1286             // for items with opposite writing directions, as the contents needs
1287             // to overflow in that direction
1288             layer()->updateScrollInfoAfterLayout();
1289             return;
1290         }
1291
1292         if (gDelayUpdateScrollInfo)
1293             gDelayedUpdateScrollInfoSet->add(this);
1294         else
1295             layer()->updateScrollInfoAfterLayout();
1296     }
1297 }
1298
1299 void RenderBlock::layout()
1300 {
1301     StackStats::LayoutCheckPoint layoutCheckPoint;
1302     OverflowEventDispatcher dispatcher(this);
1303
1304     // Update our first letter info now.
1305     updateFirstLetter();
1306
1307     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
1308     // layoutBlock().
1309     layoutBlock(false);
1310     
1311     // It's safe to check for control clip here, since controls can never be table cells.
1312     // If we have a lightweight clip, there can never be any overflow from children.
1313     if (hasControlClip() && m_overflow && !gDelayUpdateScrollInfo)
1314         clearLayoutOverflow();
1315
1316     invalidateBackgroundObscurationStatus();
1317 }
1318
1319 #if ENABLE(CSS_SHAPES)
1320 void RenderBlock::relayoutShapeDescendantIfMoved(RenderBlock* child, LayoutSize offset)
1321 {
1322     LayoutUnit left = isHorizontalWritingMode() ? offset.width() : offset.height();
1323     if (!left || !child || child->shapeInsideInfo() || !layoutShapeInsideInfo())
1324         return;
1325     // Propagate layout markers only up to the child, as we are still in the middle
1326     // of a layout pass
1327     child->setNormalChildNeedsLayoutBit(true);
1328     child->markShapeInsideDescendantsForLayout();
1329     child->layoutIfNeeded();
1330 }
1331
1332 LayoutSize RenderBlock::logicalOffsetFromShapeAncestorContainer(const RenderBlock* container) const
1333 {
1334     const RenderBlock* currentBlock = this;
1335     LayoutRect blockRect(currentBlock->borderBoxRect());
1336     while (currentBlock && !currentBlock->isRenderFlowThread() && currentBlock != container) {
1337         RenderBlock* containerBlock = currentBlock->containingBlock();
1338         ASSERT(containerBlock);
1339         if (!containerBlock)
1340             return LayoutSize();
1341
1342         if (containerBlock->style()->writingMode() != currentBlock->style()->writingMode()) {
1343             // We have to put the block rect in container coordinates
1344             // and we have to take into account both the container and current block flipping modes
1345             // Bug 118073: Flipping inline and block directions at the same time will not work,
1346             // as one of the flipped dimensions will not yet have been set to its final size
1347             if (containerBlock->style()->isFlippedBlocksWritingMode()) {
1348                 if (containerBlock->isHorizontalWritingMode())
1349                     blockRect.setY(currentBlock->height() - blockRect.maxY());
1350                 else
1351                     blockRect.setX(currentBlock->width() - blockRect.maxX());
1352             }
1353             currentBlock->flipForWritingMode(blockRect);
1354         }
1355
1356         blockRect.moveBy(currentBlock->location());
1357         currentBlock = containerBlock;
1358     }
1359
1360     LayoutSize result = isHorizontalWritingMode() ? LayoutSize(blockRect.x(), blockRect.y()) : LayoutSize(blockRect.y(), blockRect.x());
1361     return result;
1362 }
1363
1364 void RenderBlock::imageChanged(WrappedImagePtr image, const IntRect*)
1365 {
1366     RenderBox::imageChanged(image);
1367
1368     if (!parent())
1369         return;
1370
1371     ShapeValue* shapeValue = style()->shapeInside();
1372     if (shapeValue && shapeValue->image() && shapeValue->image()->data() == image) {
1373         ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
1374         shapeInsideInfo->dirtyShapeSize();
1375         markShapeInsideDescendantsForLayout();
1376     }
1377 }
1378
1379 void RenderBlock::updateShapeInsideInfoAfterStyleChange(const ShapeValue* shapeInside, const ShapeValue* oldShapeInside)
1380 {
1381     // FIXME: A future optimization would do a deep comparison for equality.
1382     if (shapeInside == oldShapeInside)
1383         return;
1384
1385     if (shapeInside) {
1386         ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
1387         shapeInsideInfo->dirtyShapeSize();
1388     } else {
1389         setShapeInsideInfo(nullptr);
1390         markShapeInsideDescendantsForLayout();
1391     }
1392 }
1393
1394 void RenderBlock::markShapeInsideDescendantsForLayout()
1395 {
1396     if (!everHadLayout())
1397         return;
1398     if (childrenInline()) {
1399         setNeedsLayout();
1400         return;
1401     }
1402     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
1403         if (!child->isRenderBlock())
1404             continue;
1405         RenderBlock* childBlock = toRenderBlock(child);
1406         childBlock->markShapeInsideDescendantsForLayout();
1407     }
1408 }
1409 #endif
1410
1411 #if ENABLE(CSS_SHAPES)
1412 static inline bool shapeInfoRequiresRelayout(const RenderBlock* block)
1413 {
1414     ShapeInsideInfo* info = block->shapeInsideInfo();
1415     if (info)
1416         info->setNeedsLayout(info->shapeSizeDirty());
1417     else
1418         info = block->layoutShapeInsideInfo();
1419     return info && info->needsLayout();
1420 }
1421 #endif
1422
1423 bool RenderBlock::updateShapesBeforeBlockLayout()
1424 {
1425 #if ENABLE(CSS_SHAPES)
1426     if (!flowThreadContainingBlock() && !shapeInsideInfo())
1427         return shapeInfoRequiresRelayout(this);
1428
1429     LayoutUnit oldHeight = logicalHeight();
1430     LayoutUnit oldTop = logicalTop();
1431
1432     // Compute the maximum logical height content may cause this block to expand to
1433     // FIXME: These should eventually use the const computeLogicalHeight rather than updateLogicalHeight
1434     setLogicalHeight(RenderFlowThread::maxLogicalHeight());
1435     updateLogicalHeight();
1436
1437     computeShapeSize();
1438
1439     setLogicalHeight(oldHeight);
1440     setLogicalTop(oldTop);
1441
1442     return shapeInfoRequiresRelayout(this);
1443 #else
1444     return false;
1445 #endif
1446 }
1447
1448 #if ENABLE(CSS_SHAPES)
1449 void RenderBlock::computeShapeSize()
1450 {
1451     ShapeInsideInfo* shapeInsideInfo = this->shapeInsideInfo();
1452     if (shapeInsideInfo) {
1453         bool percentageLogicalHeightResolvable = percentageLogicalHeightIsResolvableFromBlock(this, false);
1454         shapeInsideInfo->setShapeSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : LayoutUnit());
1455     }
1456 }
1457 #endif
1458
1459 void RenderBlock::updateShapesAfterBlockLayout(bool heightChanged)
1460 {
1461 #if ENABLE(CSS_SHAPES)
1462     // A previous sibling has changed dimension, so we need to relayout the shape with the content
1463     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
1464     if (heightChanged && shapeInsideInfo)
1465         shapeInsideInfo->dirtyShapeSize();
1466 #else
1467     UNUSED_PARAM(heightChanged);
1468 #endif
1469 }
1470
1471 bool RenderBlock::updateLogicalWidthAndColumnWidth()
1472 {
1473     LayoutUnit oldWidth = logicalWidth();
1474     LayoutUnit oldColumnWidth = desiredColumnWidth();
1475
1476     updateLogicalWidth();
1477     calcColumnWidth();
1478
1479     bool hasBorderOrPaddingLogicalWidthChanged = m_hasBorderOrPaddingLogicalWidthChanged;
1480     m_hasBorderOrPaddingLogicalWidthChanged = false;
1481
1482     return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth() || hasBorderOrPaddingLogicalWidthChanged;
1483 }
1484
1485 void RenderBlock::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight)
1486 {
1487     ColumnInfo* colInfo = columnInfo();
1488     if (hasColumns()) {
1489         if (!pageLogicalHeight) {
1490             // We need to go ahead and set our explicit page height if one exists, so that we can
1491             // avoid doing two layout passes.
1492             updateLogicalHeight();
1493             LayoutUnit columnHeight = isRenderView() ? view().pageOrViewLogicalHeight() : contentLogicalHeight();
1494             if (columnHeight > 0) {
1495                 pageLogicalHeight = columnHeight;
1496                 hasSpecifiedPageLogicalHeight = true;
1497             }
1498             setLogicalHeight(0);
1499         }
1500
1501         if (colInfo->columnHeight() != pageLogicalHeight && everHadLayout())
1502             pageLogicalHeightChanged = true;
1503
1504         colInfo->setColumnHeight(pageLogicalHeight);
1505         
1506         if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
1507             colInfo->clearForcedBreaks();
1508
1509         colInfo->setPaginationUnit(paginationUnit());
1510     } else if (isRenderFlowThread()) {
1511         pageLogicalHeight = 1; // This is just a hack to always make sure we have a page logical height.
1512         pageLogicalHeightChanged = toRenderFlowThread(this)->pageLogicalSizeChanged();
1513     }
1514 }
1515
1516 void RenderBlock::layoutBlock(bool, LayoutUnit)
1517 {
1518     ASSERT_NOT_REACHED();
1519     clearNeedsLayout();
1520 }
1521
1522 void RenderBlock::addOverflowFromChildren()
1523 {
1524     if (!hasColumns()) {
1525         if (childrenInline())
1526             addOverflowFromInlineChildren();
1527         else
1528             addOverflowFromBlockChildren();
1529     } else {
1530         ColumnInfo* colInfo = columnInfo();
1531         if (columnCount(colInfo)) {
1532             LayoutRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
1533             addLayoutOverflow(lastRect);
1534             if (!hasOverflowClip())
1535                 addVisualOverflow(lastRect);
1536         }
1537     }
1538 }
1539
1540 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
1541 {
1542     clearOverflow();
1543
1544     // Add overflow from children.
1545     addOverflowFromChildren();
1546
1547     // Add in the overflow from positioned objects.
1548     addOverflowFromPositionedObjects();
1549
1550     if (hasOverflowClip()) {
1551         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1552         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1553         // be considered reachable.
1554         LayoutRect clientRect(clientBoxRect());
1555         LayoutRect rectToApply;
1556         if (isHorizontalWritingMode())
1557             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), 1, max<LayoutUnit>(0, oldClientAfterEdge - clientRect.y()));
1558         else
1559             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), max<LayoutUnit>(0, oldClientAfterEdge - clientRect.x()), 1);
1560         addLayoutOverflow(rectToApply);
1561         if (hasRenderOverflow())
1562             m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
1563     }
1564         
1565     // Add visual overflow from box-shadow and border-image-outset.
1566     addVisualEffectOverflow();
1567
1568     // Add visual overflow from theme.
1569     addVisualOverflowFromTheme();
1570
1571     if (isRenderNamedFlowThread())
1572         toRenderNamedFlowThread(this)->computeOversetStateForRegions(oldClientAfterEdge);
1573 }
1574
1575 void RenderBlock::clearLayoutOverflow()
1576 {
1577     if (!m_overflow)
1578         return;
1579     
1580     if (visualOverflowRect() == borderBoxRect()) {
1581         // FIXME: Implement complete solution for regions overflow.
1582         clearOverflow();
1583         return;
1584     }
1585     
1586     m_overflow->setLayoutOverflow(borderBoxRect());
1587 }
1588
1589 void RenderBlock::addOverflowFromBlockChildren()
1590 {
1591     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1592         if (!child->isFloatingOrOutOfFlowPositioned())
1593             addOverflowFromChild(child);
1594     }
1595 }
1596
1597 void RenderBlock::addOverflowFromPositionedObjects()
1598 {
1599     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1600     if (!positionedDescendants)
1601         return;
1602
1603     RenderBox* positionedObject;
1604     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
1605     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
1606         positionedObject = *it;
1607         
1608         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1609         if (positionedObject->style()->position() != FixedPosition) {
1610             LayoutUnit x = positionedObject->x();
1611             if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1612                 x -= verticalScrollbarWidth();
1613             addOverflowFromChild(positionedObject, LayoutSize(x, positionedObject->y()));
1614         }
1615     }
1616 }
1617
1618 void RenderBlock::addVisualOverflowFromTheme()
1619 {
1620     if (!style()->hasAppearance())
1621         return;
1622
1623     IntRect inflatedRect = pixelSnappedBorderBoxRect();
1624     theme()->adjustRepaintRect(this, inflatedRect);
1625     addVisualOverflow(inflatedRect);
1626
1627     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
1628         flowThread->addRegionsVisualOverflowFromTheme(this);
1629 }
1630
1631 bool RenderBlock::expandsToEncloseOverhangingFloats() const
1632 {
1633     return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBoxIncludingDeprecated())
1634            || hasColumns() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isRoot();
1635 }
1636
1637 static void destroyRunIn(RenderBoxModelObject* runIn)
1638 {
1639     ASSERT(runIn->isRunIn());
1640     ASSERT(!runIn->firstChild());
1641
1642     // Delete our line box tree. This is needed as our children got moved
1643     // and our line box tree is no longer valid.
1644     if (runIn->isRenderBlock())
1645         toRenderBlock(runIn)->deleteLineBoxTree();
1646     else if (runIn->isRenderInline())
1647         toRenderInline(runIn)->deleteLineBoxTree();
1648     else
1649         ASSERT_NOT_REACHED();
1650
1651     runIn->destroy();
1652 }
1653
1654 void RenderBlock::placeRunInIfNeeded(RenderObject* newChild)
1655 {
1656     if (newChild->isRunIn())
1657         moveRunInUnderSiblingBlockIfNeeded(newChild);
1658     else if (RenderObject* prevSibling = newChild->previousSibling()) {
1659         if (prevSibling->isRunIn())
1660             moveRunInUnderSiblingBlockIfNeeded(prevSibling);
1661     }
1662 }
1663
1664 RenderBoxModelObject* RenderBlock::createReplacementRunIn(RenderBoxModelObject* runIn)
1665 {
1666     ASSERT(runIn->isRunIn());
1667     ASSERT(runIn->element());
1668
1669     RenderBoxModelObject* newRunIn = 0;
1670     if (!runIn->isRenderBlockFlow())
1671         newRunIn = new (renderArena()) RenderBlockFlow(runIn->element());
1672     else
1673         newRunIn = new (renderArena()) RenderInline(runIn->element());
1674
1675     runIn->element()->setRenderer(newRunIn);
1676     newRunIn->setStyle(runIn->style());
1677
1678     runIn->moveAllChildrenTo(newRunIn, true);
1679
1680     return newRunIn;
1681 }
1682
1683 void RenderBlock::moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn)
1684 {
1685     ASSERT(runIn->isRunIn());
1686
1687     // See if we have inline children. If the children aren't inline,
1688     // then just treat the run-in as a normal block.
1689     if (!runIn->childrenInline())
1690         return;
1691
1692     // FIXME: We don't handle non-block elements with run-in for now.
1693     if (!runIn->isRenderBlockFlow())
1694         return;
1695
1696     // FIXME: We don't support run-ins with or as part of a continuation
1697     // as it makes the back-and-forth placing complex.
1698     if (runIn->isElementContinuation() || runIn->virtualContinuation())
1699         return;
1700
1701     // Check if this node is allowed to run-in. E.g. <select> expects its renderer to
1702     // be a RenderListBox or RenderMenuList, and hence cannot be a RenderInline run-in.
1703     if (!runIn->canBeReplacedWithInlineRunIn())
1704         return;
1705
1706     RenderObject* curr = runIn->nextSibling();
1707     if (!curr || !curr->isRenderBlock() || !curr->childrenInline())
1708         return;
1709
1710     RenderBlock& nextSiblingBlock = toRenderBlock(*curr);
1711     if (nextSiblingBlock.beingDestroyed())
1712         return;
1713
1714     // Per CSS3, "A run-in cannot run in to a block that already starts with a
1715     // run-in or that itself is a run-in".
1716     if (nextSiblingBlock.isRunIn() || (nextSiblingBlock.firstChild() && nextSiblingBlock.firstChild()->isRunIn()))
1717         return;
1718
1719     if (nextSiblingBlock.isAnonymous() || nextSiblingBlock.isFloatingOrOutOfFlowPositioned())
1720         return;
1721
1722     RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn);
1723     RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn);
1724     destroyRunIn(oldRunIn);
1725
1726     // Now insert the new child under |curr| block. Use addChild instead of insertChildNode
1727     // since it handles correct placement of the children, especially where we cannot insert
1728     // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
1729     nextSiblingBlock.addChild(newRunIn, nextSiblingBlock.firstChild());
1730
1731     // Make sure that |this| get a layout since its run-in child moved.
1732     nextSiblingBlock.setNeedsLayoutAndPrefWidthsRecalc();
1733 }
1734
1735 bool RenderBlock::runInIsPlacedIntoSiblingBlock(RenderObject* runIn)
1736 {
1737     ASSERT(runIn->isRunIn());
1738
1739     // If we don't have a parent, we can't be moved into our sibling block.
1740     if (!parent())
1741         return false;
1742
1743     // An intruded run-in needs to be an inline.
1744     if (!runIn->isRenderInline())
1745         return false;
1746
1747     return true;
1748 }
1749
1750 void RenderBlock::moveRunInToOriginalPosition(RenderObject* runIn)
1751 {
1752     ASSERT(runIn->isRunIn());
1753
1754     if (!runInIsPlacedIntoSiblingBlock(runIn))
1755         return;
1756
1757     // FIXME: Run-in that are now placed in sibling block can break up into continuation
1758     // chains when new children are added to it. We cannot easily send them back to their
1759     // original place since that requires writing integration logic with RenderInline::addChild
1760     // and all other places that might cause continuations to be created (without blowing away
1761     // |this|). Disabling this feature for now to prevent crashes.
1762     if (runIn->isElementContinuation() || runIn->virtualContinuation())
1763         return;
1764
1765     RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn);
1766     RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn);
1767     destroyRunIn(oldRunIn);
1768
1769     // Add the run-in block as our previous sibling.
1770     parent()->addChild(newRunIn, this);
1771
1772     // Make sure that the parent holding the new run-in gets layout.
1773     parent()->setNeedsLayoutAndPrefWidthsRecalc();
1774 }
1775
1776 LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart, RenderRegion* region)
1777 {
1778     LayoutUnit startPosition = startOffsetForContent(region);
1779
1780     // Add in our start margin.
1781     LayoutUnit oldPosition = startPosition + childMarginStart;
1782     LayoutUnit newPosition = oldPosition;
1783
1784     LayoutUnit blockOffset = logicalTopForChild(child);
1785     if (region)
1786         blockOffset = max(blockOffset, blockOffset + (region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage()));
1787
1788     LayoutUnit startOff = startOffsetForLine(blockOffset, false, region, logicalHeightForChild(child));
1789
1790     if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
1791         if (childMarginStart < 0)
1792             startOff += childMarginStart;
1793         newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
1794     } else if (startOff != startPosition)
1795         newPosition = startOff + childMarginStart;
1796
1797     return newPosition - oldPosition;
1798 }
1799
1800 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode applyDelta)
1801 {
1802     LayoutUnit startPosition = borderStart() + paddingStart();
1803     if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1804         startPosition -= verticalScrollbarWidth();
1805     LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
1806
1807     // Add in our start margin.
1808     LayoutUnit childMarginStart = marginStartForChild(child);
1809     LayoutUnit newPosition = startPosition + childMarginStart;
1810         
1811     // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
1812     // to shift over as necessary to dodge any floats that might get in the way.
1813     if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock())
1814         newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
1815
1816     setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
1817 }
1818
1819 void RenderBlock::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
1820 {
1821     if (isHorizontalWritingMode()) {
1822         if (applyDelta == ApplyLayoutDelta)
1823             view().addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
1824         child->setX(logicalLeft);
1825     } else {
1826         if (applyDelta == ApplyLayoutDelta)
1827             view().addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
1828         child->setY(logicalLeft);
1829     }
1830 }
1831
1832 void RenderBlock::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
1833 {
1834     if (isHorizontalWritingMode()) {
1835         if (applyDelta == ApplyLayoutDelta)
1836             view().addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
1837         child->setY(logicalTop);
1838     } else {
1839         if (applyDelta == ApplyLayoutDelta)
1840             view().addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
1841         child->setX(logicalTop);
1842     }
1843 }
1844
1845 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
1846 {
1847     // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
1848     // an auto value. Add a method to determine this, so that we can avoid the relayout.
1849     if (relayoutChildren || (child->hasRelativeLogicalHeight() && !isRenderView()) || child->hasViewportPercentageLogicalHeight())
1850         child->setChildNeedsLayout(MarkOnlyThis);
1851
1852     // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1853     if (relayoutChildren && child->needsPreferredWidthsRecalculation())
1854         child->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
1855 }
1856
1857 void RenderBlock::dirtyForLayoutFromPercentageHeightDescendants()
1858 {
1859     if (!gPercentHeightDescendantsMap)
1860         return;
1861
1862     TrackedRendererListHashSet* descendants = gPercentHeightDescendantsMap->get(this);
1863     if (!descendants)
1864         return;
1865     
1866     TrackedRendererListHashSet::iterator end = descendants->end();
1867     for (TrackedRendererListHashSet::iterator it = descendants->begin(); it != end; ++it) {
1868         RenderBox* box = *it;
1869         while (box != this) {
1870             if (box->normalChildNeedsLayout())
1871                 break;
1872             box->setChildNeedsLayout(MarkOnlyThis);
1873             
1874             // If the width of an image is affected by the height of a child (e.g., an image with an aspect ratio),
1875             // then we have to dirty preferred widths, since even enclosing blocks can become dirty as a result.
1876             // (A horizontal flexbox that contains an inline image wrapped in an anonymous block for example.)
1877             if (box->hasAspectRatio()) 
1878                 box->setPreferredLogicalWidthsDirty(true);
1879             
1880             box = box->containingBlock();
1881             ASSERT(box);
1882             if (!box)
1883                 break;
1884         }
1885     }
1886 }
1887
1888 void RenderBlock::simplifiedNormalFlowLayout()
1889 {
1890     if (childrenInline()) {
1891         ListHashSet<RootInlineBox*> lineBoxes;
1892         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
1893             RenderObject* o = walker.current();
1894             if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating())) {
1895                 RenderBox& box = toRenderBox(*o);
1896                 box.layoutIfNeeded();
1897                 if (box.inlineBoxWrapper())
1898                     lineBoxes.add(&box.inlineBoxWrapper()->root());
1899             } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline()))
1900                 o->clearNeedsLayout();
1901         }
1902
1903         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
1904         // FIXME: Find a way to invalidate the knownToHaveNoOverflow flag on the InlineBoxes.
1905         GlyphOverflowAndFallbackFontsMap textBoxDataMap;                  
1906         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
1907             RootInlineBox* box = *it;
1908             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
1909         }
1910     } else {
1911         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
1912             if (!box->isOutOfFlowPositioned())
1913                 box->layoutIfNeeded();
1914         }
1915     }
1916 }
1917
1918 bool RenderBlock::simplifiedLayout()
1919 {
1920     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
1921         return false;
1922
1923     LayoutStateMaintainer statePusher(&view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
1924     
1925     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
1926         return false;
1927
1928     // Lay out positioned descendants or objects that just need to recompute overflow.
1929     if (needsSimplifiedNormalFlowLayout())
1930         simplifiedNormalFlowLayout();
1931
1932     // Make sure a forced break is applied after the content if we are a flow thread in a simplified layout.
1933     // This ensures the size information is correctly computed for the last auto-height region receiving content.
1934     if (isRenderFlowThread())
1935         toRenderFlowThread(this)->applyBreakAfterContent(clientLogicalBottom());
1936
1937     // Lay out our positioned objects if our positioned child bit is set.
1938     // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
1939     // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the 
1940     // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
1941     // are statically positioned and thus need to move with their absolute ancestors.
1942     bool canContainFixedPosObjects = canContainFixedPositionObjects();
1943     if (posChildNeedsLayout() || canContainFixedPosObjects)
1944         layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects);
1945
1946     // Recompute our overflow information.
1947     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
1948     // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
1949     // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
1950     // lowestPosition on every relayout so it's not a regression.
1951     // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
1952     // simplifiedLayout, we cache the value in m_overflow.
1953     LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
1954     computeOverflow(oldClientAfterEdge, true);
1955
1956     statePusher.pop();
1957     
1958     updateLayerTransform();
1959
1960     updateScrollInfoAfterLayout();
1961
1962     clearNeedsLayout();
1963     return true;
1964 }
1965
1966 void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject* child)
1967 {
1968     if (child->style()->position() != FixedPosition)
1969         return;
1970
1971     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontalWritingMode());
1972     bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontalWritingMode());
1973     if (!hasStaticBlockPosition && !hasStaticInlinePosition)
1974         return;
1975
1976     RenderObject* o = child->parent();
1977     while (o && !o->isRenderView() && o->style()->position() != AbsolutePosition)
1978         o = o->parent();
1979     if (o->style()->position() != AbsolutePosition)
1980         return;
1981
1982     RenderBox* box = toRenderBox(child);
1983     if (hasStaticInlinePosition) {
1984         LogicalExtentComputedValues computedValues;
1985         box->computeLogicalWidthInRegion(computedValues);
1986         LayoutUnit newLeft = computedValues.m_position;
1987         if (newLeft != box->logicalLeft())
1988             box->setChildNeedsLayout(MarkOnlyThis);
1989     } else if (hasStaticBlockPosition) {
1990         LayoutUnit oldTop = box->logicalTop();
1991         box->updateLogicalHeight();
1992         if (box->logicalTop() != oldTop)
1993             box->setChildNeedsLayout(MarkOnlyThis);
1994     }
1995 }
1996
1997 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly)
1998 {
1999     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
2000     if (!positionedDescendants)
2001         return;
2002         
2003     if (hasColumns())
2004         view().layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
2005
2006     RenderBox* r;
2007     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
2008     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
2009         r = *it;
2010         
2011         estimateRegionRangeForBoxChild(r);
2012
2013         // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
2014         // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e. 
2015         // it has static position.
2016         markFixedPositionObjectForLayoutIfNeeded(r);
2017         if (fixedPositionObjectsOnly) {
2018             r->layoutIfNeeded();
2019             continue;
2020         }
2021
2022         // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
2023         // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
2024         // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
2025         // positioned explicitly) this should not incur a performance penalty.
2026         if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this))
2027             r->setChildNeedsLayout(MarkOnlyThis);
2028             
2029         // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
2030         if (relayoutChildren && r->needsPreferredWidthsRecalculation())
2031             r->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
2032         
2033         if (!r->needsLayout())
2034             r->markForPaginationRelayoutIfNeeded();
2035         
2036         // 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
2037         // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
2038         if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
2039             r->clearNeedsLayout();
2040             
2041         // If we are paginated or in a line grid, go ahead and compute a vertical position for our object now.
2042         // If it's wrong we'll lay out again.
2043         LayoutUnit oldLogicalTop = 0;
2044         bool needsBlockDirectionLocationSetBeforeLayout = r->needsLayout() && view().layoutState()->needsBlockDirectionLocationSetBeforeLayout();
2045         if (needsBlockDirectionLocationSetBeforeLayout) {
2046             if (isHorizontalWritingMode() == r->isHorizontalWritingMode())
2047                 r->updateLogicalHeight();
2048             else
2049                 r->updateLogicalWidth();
2050             oldLogicalTop = logicalTopForChild(r);
2051         }
2052
2053         r->layoutIfNeeded();
2054
2055         // Lay out again if our estimate was wrong.
2056         if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop) {
2057             r->setChildNeedsLayout(MarkOnlyThis);
2058             r->layoutIfNeeded();
2059         }
2060
2061         if (updateRegionRangeForBoxChild(r)) {
2062             r->setNeedsLayout(MarkOnlyThis);
2063             r->layoutIfNeeded();
2064         }
2065     }
2066     
2067     if (hasColumns())
2068         view().layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
2069 }
2070
2071 void RenderBlock::markPositionedObjectsForLayout()
2072 {
2073     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
2074     if (positionedDescendants) {
2075         RenderBox* r;
2076         TrackedRendererListHashSet::iterator end = positionedDescendants->end();
2077         for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
2078             r = *it;
2079             r->setChildNeedsLayout();
2080         }
2081     }
2082 }
2083
2084 void RenderBlock::markForPaginationRelayoutIfNeeded()
2085 {
2086     ASSERT(!needsLayout());
2087     if (needsLayout())
2088         return;
2089
2090     if (view().layoutState()->pageLogicalHeightChanged() || (view().layoutState()->pageLogicalHeight() && view().layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()))
2091         setChildNeedsLayout(MarkOnlyThis);
2092 }
2093
2094 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2095 {
2096     LayoutPoint adjustedPaintOffset = paintOffset + location();
2097     
2098     PaintPhase phase = paintInfo.phase;
2099
2100     // Check if we need to do anything at all.
2101     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
2102     // paints the root's background.
2103     if (!isRoot()) {
2104         LayoutRect overflowBox = overflowRectForPaintRejection();
2105         flipForWritingMode(overflowBox);
2106         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
2107         overflowBox.moveBy(adjustedPaintOffset);
2108         if (!overflowBox.intersects(paintInfo.rect))
2109             return;
2110     }
2111
2112     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset);
2113     paintObject(paintInfo, adjustedPaintOffset);
2114     if (pushedClip)
2115         popContentsClip(paintInfo, phase, adjustedPaintOffset);
2116
2117     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
2118     // z-index.  We paint after we painted the background/border, so that the scrollbars will
2119     // sit above the background/border.
2120     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(*this) && !paintInfo.paintRootBackgroundOnly())
2121         layer()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect);
2122 }
2123
2124 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2125 {
2126     if (paintInfo.context->paintingDisabled())
2127         return;
2128
2129     const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
2130     bool ruleTransparent = style()->columnRuleIsTransparent();
2131     EBorderStyle ruleStyle = style()->columnRuleStyle();
2132     LayoutUnit ruleThickness = style()->columnRuleWidth();
2133     LayoutUnit colGap = columnGap();
2134     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
2135     if (!renderRule)
2136         return;
2137
2138     ColumnInfo* colInfo = columnInfo();
2139     unsigned colCount = columnCount(colInfo);
2140
2141     bool antialias = shouldAntialiasLines(paintInfo.context);
2142
2143     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
2144         bool leftToRight = style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed();
2145         LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentLogicalWidth();
2146         LayoutUnit ruleAdd = logicalLeftOffsetForContent();
2147         LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogicalWidth();
2148         LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
2149         BoxSide boxSide = isHorizontalWritingMode()
2150             ? leftToRight ? BSLeft : BSRight
2151             : leftToRight ? BSTop : BSBottom;
2152
2153         for (unsigned i = 0; i < colCount; i++) {
2154             // Move to the next position.
2155             if (leftToRight) {
2156                 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
2157                 currLogicalLeftOffset += inlineDirectionSize + colGap;
2158             } else {
2159                 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
2160                 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
2161             }
2162            
2163             // Now paint the column rule.
2164             if (i < colCount - 1) {
2165                 LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
2166                 LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
2167                 LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
2168                 LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
2169                 IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
2170                 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
2171             }
2172             
2173             ruleLogicalLeft = currLogicalLeftOffset;
2174         }
2175     } else {
2176         bool topToBottom = !style()->isFlippedBlocksWritingMode() ^ colInfo->progressionIsReversed();
2177         LayoutUnit ruleLeft = isHorizontalWritingMode()
2178             ? borderLeft() + paddingLeft()
2179             : colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderAndPaddingBefore() : borderAndPaddingAfter());
2180         LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
2181         LayoutUnit ruleTop = isHorizontalWritingMode()
2182             ? colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderAndPaddingBefore() : borderAndPaddingAfter())
2183             : borderStart() + paddingStart();
2184         LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
2185         LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
2186
2187         if (!topToBottom) {
2188             if (isHorizontalWritingMode())
2189                 ruleRect.setY(height() - ruleRect.maxY());
2190             else
2191                 ruleRect.setX(width() - ruleRect.maxX());
2192         }
2193
2194         ruleRect.moveBy(paintOffset);
2195
2196         BoxSide boxSide = isHorizontalWritingMode()
2197             ? topToBottom ? BSTop : BSBottom
2198             : topToBottom ? BSLeft : BSRight;
2199
2200         LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
2201         if (!isHorizontalWritingMode())
2202             step = step.transposedSize();
2203
2204         for (unsigned i = 1; i < colCount; i++) {
2205             ruleRect.move(step);
2206             IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
2207             drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
2208         }
2209     }
2210 }
2211
2212 LayoutUnit RenderBlock::initialBlockOffsetForPainting() const
2213 {
2214     ColumnInfo* colInfo = columnInfo();
2215     LayoutUnit result = 0;
2216     if (colInfo->progressionAxis() == ColumnInfo::BlockAxis && colInfo->progressionIsReversed()) {
2217         LayoutRect colRect = columnRectAt(colInfo, 0);
2218         result = isHorizontalWritingMode() ? colRect.y() : colRect.x();
2219         result -= borderAndPaddingBefore();
2220         if (style()->isFlippedBlocksWritingMode())
2221             result = -result;
2222     }
2223     return result;
2224 }
2225     
2226 LayoutUnit RenderBlock::blockDeltaForPaintingNextColumn() const
2227 {
2228     ColumnInfo* colInfo = columnInfo();
2229     LayoutUnit blockDelta = -colInfo->columnHeight();
2230     LayoutUnit colGap = columnGap();
2231     if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
2232         if (!colInfo->progressionIsReversed())
2233             blockDelta = colGap;
2234         else
2235             blockDelta -= (colInfo->columnHeight() + colGap);
2236     }
2237     if (style()->isFlippedBlocksWritingMode())
2238         blockDelta = -blockDelta;
2239     return blockDelta;
2240 }
2241
2242 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool paintingFloats)
2243 {
2244     // We need to do multiple passes, breaking up our child painting into strips.
2245     GraphicsContext* context = paintInfo.context;
2246     ColumnInfo* colInfo = columnInfo();
2247     unsigned colCount = columnCount(colInfo);
2248     if (!colCount)
2249         return;
2250     LayoutUnit colGap = columnGap();
2251     LayoutUnit currLogicalTopOffset = initialBlockOffsetForPainting();
2252     LayoutUnit blockDelta = blockDeltaForPaintingNextColumn();
2253     for (unsigned i = 0; i < colCount; i++) {
2254         // For each rect, we clip to the rect, and then we adjust our coords.
2255         LayoutRect colRect = columnRectAt(colInfo, i);
2256         flipForWritingMode(colRect);
2257         
2258         LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
2259         LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOffset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset);
2260         colRect.moveBy(paintOffset);
2261         PaintInfo info(paintInfo);
2262         info.rect.intersect(pixelSnappedIntRect(colRect));
2263         
2264         if (!info.rect.isEmpty()) {
2265             GraphicsContextStateSaver stateSaver(*context);
2266             LayoutRect clipRect(colRect);
2267             
2268             if (i < colCount - 1) {
2269                 if (isHorizontalWritingMode())
2270                     clipRect.expand(colGap / 2, 0);
2271                 else
2272                     clipRect.expand(0, colGap / 2);
2273             }
2274             // Each strip pushes a clip, since column boxes are specified as being
2275             // like overflow:hidden.
2276             // FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
2277             // are clipped according to the 'overflow' property.
2278             context->clip(pixelSnappedIntRect(clipRect));
2279
2280             // Adjust our x and y when painting.
2281             LayoutPoint adjustedPaintOffset = paintOffset + offset;
2282             if (paintingFloats)
2283                 paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
2284             else
2285                 paintContents(info, adjustedPaintOffset);
2286         }
2287         currLogicalTopOffset += blockDelta;
2288     }
2289 }
2290
2291 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2292 {
2293     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
2294     // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
2295     // will do a full repaint.
2296     if (document().didLayoutWithPendingStylesheets() && !isRenderView())
2297         return;
2298
2299     if (childrenInline())
2300         m_lineBoxes.paint(this, paintInfo, paintOffset);
2301     else {
2302         PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
2303         newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
2304
2305         // We don't paint our own background, but we do let the kids paint their backgrounds.
2306         PaintInfo paintInfoForChild(paintInfo);
2307         paintInfoForChild.phase = newPhase;
2308         paintInfoForChild.updateSubtreePaintRootForChildren(this);
2309
2310         // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
2311         // NSViews. Do not add any more code for this.
2312         bool usePrintRect = !view().printRect().isEmpty();
2313         paintChildren(paintInfo, paintOffset, paintInfoForChild, usePrintRect);
2314     }
2315 }
2316
2317 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset, PaintInfo& paintInfoForChild, bool usePrintRect)
2318 {
2319     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
2320         if (!paintChild(child, paintInfo, paintOffset, paintInfoForChild, usePrintRect))
2321             return;
2322     }
2323 }
2324
2325 bool RenderBlock::paintChild(RenderBox* child, PaintInfo& paintInfo, const LayoutPoint& paintOffset, PaintInfo& paintInfoForChild, bool usePrintRect)
2326 {
2327     // Check for page-break-before: always, and if it's set, break and bail.
2328     bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
2329     LayoutUnit absoluteChildY = paintOffset.y() + child->y();
2330     if (checkBeforeAlways
2331         && absoluteChildY > paintInfo.rect.y()
2332         && absoluteChildY < paintInfo.rect.maxY()) {
2333         view().setBestTruncatedAt(absoluteChildY, this, true);
2334         return false;
2335     }
2336
2337     if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= view().printRect().height()) {
2338         // Paginate block-level replaced elements.
2339         if (absoluteChildY + child->height() > view().printRect().maxY()) {
2340             if (absoluteChildY < view().truncatedAt())
2341                 view().setBestTruncatedAt(absoluteChildY, child);
2342             // If we were able to truncate, don't paint.
2343             if (absoluteChildY >= view().truncatedAt())
2344                 return false;
2345         }
2346     }
2347
2348     LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
2349     if (!child->hasSelfPaintingLayer() && !child->isFloating())
2350         child->paint(paintInfoForChild, childPoint);
2351
2352     // Check for page-break-after: always, and if it's set, break and bail.
2353     bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
2354     if (checkAfterAlways
2355         && (absoluteChildY + child->height()) > paintInfo.rect.y()
2356         && (absoluteChildY + child->height()) < paintInfo.rect.maxY()) {
2357         view().setBestTruncatedAt(absoluteChildY + child->height() + max<LayoutUnit>(0, child->collapsedMarginAfter()), this, true);
2358         return false;
2359     }
2360     return true;
2361 }
2362
2363
2364 void RenderBlock::paintCaret(PaintInfo& paintInfo, const LayoutPoint& paintOffset, CaretType type)
2365 {
2366     // Paint the caret if the FrameSelection says so or if caret browsing is enabled
2367     bool caretBrowsing = frame().settings().caretBrowsingEnabled();
2368     RenderObject* caretPainter;
2369     bool isContentEditable;
2370     if (type == CursorCaret) {
2371         caretPainter = frame().selection().caretRenderer();
2372         isContentEditable = frame().selection().rendererIsEditable();
2373     } else {
2374         caretPainter = frame().page()->dragCaretController().caretRenderer();
2375         isContentEditable = frame().page()->dragCaretController().isContentEditable();
2376     }
2377
2378     if (caretPainter == this && (isContentEditable || caretBrowsing)) {
2379         if (type == CursorCaret)
2380             frame().selection().paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
2381         else
2382             frame().page()->dragCaretController().paintDragCaret(&frame(), paintInfo.context, paintOffset, paintInfo.rect);
2383     }
2384 }
2385
2386 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2387 {
2388     PaintPhase paintPhase = paintInfo.phase;
2389
2390     // 1. paint background, borders etc
2391     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
2392         if (hasBoxDecorations())
2393             paintBoxDecorations(paintInfo, paintOffset);
2394         if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
2395             paintColumnRules(paintInfo, paintOffset);
2396     }
2397
2398     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
2399         paintMask(paintInfo, paintOffset);
2400         return;
2401     }
2402
2403     // We're done.  We don't bother painting any children.
2404     if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackgroundOnly())
2405         return;
2406
2407     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
2408     LayoutPoint scrolledOffset = paintOffset;
2409     if (hasOverflowClip())
2410         scrolledOffset.move(-scrolledContentOffset());
2411
2412     // 2. paint contents
2413     if (paintPhase != PaintPhaseSelfOutline) {
2414         if (hasColumns())
2415             paintColumnContents(paintInfo, scrolledOffset);
2416         else
2417             paintContents(paintInfo, scrolledOffset);
2418     }
2419
2420     // 3. paint selection
2421     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
2422     bool isPrinting = document().printing();
2423     if (!isPrinting && !hasColumns())
2424         paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
2425
2426     // 4. paint floats.
2427     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
2428         if (hasColumns())
2429             paintColumnContents(paintInfo, scrolledOffset, true);
2430         else
2431             paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
2432     }
2433
2434     // 5. paint outline.
2435     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2436         paintOutline(paintInfo, LayoutRect(paintOffset, size()));
2437
2438     // 6. paint continuation outlines.
2439     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
2440         RenderInline* inlineCont = inlineElementContinuation();
2441         if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
2442             RenderInline* inlineRenderer = toRenderInline(inlineCont->element()->renderer());
2443             RenderBlock* cb = containingBlock();
2444
2445             bool inlineEnclosedInSelfPaintingLayer = false;
2446             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
2447                 if (box->hasSelfPaintingLayer()) {
2448                     inlineEnclosedInSelfPaintingLayer = true;
2449                     break;
2450                 }
2451             }
2452
2453             // Do not add continuations for outline painting by our containing block if we are a relative positioned
2454             // anonymous block (i.e. have our own layer), paint them straightaway instead. This is because a block depends on renderers in its continuation table being
2455             // in the same layer. 
2456             if (!inlineEnclosedInSelfPaintingLayer && !hasLayer())
2457                 cb->addContinuationWithOutline(inlineRenderer);
2458             else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPaintingLayer && hasLayer()))
2459                 inlineRenderer->paintOutline(paintInfo, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
2460         }
2461         paintContinuationOutlines(paintInfo, paintOffset);
2462     }
2463
2464     // 7. paint caret.
2465     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
2466     // then paint the caret.
2467     if (paintPhase == PaintPhaseForeground) {        
2468         paintCaret(paintInfo, paintOffset, CursorCaret);
2469         paintCaret(paintInfo, paintOffset, DragCaret);
2470     }
2471 }
2472
2473 LayoutPoint RenderBlock::flipFloatForWritingModeForChild(const FloatingObject* child, const LayoutPoint& point) const
2474 {
2475     if (!style()->isFlippedBlocksWritingMode())
2476         return point;
2477     
2478     // This is similar to RenderBox::flipForWritingModeForChild. We have to subtract out our left/top offsets twice, since
2479     // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
2480     // case.
2481     if (isHorizontalWritingMode())
2482         return LayoutPoint(point.x(), point.y() + height() - child->renderer().height() - 2 * yPositionForFloatIncludingMargin(child));
2483     return LayoutPoint(point.x() + width() - child->renderer().width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
2484 }
2485
2486 RenderInline* RenderBlock::inlineElementContinuation() const
2487
2488     RenderBoxModelObject* continuation = this->continuation();
2489     return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
2490 }
2491
2492 RenderBlock* RenderBlock::blockElementContinuation() const
2493 {
2494     RenderBoxModelObject* currentContinuation = continuation();
2495     if (!currentContinuation || currentContinuation->isInline())
2496         return 0;
2497     RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2498     if (nextContinuation->isAnonymousBlock())
2499         return nextContinuation->blockElementContinuation();
2500     return nextContinuation;
2501 }
2502     
2503 static ContinuationOutlineTableMap* continuationOutlineTable()
2504 {
2505     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
2506     return &table;
2507 }
2508
2509 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
2510 {
2511     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
2512     // way of painting.
2513     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
2514     
2515     ContinuationOutlineTableMap* table = continuationOutlineTable();
2516     ListHashSet<RenderInline*>* continuations = table->get(this);
2517     if (!continuations) {
2518         continuations = new ListHashSet<RenderInline*>;
2519         table->set(this, adoptPtr(continuations));
2520     }
2521     
2522     continuations->add(flow);
2523 }
2524
2525 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
2526 {
2527     ContinuationOutlineTableMap* table = continuationOutlineTable();
2528     if (table->isEmpty())
2529         return false;
2530         
2531     ListHashSet<RenderInline*>* continuations = table->get(this);
2532     if (!continuations)
2533         return false;
2534
2535     return continuations->contains(flow);
2536 }
2537
2538 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint& paintOffset)
2539 {
2540     ContinuationOutlineTableMap* table = continuationOutlineTable();
2541     if (table->isEmpty())
2542         return;
2543         
2544     OwnPtr<ListHashSet<RenderInline*> > continuations = table->take(this);
2545     if (!continuations)
2546         return;
2547
2548     LayoutPoint accumulatedPaintOffset = paintOffset;
2549     // Paint each continuation outline.
2550     ListHashSet<RenderInline*>::iterator end = continuations->end();
2551     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
2552         // Need to add in the coordinates of the intervening blocks.
2553         RenderInline* flow = *it;
2554         RenderBlock* block = flow->containingBlock();
2555         for ( ; block && block != this; block = block->containingBlock())
2556             accumulatedPaintOffset.moveBy(block->location());
2557         ASSERT(block);   
2558         flow->paintOutline(info, accumulatedPaintOffset);
2559     }
2560 }
2561
2562 bool RenderBlock::shouldPaintSelectionGaps() const
2563 {
2564     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
2565 }
2566
2567 bool RenderBlock::isSelectionRoot() const
2568 {
2569     if (isPseudoElement())
2570         return false;
2571     ASSERT(element() || isAnonymous());
2572         
2573     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
2574     if (isTable())
2575         return false;
2576         
2577     if (isBody() || isRoot() || hasOverflowClip()
2578         || isPositioned() || isFloating()
2579         || isTableCell() || isInlineBlockOrInlineTable()
2580         || hasTransform() || hasReflection() || hasMask() || isWritingModeRoot()
2581         || isRenderFlowThread())
2582         return true;
2583     
2584     if (view().selectionStart()) {
2585         Node* startElement = view().selectionStart()->node();
2586         if (startElement && startElement->rootEditableElement() == element())
2587             return true;
2588     }
2589     
2590     return false;
2591 }
2592
2593 GapRects RenderBlock::selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer)
2594 {
2595     ASSERT(!needsLayout());
2596
2597     if (!shouldPaintSelectionGaps())
2598         return GapRects();
2599
2600     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
2601     mapLocalToContainer(repaintContainer, transformState, ApplyContainerFlip | UseTransforms);
2602     LayoutPoint offsetFromRepaintContainer = roundedLayoutPoint(transformState.mappedPoint());
2603
2604     if (hasOverflowClip())
2605         offsetFromRepaintContainer -= scrolledContentOffset();
2606
2607     LogicalSelectionOffsetCaches cache(this);
2608     LayoutUnit lastTop = 0;
2609     LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop, cache);
2610     LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop, cache);
2611     
2612     return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight, cache);
2613 }
2614
2615 void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2616 {
2617     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2618         LogicalSelectionOffsetCaches cache(this);
2619         LayoutUnit lastTop = 0;
2620         LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop, cache);
2621         LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop, cache);
2622         GraphicsContextStateSaver stateSaver(*paintInfo.context);
2623
2624         LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, cache, &paintInfo);
2625         if (!gapRectsBounds.isEmpty()) {
2626             if (RenderLayer* layer = enclosingLayer()) {
2627                 gapRectsBounds.moveBy(-paintOffset);
2628                 if (!hasLayer()) {
2629                     LayoutRect localBounds(gapRectsBounds);
2630                     flipForWritingMode(localBounds);
2631                     gapRectsBounds = localToContainerQuad(FloatRect(localBounds), &layer->renderer()).enclosingBoundingBox();
2632                     if (layer->renderer().hasOverflowClip())
2633                         gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
2634                 }
2635                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
2636             }
2637         }
2638     }
2639 }
2640
2641 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects)
2642 {
2643     if (!positionedObjects)
2644         return;
2645     
2646     TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
2647     for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
2648         RenderBox* r = *it;
2649         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
2650     }
2651 }
2652
2653 static LayoutUnit blockDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
2654 {
2655     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
2656 }
2657
2658 static LayoutUnit inlineDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
2659 {
2660     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
2661 }
2662
2663 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPhysicalPosition, const LayoutRect& logicalRect)
2664 {
2665     LayoutRect result;
2666     if (isHorizontalWritingMode())
2667         result = logicalRect;
2668     else
2669         result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
2670     flipForWritingMode(result);
2671     result.moveBy(rootBlockPhysicalPosition);
2672     return result;
2673 }
2674
2675 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2676     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2677 {
2678     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
2679     // Clip out floating and positioned objects when painting selection gaps.
2680     if (paintInfo) {
2681         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
2682         LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
2683         rootBlock->flipForWritingMode(flippedBlockRect);
2684         flippedBlockRect.moveBy(rootBlockPhysicalPosition);
2685         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
2686         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
2687             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
2688                 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
2689         clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock);
2690     }
2691
2692     // 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
2693     // fixed).
2694     GapRects result;
2695     if (!isRenderBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
2696         return result;
2697
2698     if (hasColumns() || hasTransform() || style()->columnSpan()) {
2699         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
2700         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
2701         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight(), cache);
2702         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(), cache);
2703         return result;
2704     }
2705
2706     if (childrenInline())
2707         result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo);
2708     else
2709         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo);
2710
2711     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
2712     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd)) {
2713         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
2714             lastLogicalTop, lastLogicalLeft, lastLogicalRight, logicalHeight(), cache, paintInfo));
2715     }
2716
2717     return result;
2718 }
2719
2720 GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2721     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2722 {
2723     GapRects result;
2724
2725     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
2726
2727     if (!firstLineBox()) {
2728         if (containsStart) {
2729             // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
2730             // case.
2731             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
2732             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight(), cache);
2733             lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(), cache);
2734         }
2735         return result;
2736     }
2737
2738     RootInlineBox* lastSelectedLine = 0;
2739     RootInlineBox* curr;
2740     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
2741
2742     // Now paint the gaps for the lines.
2743     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
2744         LayoutUnit selTop =  curr->selectionTopAdjustedForPrecedingBlock();
2745         LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock();
2746
2747         if (!containsStart && !lastSelectedLine &&
2748             selectionState() != SelectionStart && selectionState() != SelectionBoth)
2749             result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, selTop, cache, paintInfo));
2750         
2751         LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
2752         logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : offsetFromRootBlock.transposedSize());
2753         LayoutRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
2754         if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
2755             || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
2756             result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, cache, paintInfo));
2757
2758         lastSelectedLine = curr;
2759     }
2760
2761     if (containsStart && !lastSelectedLine)
2762         // VisibleSelection must start just after our last line.
2763         lastSelectedLine = lastRootBox();
2764
2765     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
2766         // Go ahead and update our lastY to be the bottom of the last selected line.
2767         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
2768         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom(), cache);
2769         lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom(), cache);
2770     }
2771     return result;
2772 }
2773
2774 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2775     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2776 {
2777     GapRects result;
2778
2779     // Go ahead and jump right to the first block child that contains some selected objects.
2780     RenderBox* curr;
2781     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
2782     
2783     if (!curr)
2784         return result;
2785
2786     LogicalSelectionOffsetCaches childCache(this, cache);
2787
2788     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
2789         SelectionState childState = curr->selectionState();
2790         if (childState == SelectionBoth || childState == SelectionEnd)
2791             sawSelectionEnd = true;
2792
2793         if (curr->isFloatingOrOutOfFlowPositioned())
2794             continue; // We must be a normal flow object in order to even be considered.
2795
2796         if (curr->isInFlowPositioned() && curr->hasLayer()) {
2797             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
2798             // Just disregard it completely.
2799             LayoutSize relOffset = curr->layer()->offsetForInFlowPosition();
2800             if (relOffset.width() || relOffset.height())
2801                 continue;
2802         }
2803
2804         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
2805         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
2806         if (fillBlockGaps) {
2807             // We need to fill the vertical gap above this object.
2808             if (childState == SelectionEnd || childState == SelectionInside) {
2809                 // Fill the gap above the object.
2810                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
2811                     lastLogicalTop, lastLogicalLeft, lastLogicalRight, curr->logicalTop(), cache, paintInfo));
2812             }
2813
2814             // 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*
2815             // our object.  We know this if the selection did not end inside our object.
2816             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
2817                 childState = SelectionNone;
2818
2819             // Fill side gaps on this object based off its state.
2820             bool leftGap, rightGap;
2821             getSelectionGapInfo(childState, leftGap, rightGap);
2822
2823             if (leftGap)
2824                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), cache, paintInfo));
2825             if (rightGap)
2826                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), cache, paintInfo));
2827
2828             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
2829             // they can without bumping into floating or positioned objects.  Ideally they will go right up
2830             // to the border of the root selection block.
2831             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
2832             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom(), cache);
2833             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom(), cache);
2834         } else if (childState != SelectionNone) {
2835             // We must be a block that has some selected object inside it.  Go ahead and recur.
2836             result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), 
2837                 lastLogicalTop, lastLogicalLeft, lastLogicalRight, childCache, paintInfo));
2838         }
2839     }
2840     return result;
2841 }
2842
2843 LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2844     LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2845 {
2846     LayoutUnit logicalTop = lastLogicalTop;
2847     LayoutUnit logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
2848     if (logicalHeight <= 0)
2849         return LayoutRect();
2850
2851     // Get the selection offsets for the bottom of the gap
2852     LayoutUnit logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom, cache));
2853     LayoutUnit logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom, cache));
2854     LayoutUnit logicalWidth = logicalRight - logicalLeft;
2855     if (logicalWidth <= 0)
2856         return LayoutRect();
2857
2858     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
2859     if (paintInfo)
2860         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selectionBackgroundColor(), style()->colorSpace());
2861     return gapRect;
2862 }
2863
2864 LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2865     RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2866 {
2867     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
2868     LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop, cache), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight, cache));
2869     LayoutUnit rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalLeft),
2870         min(logicalRightSelectionOffset(rootBlock, logicalTop, cache), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight, cache)));
2871     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
2872     if (rootBlockLogicalWidth <= 0)
2873         return LayoutRect();
2874
2875     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
2876     if (paintInfo)
2877         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
2878     return gapRect;
2879 }
2880
2881 LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2882     RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2883 {
2884     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
2885     LayoutUnit rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalRight),
2886         max(logicalLeftSelectionOffset(rootBlock, logicalTop, cache), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight, cache)));
2887     LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop, cache), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight, cache));
2888     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
2889     if (rootBlockLogicalWidth <= 0)
2890         return LayoutRect();
2891
2892     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
2893     if (paintInfo)
2894         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
2895     return gapRect;
2896 }
2897
2898 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
2899 {
2900     bool ltr = style()->isLeftToRightDirection();
2901     leftGap = (state == RenderObject::SelectionInside) ||
2902               (state == RenderObject::SelectionEnd && ltr) ||
2903               (state == RenderObject::SelectionStart && !ltr);
2904     rightGap = (state == RenderObject::SelectionInside) ||
2905                (state == RenderObject::SelectionStart && ltr) ||
2906                (state == RenderObject::SelectionEnd && !ltr);
2907 }
2908
2909 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches& cache)
2910 {
2911     LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false);
2912     if (logicalLeft == logicalLeftOffsetForContent()) {
2913         if (rootBlock != this) // The border can potentially be further extended by our containingBlock().
2914             return cache.containingBlockInfo(this).logicalLeftSelectionOffset(rootBlock, position + logicalTop());
2915         return logicalLeft;
2916     } else {
2917         RenderBlock* cb = this;
2918         const LogicalSelectionOffsetCaches* currentCache = &cache;
2919         while (cb != rootBlock) {
2920             logicalLeft += cb->logicalLeft();
2921
2922             ASSERT(currentCache);
2923             const LogicalSelectionOffsetCaches::ContainingBlockInfo& info = currentCache->containingBlockInfo(cb);
2924             cb = info.block();
2925             currentCache = info.cache();
2926         }
2927     }
2928     return logicalLeft;
2929 }
2930
2931 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches& cache)
2932 {
2933     LayoutUnit logicalRight = logicalRightOffsetForLine(position, false);
2934     if (logicalRight == logicalRightOffsetForContent()) {
2935         if (rootBlock != this) // The border can potentially be further extended by our containingBlock().
2936             return cache.containingBlockInfo(this).logicalRightSelectionOffset(rootBlock, position + logicalTop());
2937         return logicalRight;
2938     } else {
2939         RenderBlock* cb = this;
2940         const LogicalSelectionOffsetCaches* currentCache = &cache;
2941         while (cb != rootBlock) {
2942             logicalRight += cb->logicalLeft();
2943
2944             ASSERT(currentCache);
2945             const LogicalSelectionOffsetCaches::ContainingBlockInfo& info = currentCache->containingBlockInfo(cb);
2946             cb = info.block();
2947             currentCache = info.cache();
2948         }
2949     }
2950     return logicalRight;
2951 }
2952
2953 RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
2954 {
2955     if (isSelectionRoot())
2956         return 0;
2957
2958     const RenderObject* object = this;
2959     RenderObject* sibling;
2960     do {
2961         sibling = object->previousSibling();
2962         while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
2963             sibling = sibling->previousSibling();
2964
2965         offset -= LayoutSize(toRenderBlock(object)->logicalLeft(), toRenderBlock(object)->logicalTop());
2966         object = object->parent();
2967     } while (!sibling && object && object->isRenderBlock() && !toRenderBlock(object)->isSelectionRoot());
2968
2969     if (!sibling)
2970         return 0;
2971
2972     RenderBlock* beforeBlock = toRenderBlock(sibling);
2973
2974     offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
2975
2976     RenderObject* child = beforeBlock->lastChild();
2977     while (child && child->isRenderBlock()) {
2978         beforeBlock = toRenderBlock(child);
2979         offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
2980         child = beforeBlock->lastChild();
2981     }
2982     return beforeBlock;
2983 }
2984
2985 void RenderBlock::insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
2986 {
2987     if (!descendantsMap) {
2988         descendantsMap = new TrackedDescendantsMap;
2989         containerMap = new TrackedContainerMap;
2990     }
2991     
2992     TrackedRendererListHashSet* descendantSet = descendantsMap->get(this);
2993     if (!descendantSet) {
2994         descendantSet = new TrackedRendererListHashSet;
2995         descendantsMap->set(this, adoptPtr(descendantSet));
2996     }
2997     bool added = descendantSet->add(descendant).isNewEntry;
2998     if (!added) {
2999         ASSERT(containerMap->get(descendant));
3000         ASSERT(containerMap->get(descendant)->contains(this));
3001         return;
3002     }
3003     
3004     HashSet<RenderBlock*>* containerSet = containerMap->get(descendant);
3005     if (!containerSet) {
3006         containerSet = new HashSet<RenderBlock*>;
3007         containerMap->set(descendant, adoptPtr(containerSet));
3008     }
3009     ASSERT(!containerSet->contains(this));
3010     containerSet->add(this);
3011 }
3012
3013 void RenderBlock::removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
3014 {
3015     if (!descendantsMap)
3016         return;
3017     
3018     OwnPtr<HashSet<RenderBlock*> > containerSet = containerMap->take(descendant);
3019     if (!containerSet)
3020         return;
3021     
3022     HashSet<RenderBlock*>::iterator end = containerSet->end();
3023     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
3024         RenderBlock* container = *it;
3025
3026         // FIXME: Disabling this assert temporarily until we fix the layout
3027         // bugs associated with positioned objects not properly cleared from
3028         // their ancestor chain before being moved. See webkit bug 93766.
3029         // ASSERT(descendant->isDescendantOf(container));
3030
3031         TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap->find(container);
3032         ASSERT(descendantsMapIterator != descendantsMap->end());
3033         if (descendantsMapIterator == descendantsMap->end())
3034             continue;
3035         TrackedRendererListHashSet* descendantSet = descendantsMapIterator->value.get();
3036         ASSERT(descendantSet->contains(descendant));
3037         descendantSet->remove(descendant);
3038         if (descendantSet->isEmpty())
3039             descendantsMap->remove(descendantsMapIterator);
3040     }
3041 }
3042
3043 TrackedRendererListHashSet* RenderBlock::positionedObjects() const
3044 {
3045     if (gPositionedDescendantsMap)
3046         return gPositionedDescendantsMap->get(this);
3047     return 0;
3048 }
3049
3050 void RenderBlock::insertPositionedObject(RenderBox* o)
3051 {
3052     ASSERT(!isAnonymousBlock());
3053
3054     if (o->isRenderFlowThread())
3055         return;
3056     
3057     insertIntoTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
3058 }
3059
3060 void RenderBlock::removePositionedObject(RenderBox* o)
3061 {
3062     removeFromTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
3063 }
3064
3065 void RenderBlock::removePositionedObjects(RenderBlock* o, ContainingBlockState containingBlockState)
3066 {
3067     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
3068     if (!positionedDescendants)
3069         return;
3070     
3071     RenderBox* r;
3072     
3073     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
3074     
3075     Vector<RenderBox*, 16> deadObjects;
3076
3077     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
3078         r = *it;
3079         if (!o || r->isDescendantOf(o)) {
3080             if (containingBlockState == NewContainingBlock)
3081                 r->setChildNeedsLayout(MarkOnlyThis);
3082             
3083             // It is parent blocks job to add positioned child to positioned objects list of its containing block
3084             // Parent layout needs to be invalidated to ensure this happens.
3085             RenderElement* p = r->parent();
3086             while (p && !p->isRenderBlock())
3087                 p = p->parent();
3088             if (p)
3089                 p->setChildNeedsLayout();
3090             
3091             deadObjects.append(r);
3092         }
3093     }
3094     
3095     for (unsigned i = 0; i < deadObjects.size(); i++)
3096         removePositionedObject(deadObjects.at(i));
3097 }
3098
3099 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
3100 {
3101     insertIntoTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
3102 }
3103
3104 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
3105 {
3106     removeFromTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
3107 }
3108
3109 TrackedRendererListHashSet* RenderBlock::percentHeightDescendants() const
3110 {
3111     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
3112 }
3113
3114 bool RenderBlock::hasPercentHeightContainerMap()
3115 {
3116     return gPercentHeightContainerMap;
3117 }
3118
3119 bool RenderBlock::hasPercentHeightDescendant(RenderBox* descendant)
3120 {
3121     // We don't null check gPercentHeightContainerMap since the caller
3122     // already ensures this and we need to call this function on every
3123     // descendant in clearPercentHeightDescendantsFrom().
3124     ASSERT(gPercentHeightContainerMap);
3125     return gPercentHeightContainerMap->contains(descendant);
3126 }
3127
3128 void RenderBlock::removePercentHeightDescendantIfNeeded(RenderBox* descendant)
3129 {
3130     // We query the map directly, rather than looking at style's
3131     // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those
3132     // can change with writing mode/directional changes.
3133     if (!hasPercentHeightContainerMap())
3134         return;
3135
3136     if (!hasPercentHeightDescendant(descendant))
3137         return;
3138
3139     removePercentHeightDescendant(descendant);
3140 }
3141
3142 void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent)
3143 {
3144     ASSERT(gPercentHeightContainerMap);
3145     for (RenderObject* curr = parent->firstChild(); curr; curr = curr->nextInPreOrder(parent)) {
3146         if (!curr->isBox())
3147             continue;
3148  
3149         RenderBox* box = toRenderBox(curr);
3150         if (!hasPercentHeightDescendant(box))
3151             continue;
3152
3153         removePercentHeightDescendant(box);
3154     }
3155 }
3156
3157 LayoutUnit RenderBlock::textIndentOffset() const
3158 {
3159     LayoutUnit cw = 0;
3160     if (style()->textIndent().isPercent())
3161         cw = containingBlock()->availableLogicalWidth();
3162     return minimumValueForLength(style()->textIndent(), cw);
3163 }
3164
3165 LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region) const
3166 {
3167     LayoutUnit logicalLeftOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
3168     if (!region)
3169         return logicalLeftOffset;
3170     LayoutRect boxRect = borderBoxRectInRegion(region);
3171     return logicalLeftOffset + (isHorizontalWritingMode() ? boxRect.x() : boxRect.y());
3172 }
3173
3174 LayoutUnit RenderBlock::logicalRightOffsetForContent(RenderRegion* region) const
3175 {
3176     LayoutUnit logicalRightOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
3177     logicalRightOffset += availableLogicalWidth();
3178     if (!region)
3179         return logicalRightOffset;
3180     LayoutRect boxRect = borderBoxRectInRegion(region);
3181     return logicalRightOffset - (logicalWidth() - (isHorizontalWritingMode() ? boxRect.maxX() : boxRect.maxY()));
3182 }
3183
3184 LayoutUnit RenderBlock::adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
3185 {
3186     LayoutUnit left = offsetFromFloats;
3187
3188     if (applyTextIndent && style()->isLeftToRightDirection())
3189         left += textIndentOffset();
3190
3191     if (style()->lineAlign() == LineAlignNone)
3192         return left;
3193     
3194     // Push in our left offset so that it is aligned with the character grid.
3195     LayoutState* layoutState = view().layoutState();
3196     if (!layoutState)
3197         return left;
3198
3199     RenderBlock* lineGrid = layoutState->lineGrid();
3200     if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode())
3201         return left;
3202
3203     // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
3204     float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth();
3205     if (!maxCharWidth)
3206         return left;
3207
3208     LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
3209     LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
3210     
3211     // Push in to the nearest character width (truncated so that we pixel snap left).
3212     // FIXME: Should be patched when subpixel layout lands, since this calculation doesn't have to pixel snap
3213     // any more (https://bugs.webkit.org/show_bug.cgi?id=79946).
3214     // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
3215     // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
3216     // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
3217     // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
3218     // (https://bugs.webkit.org/show_bug.cgi?id=79944)
3219     float remainder = fmodf(maxCharWidth - fmodf(left + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
3220     left += remainder;
3221     return left;
3222 }
3223
3224 LayoutUnit RenderBlock::adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
3225 {
3226     LayoutUnit right = offsetFromFloats;
3227     
3228     if (applyTextIndent && !style()->isLeftToRightDirection())
3229         right -= textIndentOffset();
3230     
3231     if (style()->lineAlign() == LineAlignNone)
3232         return right;
3233     
3234     // Push in our right offset so that it is aligned with the character grid.
3235     LayoutState* layoutState = view().layoutState();
3236     if (!layoutState)
3237         return right;
3238
3239     RenderBlock* lineGrid = layoutState->lineGrid();
3240     if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode())
3241         return right;
3242
3243     // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
3244     float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth();
3245     if (!maxCharWidth)
3246         return right;
3247
3248     LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
3249     LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
3250     
3251     // Push in to the nearest character width (truncated so that we pixel snap right).
3252     // FIXME: Should be patched when subpixel layout lands, since this calculation doesn't have to pixel snap
3253     // any more (https://bugs.webkit.org/show_bug.cgi?id=79946).
3254     // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
3255     // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
3256     // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
3257     // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
3258     // (https://bugs.webkit.org/show_bug.cgi?id=79944)
3259     float remainder = fmodf(fmodf(right + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
3260     right -= ceilf(remainder);
3261     return right;
3262 }
3263
3264 void RenderBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest)
3265 {
3266     if (logicalTop >= logicalBottom)
3267         return;
3268
3269     RootInlineBox* lowestDirtyLine = lastRootBox();
3270     RootInlineBox* afterLowest = lowestDirtyLine;
3271     while (lowestDirtyLine && lowestDirtyLine->lineBottomWithLeading() >= logicalBottom && logicalBottom < LayoutUnit::max()) {
3272         afterLowest = lowestDirtyLine;
3273         lowestDirtyLine = lowestDirtyLine->prevRootBox();
3274     }
3275
3276     while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWithLeading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) {
3277         afterLowest->markDirty();
3278         afterLowest = afterLowest->prevRootBox();
3279     }
3280 }
3281
3282 bool