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