Move CSS3 text decoration implementation behind ENABLE(CSS3_TEXT_DECORATION)
[WebKit-https.git] / Source / WebCore / rendering / RenderObject.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  *           (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011, 2013 Apple Inc. All rights reserved.
7  * Copyright (C) 2009 Google Inc. All rights reserved.
8  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26
27 #include "config.h"
28 #include "RenderObject.h"
29
30 #include "AXObjectCache.h"
31 #include "AnimationController.h"
32 #include "EventHandler.h"
33 #include "FloatQuad.h"
34 #include "FlowThreadController.h"
35 #include "Frame.h"
36 #include "FrameSelection.h"
37 #include "FrameView.h"
38 #include "GraphicsContext.h"
39 #include "HTMLAnchorElement.h"
40 #include "HTMLElement.h"
41 #include "HTMLImageElement.h"
42 #include "HTMLNames.h"
43 #include "HTMLTableElement.h"
44 #include "HitTestResult.h"
45 #include "LogicalSelectionOffsetCaches.h"
46 #include "Page.h"
47 #include "PseudoElement.h"
48 #include "RenderArena.h"
49 #include "RenderCounter.h"
50 #include "RenderFlowThread.h"
51 #include "RenderGeometryMap.h"
52 #include "RenderInline.h"
53 #include "RenderLayer.h"
54 #include "RenderLayerBacking.h"
55 #include "RenderNamedFlowThread.h"
56 #include "RenderScrollbarPart.h"
57 #include "RenderTheme.h"
58 #include "RenderView.h"
59 #include "Settings.h"
60 #include "StyleResolver.h"
61 #include "TransformState.h"
62 #include "htmlediting.h"
63 #include <algorithm>
64 #include <wtf/RefCountedLeakCounter.h>
65
66 #if ENABLE(SVG)
67 #include "RenderSVGResourceContainer.h"
68 #include "SVGRenderSupport.h"
69 #endif
70
71 using namespace std;
72
73 namespace WebCore {
74
75 using namespace HTMLNames;
76
77 #ifndef NDEBUG
78 RenderObject::SetLayoutNeededForbiddenScope::SetLayoutNeededForbiddenScope(RenderObject* renderObject, bool isForbidden)
79     : m_renderObject(renderObject)
80     , m_preexistingForbidden(m_renderObject->isSetNeedsLayoutForbidden())
81 {
82     m_renderObject->setNeedsLayoutIsForbidden(isForbidden);
83 }
84
85 RenderObject::SetLayoutNeededForbiddenScope::~SetLayoutNeededForbiddenScope()
86 {
87     m_renderObject->setNeedsLayoutIsForbidden(m_preexistingForbidden);
88 }
89 #endif
90
91 struct SameSizeAsRenderObject {
92     virtual ~SameSizeAsRenderObject() { } // Allocate vtable pointer.
93     void* pointers[4];
94 #ifndef NDEBUG
95     unsigned m_debugBitfields : 2;
96 #endif
97     unsigned m_bitfields;
98 };
99
100 COMPILE_ASSERT(sizeof(RenderObject) == sizeof(SameSizeAsRenderObject), RenderObject_should_stay_small);
101
102 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, renderObjectCounter, ("RenderObject"));
103
104 RenderObject::RenderObject(Node& node)
105     : CachedImageClient()
106     , m_node(node)
107     , m_parent(0)
108     , m_previous(0)
109     , m_next(0)
110 #ifndef NDEBUG
111     , m_hasAXObject(false)
112     , m_setNeedsLayoutForbidden(false)
113 #endif
114     , m_bitfields(node)
115 {
116     if (!node.isDocumentNode())
117         view().didCreateRenderer();
118 #ifndef NDEBUG
119     renderObjectCounter.increment();
120 #endif
121 }
122
123 RenderObject::~RenderObject()
124 {
125 #ifndef NDEBUG
126     ASSERT(!m_hasAXObject);
127     renderObjectCounter.decrement();
128 #endif
129     view().didDestroyRenderer();
130 }
131
132 RenderTheme* RenderObject::theme() const
133 {
134     ASSERT(document().page());
135
136     return document().page()->theme();
137 }
138
139 bool RenderObject::isDescendantOf(const RenderObject* obj) const
140 {
141     for (const RenderObject* r = this; r; r = r->m_parent) {
142         if (r == obj)
143             return true;
144     }
145     return false;
146 }
147
148 bool RenderObject::isBody() const
149 {
150     return node() && node()->hasTagName(bodyTag);
151 }
152
153 bool RenderObject::isHR() const
154 {
155     return node() && node()->hasTagName(hrTag);
156 }
157
158 bool RenderObject::isLegend() const
159 {
160     return node() && node()->hasTagName(legendTag);
161 }
162
163 bool RenderObject::isHTMLMarquee() const
164 {
165     return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);
166 }
167
168 void RenderObject::setFlowThreadStateIncludingDescendants(FlowThreadState state)
169 {
170     setFlowThreadState(state);
171
172     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling()) {
173         // If the child is a fragmentation context it already updated the descendants flag accordingly.
174         if (child->isRenderFlowThread())
175             continue;
176         ASSERT(state != child->flowThreadState());
177         child->setFlowThreadStateIncludingDescendants(state);
178     }
179 }
180
181 void RenderObject::setParent(RenderElement* parent)
182 {
183     m_parent = parent;
184
185     // Only update if our flow thread state is different from our new parent and if we're not a RenderFlowThread.
186     // A RenderFlowThread is always considered to be inside itself, so it never has to change its state
187     // in response to parent changes.
188     FlowThreadState newState = parent ? parent->flowThreadState() : NotInsideFlowThread;
189     if (newState != flowThreadState() && !isRenderFlowThread())
190         setFlowThreadStateIncludingDescendants(newState);
191 }
192
193 void RenderObject::removeFromParent()
194 {
195     if (parent())
196         parent()->removeChild(*this);
197 }
198
199 RenderObject* RenderObject::nextInPreOrder() const
200 {
201     if (RenderObject* o = firstChildSlow())
202         return o;
203
204     return nextInPreOrderAfterChildren();
205 }
206
207 RenderObject* RenderObject::nextInPreOrderAfterChildren() const
208 {
209     RenderObject* o;
210     if (!(o = nextSibling())) {
211         o = parent();
212         while (o && !o->nextSibling())
213             o = o->parent();
214         if (o)
215             o = o->nextSibling();
216     }
217
218     return o;
219 }
220
221 RenderObject* RenderObject::nextInPreOrder(const RenderObject* stayWithin) const
222 {
223     if (RenderObject* o = firstChildSlow())
224         return o;
225
226     return nextInPreOrderAfterChildren(stayWithin);
227 }
228
229 RenderObject* RenderObject::nextInPreOrderAfterChildren(const RenderObject* stayWithin) const
230 {
231     if (this == stayWithin)
232         return 0;
233
234     const RenderObject* current = this;
235     RenderObject* next;
236     while (!(next = current->nextSibling())) {
237         current = current->parent();
238         if (!current || current == stayWithin)
239             return 0;
240     }
241     return next;
242 }
243
244 RenderObject* RenderObject::previousInPreOrder() const
245 {
246     if (RenderObject* o = previousSibling()) {
247         while (RenderObject* last = o->lastChildSlow())
248             o = last;
249         return o;
250     }
251
252     return parent();
253 }
254
255 RenderObject* RenderObject::previousInPreOrder(const RenderObject* stayWithin) const
256 {
257     if (this == stayWithin)
258         return 0;
259
260     return previousInPreOrder();
261 }
262
263 RenderObject* RenderObject::childAt(unsigned index) const
264 {
265     RenderObject* child = firstChildSlow();
266     for (unsigned i = 0; child && i < index; i++)
267         child = child->nextSibling();
268     return child;
269 }
270
271 RenderObject* RenderObject::firstLeafChild() const
272 {
273     RenderObject* r = firstChildSlow();
274     while (r) {
275         RenderObject* n = 0;
276         n = r->firstChildSlow();
277         if (!n)
278             break;
279         r = n;
280     }
281     return r;
282 }
283
284 RenderObject* RenderObject::lastLeafChild() const
285 {
286     RenderObject* r = lastChildSlow();
287     while (r) {
288         RenderObject* n = 0;
289         n = r->lastChildSlow();
290         if (!n)
291             break;
292         r = n;
293     }
294     return r;
295 }
296
297 #if ENABLE(IOS_TEXT_AUTOSIZING)
298 // Inspired by Node::traverseNextNode.
299 RenderObject* RenderObject::traverseNext(const RenderObject* stayWithin) const
300 {
301     if (firstChild()) {
302         ASSERT(!stayWithin || firstChild()->isDescendantOf(stayWithin));
303         return firstChild();
304     }
305     if (this == stayWithin)
306         return 0;
307     if (nextSibling()) {
308         ASSERT(!stayWithin || nextSibling()->isDescendantOf(stayWithin));
309         return nextSibling();
310     }
311     const RenderObject* n = this;
312     while (n && !n->nextSibling() && (!stayWithin || n->parent() != stayWithin))
313         n = n->parent();
314     if (n) {
315         ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
316         return n->nextSibling();
317     }
318     return 0;
319 }
320
321 // Non-recursive version of the DFS search.
322 RenderObject* RenderObject::traverseNext(const RenderObject* stayWithin, HeightTypeTraverseNextInclusionFunction inclusionFunction, int& currentDepth, int& newFixedDepth) const
323 {
324     BlockContentHeightType overflowType;
325
326     // Check for suitable children.
327     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
328         overflowType = inclusionFunction(child);
329         if (overflowType != FixedHeight) {
330             currentDepth++;
331             if (overflowType == OverflowHeight)
332                 newFixedDepth = currentDepth;
333             ASSERT(!stayWithin || child->isDescendantOf(stayWithin));
334             return child;
335         }
336     }
337
338     if (this == stayWithin)
339         return 0;
340
341     // Now we traverse other nodes if they exist, otherwise
342     // we go to the parent node and try doing the same.
343     const RenderObject* n = this;
344     while (n) {
345         while (n && !n->nextSibling() && (!stayWithin || n->parent() != stayWithin)) {
346             n = n->parent();
347             currentDepth--;
348         }
349         if (!n)
350             return 0;
351         for (RenderObject* sibling = n->nextSibling(); sibling; sibling = sibling->nextSibling()) {
352             overflowType = inclusionFunction(sibling);
353             if (overflowType != FixedHeight) {
354                 if (overflowType == OverflowHeight)
355                     newFixedDepth = currentDepth;
356                 ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
357                 return sibling;
358             }
359         }
360         if (!stayWithin || n->parent() != stayWithin) {
361             n = n->parent();
362             currentDepth--;
363         } else
364             return 0;
365     }
366     return 0;
367 }
368
369 RenderObject* RenderObject::traverseNext(const RenderObject* stayWithin, TraverseNextInclusionFunction inclusionFunction) const
370 {
371     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
372         if (inclusionFunction(child)) {
373             ASSERT(!stayWithin || child->isDescendantOf(stayWithin));
374             return child;
375         }
376     }
377
378     if (this == stayWithin)
379         return 0;
380
381     for (RenderObject* sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) {
382         if (inclusionFunction(sibling)) {
383             ASSERT(!stayWithin || sibling->isDescendantOf(stayWithin));
384             return sibling;
385         }
386     }
387
388     const RenderObject* n = this;
389     while (n) {
390         while (n && !n->nextSibling() && (!stayWithin || n->parent() != stayWithin))
391             n = n->parent();
392         if (n) {
393             for (RenderObject* sibling = n->nextSibling(); sibling; sibling = sibling->nextSibling()) {
394                 if (inclusionFunction(sibling)) {
395                     ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
396                     return sibling;
397                 }
398             }
399             if ((!stayWithin || n->parent() != stayWithin))
400                 n = n->parent();
401             else
402                 return 0;
403         }
404     }
405     return 0;
406 }
407
408 static RenderObject::BlockContentHeightType includeNonFixedHeight(const RenderObject* render)
409 {
410     RenderStyle* style = render->style();
411     if (style) {
412         if (style->height().type() == Fixed) {
413             if (render->isRenderBlock()) {
414                 const RenderBlock* block = toRenderBlock(render);
415                 // For fixed height styles, if the overflow size of the element spills out of the specified
416                 // height, assume we can apply text auto-sizing.
417                 if (style->overflowY() == OVISIBLE && style->height().value() < block->layoutOverflowRect().maxY())
418                     return RenderObject::OverflowHeight;
419             }
420             return RenderObject::FixedHeight;
421         }
422     }
423     return RenderObject::FlexibleHeight;
424 }
425
426
427 void RenderObject::adjustComputedFontSizesOnBlocks(float size, float visibleWidth)
428 {
429     Document* document = view().frameView().frame().document();
430     if (!document)
431         return;
432
433     Vector<int> depthStack;
434     int currentDepth = 0;
435     int newFixedDepth = 0;
436
437     // We don't apply autosizing to nodes with fixed height normally.
438     // But we apply it to nodes which are located deep enough
439     // (nesting depth is greater than some const) inside of a parent block
440     // which has fixed height but its content overflows intentionally.
441     for (RenderObject* descendent = traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth); descendent; descendent = descendent->traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth)) {
442         while (depthStack.size() > 0 && currentDepth <= depthStack[depthStack.size() - 1])
443             depthStack.remove(depthStack.size() - 1);
444         if (newFixedDepth)
445             depthStack.append(newFixedDepth);
446
447         int stackSize = depthStack.size();
448         if (descendent->isRenderBlock() && !descendent->isListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth))
449             static_cast<RenderBlock*>(descendent)->adjustComputedFontSizes(size, visibleWidth);
450         newFixedDepth = 0;
451     }
452
453     // Remove style from auto-sizing table that are no longer valid.
454     document->validateAutoSizingNodes();
455 }
456
457 void RenderObject::resetTextAutosizing()
458 {
459     Document* document = view().frameView().frame().document();
460     if (!document)
461         return;
462
463     document->resetAutoSizingNodes();
464
465     Vector<int> depthStack;
466     int currentDepth = 0;
467     int newFixedDepth = 0;
468
469     for (RenderObject* descendent = traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth); descendent; descendent = descendent->traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth)) {
470         while (depthStack.size() > 0 && currentDepth <= depthStack[depthStack.size() - 1])
471             depthStack.remove(depthStack.size() - 1);
472         if (newFixedDepth)
473             depthStack.append(newFixedDepth);
474
475         int stackSize = depthStack.size();
476         if (descendent->isRenderBlock() && !descendent->isListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth))
477             toRenderBlock(descendent)->resetComputedFontSize();
478         newFixedDepth = 0;
479     }
480 }
481 #endif // ENABLE(IOS_TEXT_AUTOSIZING)
482
483 RenderLayer* RenderObject::enclosingLayer() const
484 {
485     const RenderObject* curr = this;
486     while (curr) {
487         RenderLayer* layer = curr->hasLayer() ? toRenderLayerModelObject(curr)->layer() : 0;
488         if (layer)
489             return layer;
490         curr = curr->parent();
491     }
492     return 0;
493 }
494
495 bool RenderObject::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
496 {
497     RenderLayer* enclosingLayer = this->enclosingLayer();
498     if (!enclosingLayer)
499         return false;
500
501     enclosingLayer->scrollRectToVisible(rect, alignX, alignY);
502     return true;
503 }
504
505 RenderBox* RenderObject::enclosingBox() const
506 {
507     RenderObject* curr = const_cast<RenderObject*>(this);
508     while (curr) {
509         if (curr->isBox())
510             return toRenderBox(curr);
511         curr = curr->parent();
512     }
513     
514     ASSERT_NOT_REACHED();
515     return 0;
516 }
517
518 RenderBoxModelObject* RenderObject::enclosingBoxModelObject() const
519 {
520     RenderObject* curr = const_cast<RenderObject*>(this);
521     while (curr) {
522         if (curr->isBoxModelObject())
523             return toRenderBoxModelObject(curr);
524         curr = curr->parent();
525     }
526
527     ASSERT_NOT_REACHED();
528     return 0;
529 }
530
531 bool RenderObject::fixedPositionedWithNamedFlowContainingBlock() const
532 {
533     return ((flowThreadState() == RenderObject::InsideOutOfFlowThread)
534         && (style().position() == FixedPosition)
535         && (containingBlock()->isOutOfFlowRenderFlowThread()));
536 }
537
538 static bool hasFixedPosInNamedFlowContainingBlock(const RenderObject* renderer)
539 {
540     ASSERT(renderer->flowThreadState() != RenderObject::NotInsideFlowThread);
541
542     RenderObject* curr = const_cast<RenderObject*>(renderer);
543     while (curr) {
544         if (curr->fixedPositionedWithNamedFlowContainingBlock())
545             return true;
546         curr = curr->containingBlock();
547     }
548
549     return false;
550 }
551
552 RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const
553 {
554     ASSERT(flowThreadState() != NotInsideFlowThread);
555
556     // See if we have the thread cached because we're in the middle of layout.
557     RenderFlowThread* flowThread = view().flowThreadController().currentRenderFlowThread();
558     if (flowThread)
559         return flowThread;
560     
561     // Not in the middle of layout so have to find the thread the slow way.
562     RenderObject* curr = const_cast<RenderObject*>(this);
563     while (curr) {
564         if (curr->isRenderFlowThread())
565             return toRenderFlowThread(curr);
566         curr = curr->containingBlock();
567     }
568     return 0;
569 }
570
571 RenderNamedFlowThread* RenderObject::renderNamedFlowThreadWrapper() const
572 {
573     RenderObject* object = const_cast<RenderObject*>(this);
574     while (object && object->isAnonymousBlock() && !object->isRenderNamedFlowThread())
575         object = object->parent();
576
577     return object && object->isRenderNamedFlowThread() ? toRenderNamedFlowThread(object) : 0;
578 }
579
580 RenderBlock* RenderObject::firstLineBlock() const
581 {
582     return 0;
583 }
584
585 static inline bool objectIsRelayoutBoundary(const RenderElement* object)
586 {
587     // FIXME: In future it may be possible to broaden these conditions in order to improve performance.
588     if (object->isRenderView())
589         return true;
590
591     if (object->isTextControl())
592         return true;
593
594 #if ENABLE(SVG)
595     if (object->isSVGRoot())
596         return true;
597 #endif
598
599     if (!object->hasOverflowClip())
600         return false;
601
602     if (object->style().width().isIntrinsicOrAuto() || object->style().height().isIntrinsicOrAuto() || object->style().height().isPercent())
603         return false;
604
605     // Table parts can't be relayout roots since the table is responsible for layouting all the parts.
606     if (object->isTablePart())
607         return false;
608
609     return true;
610 }
611
612 void RenderObject::clearNeedsLayout()
613 {
614     m_bitfields.setNeedsLayout(false);
615     setEverHadLayout(true);
616     setPosChildNeedsLayoutBit(false);
617     setNeedsSimplifiedNormalFlowLayoutBit(false);
618     setNormalChildNeedsLayoutBit(false);
619     setNeedsPositionedMovementLayoutBit(false);
620     if (isRenderElement())
621         toRenderElement(this)->setAncestorLineBoxDirty(false);
622 #ifndef NDEBUG
623     checkBlockPositionedObjectsNeedLayout();
624 #endif
625 }
626
627 static void scheduleRelayoutForSubtree(RenderElement& renderer)
628 {
629     if (!renderer.isRenderView()) {
630         if (!renderer.isRooted())
631             return;
632         renderer.view().frameView().scheduleRelayoutOfSubtree(renderer);
633         return;
634     }
635     toRenderView(renderer).frameView().scheduleRelayout();
636 }
637
638 void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, RenderElement* newRoot)
639 {
640     ASSERT(!scheduleRelayout || !newRoot);
641     ASSERT(!isSetNeedsLayoutForbidden());
642
643     auto ancestor = container();
644
645     bool simplifiedNormalFlowLayout = needsSimplifiedNormalFlowLayout() && !selfNeedsLayout() && !normalChildNeedsLayout();
646     bool hasOutOfFlowPosition = !isText() && style().hasOutOfFlowPosition();
647
648     while (ancestor) {
649 #ifndef NDEBUG
650         // FIXME: Remove this once we remove the special cases for counters, quotes and mathml
651         // calling setNeedsLayout during preferred width computation.
652         SetLayoutNeededForbiddenScope layoutForbiddenScope(ancestor, isSetNeedsLayoutForbidden());
653 #endif
654         // Don't mark the outermost object of an unrooted subtree. That object will be
655         // marked when the subtree is added to the document.
656         auto container = ancestor->container();
657         if (!container && !ancestor->isRenderView())
658             return;
659         if (hasOutOfFlowPosition) {
660             bool willSkipRelativelyPositionedInlines = !ancestor->isRenderBlock() || ancestor->isAnonymousBlock();
661             // Skip relatively positioned inlines and anonymous blocks to get to the enclosing RenderBlock.
662             while (ancestor && (!ancestor->isRenderBlock() || ancestor->isAnonymousBlock()))
663                 ancestor = ancestor->container();
664             if (!ancestor || ancestor->posChildNeedsLayout())
665                 return;
666             if (willSkipRelativelyPositionedInlines)
667                 container = ancestor->container();
668             ancestor->setPosChildNeedsLayoutBit(true);
669             simplifiedNormalFlowLayout = true;
670         } else if (simplifiedNormalFlowLayout) {
671             if (ancestor->needsSimplifiedNormalFlowLayout())
672                 return;
673             ancestor->setNeedsSimplifiedNormalFlowLayoutBit(true);
674         } else {
675             if (ancestor->normalChildNeedsLayout())
676                 return;
677             ancestor->setNormalChildNeedsLayoutBit(true);
678         }
679         ASSERT(!ancestor->isSetNeedsLayoutForbidden());
680
681         if (ancestor == newRoot)
682             return;
683
684         if (scheduleRelayout && objectIsRelayoutBoundary(ancestor))
685             break;
686
687         hasOutOfFlowPosition = ancestor->style().hasOutOfFlowPosition();
688         ancestor = container;
689     }
690
691     if (scheduleRelayout && ancestor)
692         scheduleRelayoutForSubtree(*ancestor);
693 }
694
695 #ifndef NDEBUG
696 void RenderObject::checkBlockPositionedObjectsNeedLayout()
697 {
698     ASSERT(!needsLayout());
699
700     if (isRenderBlock())
701         toRenderBlock(this)->checkPositionedObjectsNeedLayout();
702 }
703 #endif
704
705 void RenderObject::setPreferredLogicalWidthsDirty(bool shouldBeDirty, MarkingBehavior markParents)
706 {
707     bool alreadyDirty = preferredLogicalWidthsDirty();
708     m_bitfields.setPreferredLogicalWidthsDirty(shouldBeDirty);
709     if (shouldBeDirty && !alreadyDirty && markParents == MarkContainingBlockChain && (isText() || !style().hasOutOfFlowPosition()))
710         invalidateContainerPreferredLogicalWidths();
711 }
712
713 void RenderObject::invalidateContainerPreferredLogicalWidths()
714 {
715     // In order to avoid pathological behavior when inlines are deeply nested, we do include them
716     // in the chain that we mark dirty (even though they're kind of irrelevant).
717     auto o = isTableCell() ? containingBlock() : container();
718     while (o && !o->preferredLogicalWidthsDirty()) {
719         // Don't invalidate the outermost object of an unrooted subtree. That object will be 
720         // invalidated when the subtree is added to the document.
721         auto container = o->isTableCell() ? o->containingBlock() : o->container();
722         if (!container && !o->isRenderView())
723             break;
724
725         o->m_bitfields.setPreferredLogicalWidthsDirty(true);
726         if (o->style().hasOutOfFlowPosition())
727             // A positioned object has no effect on the min/max width of its containing block ever.
728             // We can optimize this case and not go up any further.
729             break;
730         o = container;
731     }
732 }
733
734 void RenderObject::setLayerNeedsFullRepaint()
735 {
736     ASSERT(hasLayer());
737     toRenderLayerModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaint);
738 }
739
740 void RenderObject::setLayerNeedsFullRepaintForPositionedMovementLayout()
741 {
742     ASSERT(hasLayer());
743     toRenderLayerModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout);
744 }
745
746 RenderBlock* RenderObject::containingBlock() const
747 {
748     auto o = parent();
749     if (!o && isRenderScrollbarPart())
750         o = toRenderScrollbarPart(this)->rendererOwningScrollbar();
751
752     const RenderStyle& style = this->style();
753     if (!isText() && style.position() == FixedPosition)
754         o = containingBlockForFixedPosition(o);
755     else if (!isText() && style.position() == AbsolutePosition)
756         o = containingBlockForAbsolutePosition(o);
757     else
758         o = containingBlockForObjectInFlow(o);
759
760     if (!o || !o->isRenderBlock())
761         return 0; // This can still happen in case of an orphaned tree
762
763     return toRenderBlock(o);
764 }
765
766 static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* layer)
767 {
768     // Nobody will use multiple layers without wanting fancy positioning.
769     if (layer->next())
770         return true;
771
772     // Make sure we have a valid image.
773     StyleImage* image = layer->image();
774     if (!image || !image->canRender(renderer, renderer->style().effectiveZoom()))
775         return false;
776
777     if (!layer->xPosition().isZero() || !layer->yPosition().isZero())
778         return true;
779
780     EFillSizeType sizeType = layer->sizeType();
781
782     if (sizeType == Contain || sizeType == Cover)
783         return true;
784     
785     if (sizeType == SizeLength) {
786         LengthSize size = layer->sizeLength();
787         if (size.width().isPercent() || size.height().isPercent())
788             return true;
789         // If the image has neither an intrinsic width nor an intrinsic height, its size is determined as for 'contain'.
790         if ((size.width().isAuto() || size.height().isAuto()) && image->isGeneratedImage())
791             return true;
792     } else if (image->usesImageContainerSize())
793         return true;
794
795     return false;
796 }
797
798 bool RenderObject::borderImageIsLoadedAndCanBeRendered() const
799 {
800     ASSERT(style().hasBorder());
801
802     StyleImage* borderImage = style().borderImage().image();
803     return borderImage && borderImage->canRender(toRenderElement(this), style().effectiveZoom()) && borderImage->isLoaded();
804 }
805
806 bool RenderObject::mustRepaintBackgroundOrBorder() const
807 {
808     if (hasMask() && mustRepaintFillLayers(this, style().maskLayers()))
809         return true;
810
811     // If we don't have a background/border/mask, then nothing to do.
812     if (!hasBoxDecorations())
813         return false;
814
815     if (mustRepaintFillLayers(this, style().backgroundLayers()))
816         return true;
817      
818     // Our fill layers are ok.  Let's check border.
819     if (style().hasBorder() && borderImageIsLoadedAndCanBeRendered())
820         return true;
821
822     return false;
823 }
824
825 void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
826     BoxSide side, Color color, EBorderStyle borderStyle, int adjacentWidth1, int adjacentWidth2, bool antialias)
827 {
828     int thickness;
829     int length;
830     if (side == BSTop || side == BSBottom) {
831         thickness = y2 - y1;
832         length = x2 - x1;
833     } else {
834         thickness = x2 - x1;
835         length = y2 - y1;
836     }
837
838     // FIXME: We really would like this check to be an ASSERT as we don't want to draw empty borders. However
839     // nothing guarantees that the following recursive calls to drawLineForBoxSide will have non-null dimensions.
840     if (!thickness || !length)
841         return;
842
843     if (borderStyle == DOUBLE && thickness < 3)
844         borderStyle = SOLID;
845
846     const RenderStyle& style = this->style();
847     switch (borderStyle) {
848         case BNONE:
849         case BHIDDEN:
850             return;
851         case DOTTED:
852         case DASHED: {
853             if (thickness > 0) {
854                 bool wasAntialiased = graphicsContext->shouldAntialias();
855                 StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
856                 graphicsContext->setShouldAntialias(antialias);
857                 graphicsContext->setStrokeColor(color, style.colorSpace());
858                 graphicsContext->setStrokeThickness(thickness);
859                 graphicsContext->setStrokeStyle(borderStyle == DASHED ? DashedStroke : DottedStroke);
860
861                 switch (side) {
862                     case BSBottom:
863                     case BSTop:
864                         graphicsContext->drawLine(IntPoint(x1, (y1 + y2) / 2), IntPoint(x2, (y1 + y2) / 2));
865                         break;
866                     case BSRight:
867                     case BSLeft:
868                         graphicsContext->drawLine(IntPoint((x1 + x2) / 2, y1), IntPoint((x1 + x2) / 2, y2));
869                         break;
870                 }
871                 graphicsContext->setShouldAntialias(wasAntialiased);
872                 graphicsContext->setStrokeStyle(oldStrokeStyle);
873             }
874             break;
875         }
876         case DOUBLE: {
877             int thirdOfThickness = (thickness + 1) / 3;
878             ASSERT(thirdOfThickness);
879
880             if (adjacentWidth1 == 0 && adjacentWidth2 == 0) {
881                 StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
882                 graphicsContext->setStrokeStyle(NoStroke);
883                 graphicsContext->setFillColor(color, style.colorSpace());
884                 
885                 bool wasAntialiased = graphicsContext->shouldAntialias();
886                 graphicsContext->setShouldAntialias(antialias);
887
888                 switch (side) {
889                     case BSTop:
890                     case BSBottom:
891                         graphicsContext->drawRect(IntRect(x1, y1, length, thirdOfThickness));
892                         graphicsContext->drawRect(IntRect(x1, y2 - thirdOfThickness, length, thirdOfThickness));
893                         break;
894                     case BSLeft:
895                     case BSRight:
896                         // FIXME: Why do we offset the border by 1 in this case but not the other one?
897                         if (length > 1) {
898                             graphicsContext->drawRect(IntRect(x1, y1 + 1, thirdOfThickness, length - 1));
899                             graphicsContext->drawRect(IntRect(x2 - thirdOfThickness, y1 + 1, thirdOfThickness, length - 1));
900                         }
901                         break;
902                 }
903
904                 graphicsContext->setShouldAntialias(wasAntialiased);
905                 graphicsContext->setStrokeStyle(oldStrokeStyle);
906             } else {
907                 int adjacent1BigThird = ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 3;
908                 int adjacent2BigThird = ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 3;
909
910                 switch (side) {
911                     case BSTop:
912                         drawLineForBoxSide(graphicsContext, x1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
913                                    y1, x2 - max((-adjacentWidth2 * 2 + 1) / 3, 0), y1 + thirdOfThickness,
914                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
915                         drawLineForBoxSide(graphicsContext, x1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
916                                    y2 - thirdOfThickness, x2 - max((adjacentWidth2 * 2 + 1) / 3, 0), y2,
917                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
918                         break;
919                     case BSLeft:
920                         drawLineForBoxSide(graphicsContext, x1, y1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
921                                    x1 + thirdOfThickness, y2 - max((-adjacentWidth2 * 2 + 1) / 3, 0),
922                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
923                         drawLineForBoxSide(graphicsContext, x2 - thirdOfThickness, y1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
924                                    x2, y2 - max((adjacentWidth2 * 2 + 1) / 3, 0),
925                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
926                         break;
927                     case BSBottom:
928                         drawLineForBoxSide(graphicsContext, x1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
929                                    y1, x2 - max((adjacentWidth2 * 2 + 1) / 3, 0), y1 + thirdOfThickness,
930                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
931                         drawLineForBoxSide(graphicsContext, x1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
932                                    y2 - thirdOfThickness, x2 - max((-adjacentWidth2 * 2 + 1) / 3, 0), y2,
933                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
934                         break;
935                     case BSRight:
936                         drawLineForBoxSide(graphicsContext, x1, y1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
937                                    x1 + thirdOfThickness, y2 - max((adjacentWidth2 * 2 + 1) / 3, 0),
938                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
939                         drawLineForBoxSide(graphicsContext, x2 - thirdOfThickness, y1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
940                                    x2, y2 - max((-adjacentWidth2 * 2 + 1) / 3, 0),
941                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
942                         break;
943                     default:
944                         break;
945                 }
946             }
947             break;
948         }
949         case RIDGE:
950         case GROOVE: {
951             EBorderStyle s1;
952             EBorderStyle s2;
953             if (borderStyle == GROOVE) {
954                 s1 = INSET;
955                 s2 = OUTSET;
956             } else {
957                 s1 = OUTSET;
958                 s2 = INSET;
959             }
960
961             int adjacent1BigHalf = ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 2;
962             int adjacent2BigHalf = ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 2;
963
964             switch (side) {
965                 case BSTop:
966                     drawLineForBoxSide(graphicsContext, x1 + max(-adjacentWidth1, 0) / 2, y1, x2 - max(-adjacentWidth2, 0) / 2, (y1 + y2 + 1) / 2,
967                                side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
968                     drawLineForBoxSide(graphicsContext, x1 + max(adjacentWidth1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(adjacentWidth2 + 1, 0) / 2, y2,
969                                side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
970                     break;
971                 case BSLeft:
972                     drawLineForBoxSide(graphicsContext, x1, y1 + max(-adjacentWidth1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(-adjacentWidth2, 0) / 2,
973                                side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
974                     drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(adjacentWidth1 + 1, 0) / 2, x2, y2 - max(adjacentWidth2 + 1, 0) / 2,
975                                side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
976                     break;
977                 case BSBottom:
978                     drawLineForBoxSide(graphicsContext, x1 + max(adjacentWidth1, 0) / 2, y1, x2 - max(adjacentWidth2, 0) / 2, (y1 + y2 + 1) / 2,
979                                side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
980                     drawLineForBoxSide(graphicsContext, x1 + max(-adjacentWidth1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(-adjacentWidth2 + 1, 0) / 2, y2,
981                                side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
982                     break;
983                 case BSRight:
984                     drawLineForBoxSide(graphicsContext, x1, y1 + max(adjacentWidth1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(adjacentWidth2, 0) / 2,
985                                side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
986                     drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(-adjacentWidth1 + 1, 0) / 2, x2, y2 - max(-adjacentWidth2 + 1, 0) / 2,
987                                side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
988                     break;
989             }
990             break;
991         }
992         case INSET:
993             // FIXME: Maybe we should lighten the colors on one side like Firefox.
994             // https://bugs.webkit.org/show_bug.cgi?id=58608
995             if (side == BSTop || side == BSLeft)
996                 color = color.dark();
997             // fall through
998         case OUTSET:
999             if (borderStyle == OUTSET && (side == BSBottom || side == BSRight))
1000                 color = color.dark();
1001             // fall through
1002         case SOLID: {
1003             StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
1004             graphicsContext->setStrokeStyle(NoStroke);
1005             graphicsContext->setFillColor(color, style.colorSpace());
1006             ASSERT(x2 >= x1);
1007             ASSERT(y2 >= y1);
1008             if (!adjacentWidth1 && !adjacentWidth2) {
1009                 // Turn off antialiasing to match the behavior of drawConvexPolygon();
1010                 // this matters for rects in transformed contexts.
1011                 bool wasAntialiased = graphicsContext->shouldAntialias();
1012                 graphicsContext->setShouldAntialias(antialias);
1013                 graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, y2 - y1));
1014                 graphicsContext->setShouldAntialias(wasAntialiased);
1015                 graphicsContext->setStrokeStyle(oldStrokeStyle);
1016                 return;
1017             }
1018             FloatPoint quad[4];
1019             switch (side) {
1020                 case BSTop:
1021                     quad[0] = FloatPoint(x1 + max(-adjacentWidth1, 0), y1);
1022                     quad[1] = FloatPoint(x1 + max(adjacentWidth1, 0), y2);
1023                     quad[2] = FloatPoint(x2 - max(adjacentWidth2, 0), y2);
1024                     quad[3] = FloatPoint(x2 - max(-adjacentWidth2, 0), y1);
1025                     break;
1026                 case BSBottom:
1027                     quad[0] = FloatPoint(x1 + max(adjacentWidth1, 0), y1);
1028                     quad[1] = FloatPoint(x1 + max(-adjacentWidth1, 0), y2);
1029                     quad[2] = FloatPoint(x2 - max(-adjacentWidth2, 0), y2);
1030                     quad[3] = FloatPoint(x2 - max(adjacentWidth2, 0), y1);
1031                     break;
1032                 case BSLeft:
1033                     quad[0] = FloatPoint(x1, y1 + max(-adjacentWidth1, 0));
1034                     quad[1] = FloatPoint(x1, y2 - max(-adjacentWidth2, 0));
1035                     quad[2] = FloatPoint(x2, y2 - max(adjacentWidth2, 0));
1036                     quad[3] = FloatPoint(x2, y1 + max(adjacentWidth1, 0));
1037                     break;
1038                 case BSRight:
1039                     quad[0] = FloatPoint(x1, y1 + max(adjacentWidth1, 0));
1040                     quad[1] = FloatPoint(x1, y2 - max(adjacentWidth2, 0));
1041                     quad[2] = FloatPoint(x2, y2 - max(-adjacentWidth2, 0));
1042                     quad[3] = FloatPoint(x2, y1 + max(-adjacentWidth1, 0));
1043                     break;
1044             }
1045
1046             graphicsContext->drawConvexPolygon(4, quad, antialias);
1047             graphicsContext->setStrokeStyle(oldStrokeStyle);
1048             break;
1049         }
1050     }
1051 }
1052
1053 void RenderObject::paintFocusRing(PaintInfo& paintInfo, const LayoutPoint& paintOffset, RenderStyle* style)
1054 {
1055     Vector<IntRect> focusRingRects;
1056     addFocusRingRects(focusRingRects, paintOffset, paintInfo.paintContainer);
1057     if (style->outlineStyleIsAuto())
1058         paintInfo.context->drawFocusRing(focusRingRects, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
1059     else
1060         addPDFURLRect(paintInfo.context, unionRect(focusRingRects));
1061 }
1062
1063 void RenderObject::addPDFURLRect(GraphicsContext* context, const LayoutRect& rect)
1064 {
1065     if (rect.isEmpty())
1066         return;
1067     Node* n = node();
1068     if (!n || !n->isLink() || !n->isElementNode())
1069         return;
1070     const AtomicString& href = toElement(n)->getAttribute(hrefAttr);
1071     if (href.isNull())
1072         return;
1073     context->setURLForRect(n->document().completeURL(href), pixelSnappedIntRect(rect));
1074 }
1075
1076 void RenderObject::paintOutline(PaintInfo& paintInfo, const LayoutRect& paintRect)
1077 {
1078     if (!hasOutline())
1079         return;
1080
1081     RenderStyle& styleToUse = style();
1082     LayoutUnit outlineWidth = styleToUse.outlineWidth();
1083
1084     int outlineOffset = styleToUse.outlineOffset();
1085
1086     if (styleToUse.outlineStyleIsAuto() || hasOutlineAnnotation()) {
1087         if (!theme()->supportsFocusRing(&styleToUse)) {
1088             // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
1089             paintFocusRing(paintInfo, paintRect.location(), &styleToUse);
1090         }
1091     }
1092
1093     if (styleToUse.outlineStyleIsAuto() || styleToUse.outlineStyle() == BNONE)
1094         return;
1095
1096     IntRect inner = pixelSnappedIntRect(paintRect);
1097     inner.inflate(outlineOffset);
1098
1099     IntRect outer = pixelSnappedIntRect(inner);
1100     outer.inflate(outlineWidth);
1101
1102     // FIXME: This prevents outlines from painting inside the object. See bug 12042
1103     if (outer.isEmpty())
1104         return;
1105
1106     EBorderStyle outlineStyle = styleToUse.outlineStyle();
1107     Color outlineColor = styleToUse.visitedDependentColor(CSSPropertyOutlineColor);
1108
1109     GraphicsContext* graphicsContext = paintInfo.context;
1110     bool useTransparencyLayer = outlineColor.hasAlpha();
1111     if (useTransparencyLayer) {
1112         if (outlineStyle == SOLID) {
1113             Path path;
1114             path.addRect(outer);
1115             path.addRect(inner);
1116             graphicsContext->setFillRule(RULE_EVENODD);
1117             graphicsContext->setFillColor(outlineColor, styleToUse.colorSpace());
1118             graphicsContext->fillPath(path);
1119             return;
1120         }
1121         graphicsContext->beginTransparencyLayer(static_cast<float>(outlineColor.alpha()) / 255);
1122         outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue());
1123     }
1124
1125     int leftOuter = outer.x();
1126     int leftInner = inner.x();
1127     int rightOuter = outer.maxX();
1128     int rightInner = inner.maxX();
1129     int topOuter = outer.y();
1130     int topInner = inner.y();
1131     int bottomOuter = outer.maxY();
1132     int bottomInner = inner.maxY();
1133     
1134     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, leftInner, bottomOuter, BSLeft, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1135     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, rightOuter, topInner, BSTop, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1136     drawLineForBoxSide(graphicsContext, rightInner, topOuter, rightOuter, bottomOuter, BSRight, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1137     drawLineForBoxSide(graphicsContext, leftOuter, bottomInner, rightOuter, bottomOuter, BSBottom, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1138
1139     if (useTransparencyLayer)
1140         graphicsContext->endTransparencyLayer();
1141 }
1142
1143 IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
1144 {
1145     if (useTransforms) {
1146         Vector<FloatQuad> quads;
1147         absoluteQuads(quads);
1148
1149         size_t n = quads.size();
1150         if (!n)
1151             return IntRect();
1152     
1153         IntRect result = quads[0].enclosingBoundingBox();
1154         for (size_t i = 1; i < n; ++i)
1155             result.unite(quads[i].enclosingBoundingBox());
1156         return result;
1157     }
1158
1159     FloatPoint absPos = localToAbsolute();
1160     Vector<IntRect> rects;
1161     absoluteRects(rects, flooredLayoutPoint(absPos));
1162
1163     size_t n = rects.size();
1164     if (!n)
1165         return IntRect();
1166
1167     LayoutRect result = rects[0];
1168     for (size_t i = 1; i < n; ++i)
1169         result.unite(rects[i]);
1170     return pixelSnappedIntRect(result);
1171 }
1172
1173 void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
1174 {
1175     Vector<IntRect> rects;
1176     // FIXME: addFocusRingRects() needs to be passed this transform-unaware
1177     // localToAbsolute() offset here because RenderInline::addFocusRingRects()
1178     // implicitly assumes that. This doesn't work correctly with transformed
1179     // descendants.
1180     FloatPoint absolutePoint = localToAbsolute();
1181     addFocusRingRects(rects, flooredLayoutPoint(absolutePoint));
1182     size_t count = rects.size();
1183     for (size_t i = 0; i < count; ++i) {
1184         IntRect rect = rects[i];
1185         rect.move(-absolutePoint.x(), -absolutePoint.y());
1186         quads.append(localToAbsoluteQuad(FloatQuad(rect)));
1187     }
1188 }
1189
1190 FloatRect RenderObject::absoluteBoundingBoxRectForRange(const Range* range)
1191 {
1192     if (!range || !range->startContainer())
1193         return FloatRect();
1194
1195     range->ownerDocument().updateLayout();
1196
1197     Vector<FloatQuad> quads;
1198     range->textQuads(quads);
1199
1200     if (quads.isEmpty())
1201         return FloatRect();
1202
1203     FloatRect result = quads[0].boundingBox();
1204     for (size_t i = 1; i < quads.size(); ++i)
1205         result.uniteEvenIfEmpty(quads[i].boundingBox());
1206
1207     return result;
1208 }
1209
1210 void RenderObject::addAbsoluteRectForLayer(LayoutRect& result)
1211 {
1212     if (hasLayer())
1213         result.unite(absoluteBoundingBoxRectIgnoringTransforms());
1214     for (RenderObject* current = firstChildSlow(); current; current = current->nextSibling())
1215         current->addAbsoluteRectForLayer(result);
1216 }
1217
1218 // FIXME: change this to use the subtreePaint terminology
1219 LayoutRect RenderObject::paintingRootRect(LayoutRect& topLevelRect)
1220 {
1221     LayoutRect result = absoluteBoundingBoxRectIgnoringTransforms();
1222     topLevelRect = result;
1223     for (RenderObject* current = firstChildSlow(); current; current = current->nextSibling())
1224         current->addAbsoluteRectForLayer(result);
1225     return result;
1226 }
1227
1228 RenderLayerModelObject* RenderObject::containerForRepaint() const
1229 {
1230     RenderLayerModelObject* repaintContainer = 0;
1231
1232 #if USE(ACCELERATED_COMPOSITING)
1233     if (view().usesCompositing()) {
1234         if (RenderLayer* parentLayer = enclosingLayer()) {
1235             RenderLayer* compLayer = parentLayer->enclosingCompositingLayerForRepaint();
1236             if (compLayer)
1237                 repaintContainer = &compLayer->renderer();
1238         }
1239     }
1240 #endif
1241     
1242 #if ENABLE(CSS_FILTERS)
1243     if (view().hasSoftwareFilters()) {
1244         if (RenderLayer* parentLayer = enclosingLayer()) {
1245             RenderLayer* enclosingFilterLayer = parentLayer->enclosingFilterLayer();
1246             if (enclosingFilterLayer)
1247                 return &enclosingFilterLayer->renderer();
1248         }
1249     }
1250 #endif
1251
1252     // If we have a flow thread, then we need to do individual repaints within the RenderRegions instead.
1253     // Return the flow thread as a repaint container in order to create a chokepoint that allows us to change
1254     // repainting to do individual region repaints.
1255     RenderFlowThread* parentRenderFlowThread = flowThreadContainingBlock();
1256     if (parentRenderFlowThread) {
1257         // If the element has a fixed positioned element with named flow as CB along the CB chain
1258         // then the repaint container is not the flow thread.
1259         if (hasFixedPosInNamedFlowContainingBlock(this))
1260             return repaintContainer;
1261         // The ancestor document will do the reparenting when the repaint propagates further up.
1262         // We're just a seamless child document, and we don't need to do the hacking.
1263         if (parentRenderFlowThread && &parentRenderFlowThread->document() != &document())
1264             return repaintContainer;
1265         // If we have already found a repaint container then we will repaint into that container only if it is part of the same
1266         // flow thread. Otherwise we will need to catch the repaint call and send it to the flow thread.
1267         RenderFlowThread* repaintContainerFlowThread = repaintContainer ? repaintContainer->flowThreadContainingBlock() : 0;
1268         if (!repaintContainerFlowThread || repaintContainerFlowThread != parentRenderFlowThread)
1269             repaintContainer = parentRenderFlowThread;
1270     }
1271     return repaintContainer;
1272 }
1273
1274 void RenderObject::repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const IntRect& r, bool immediate) const
1275 {
1276     if (!repaintContainer) {
1277         view().repaintViewRectangle(r, immediate);
1278         return;
1279     }
1280
1281     if (repaintContainer->isRenderFlowThread()) {
1282         toRenderFlowThread(repaintContainer)->repaintRectangleInRegions(r, immediate);
1283         return;
1284     }
1285
1286 #if ENABLE(CSS_FILTERS)
1287     if (repaintContainer->hasFilter() && repaintContainer->layer() && repaintContainer->layer()->requiresFullLayerImageForFilters()) {
1288         repaintContainer->layer()->setFilterBackendNeedsRepaintingInRect(r, immediate);
1289         return;
1290     }
1291 #endif
1292
1293 #if USE(ACCELERATED_COMPOSITING)
1294     RenderView& v = view();
1295     if (repaintContainer->isRenderView()) {
1296         ASSERT(repaintContainer == &v);
1297         bool viewHasCompositedLayer = v.hasLayer() && v.layer()->isComposited();
1298         if (!viewHasCompositedLayer || v.layer()->backing()->paintsIntoWindow()) {
1299             v.repaintViewRectangle(viewHasCompositedLayer && v.layer()->transform() ? v.layer()->transform()->mapRect(r) : r, immediate);
1300             return;
1301         }
1302     }
1303     
1304     if (v.usesCompositing()) {
1305         ASSERT(repaintContainer->hasLayer() && repaintContainer->layer()->isComposited());
1306         repaintContainer->layer()->setBackingNeedsRepaintInRect(r);
1307     }
1308 #else
1309     if (repaintContainer->isRenderView())
1310         toRenderView(*repaintContainer).repaintViewRectangle(r, immediate);
1311 #endif
1312 }
1313
1314 void RenderObject::repaint(bool immediate) const
1315 {
1316     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1317     RenderView* view;
1318     if (!isRooted(&view))
1319         return;
1320
1321     if (view->printing())
1322         return; // Don't repaint if we're printing.
1323
1324     RenderLayerModelObject* repaintContainer = containerForRepaint();
1325     repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(clippedOverflowRectForRepaint(repaintContainer)), immediate);
1326 }
1327
1328 void RenderObject::repaintRectangle(const LayoutRect& r, bool immediate) const
1329 {
1330     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1331     RenderView* view;
1332     if (!isRooted(&view))
1333         return;
1334
1335     if (view->printing())
1336         return; // Don't repaint if we're printing.
1337
1338     LayoutRect dirtyRect(r);
1339
1340     // FIXME: layoutDelta needs to be applied in parts before/after transforms and
1341     // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
1342     dirtyRect.move(view->layoutDelta());
1343
1344     RenderLayerModelObject* repaintContainer = containerForRepaint();
1345     computeRectForRepaint(repaintContainer, dirtyRect);
1346     repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(dirtyRect), immediate);
1347 }
1348
1349 IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
1350 {
1351     return pixelSnappedIntRect(absoluteClippedOverflowRect());
1352 }
1353
1354 bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr, const LayoutRect* newOutlineBoxRectPtr)
1355 {
1356     if (view().printing())
1357         return false; // Don't repaint if we're printing.
1358
1359     // This ASSERT fails due to animations.  See https://bugs.webkit.org/show_bug.cgi?id=37048
1360     // ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForRepaint(repaintContainer));
1361     LayoutRect newBounds = newBoundsPtr ? *newBoundsPtr : clippedOverflowRectForRepaint(repaintContainer);
1362     LayoutRect newOutlineBox;
1363
1364     bool fullRepaint = selfNeedsLayout();
1365     // Presumably a background or a border exists if border-fit:lines was specified.
1366     if (!fullRepaint && style().borderFit() == BorderFitLines)
1367         fullRepaint = true;
1368     if (!fullRepaint) {
1369         // This ASSERT fails due to animations.  See https://bugs.webkit.org/show_bug.cgi?id=37048
1370         // ASSERT(!newOutlineBoxRectPtr || *newOutlineBoxRectPtr == outlineBoundsForRepaint(repaintContainer));
1371         newOutlineBox = newOutlineBoxRectPtr ? *newOutlineBoxRectPtr : outlineBoundsForRepaint(repaintContainer);
1372         if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
1373             fullRepaint = true;
1374     }
1375
1376     if (!repaintContainer)
1377         repaintContainer = &view();
1378
1379     if (fullRepaint) {
1380         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds));
1381         if (newBounds != oldBounds)
1382             repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds));
1383         return true;
1384     }
1385
1386     if (newBounds == oldBounds && newOutlineBox == oldOutlineBox)
1387         return false;
1388
1389     LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
1390     if (deltaLeft > 0)
1391         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
1392     else if (deltaLeft < 0)
1393         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
1394
1395     LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
1396     if (deltaRight > 0)
1397         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
1398     else if (deltaRight < 0)
1399         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
1400
1401     LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
1402     if (deltaTop > 0)
1403         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
1404     else if (deltaTop < 0)
1405         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
1406
1407     LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
1408     if (deltaBottom > 0)
1409         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
1410     else if (deltaBottom < 0)
1411         repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
1412
1413     if (newOutlineBox == oldOutlineBox)
1414         return false;
1415
1416     // We didn't move, but we did change size. Invalidate the delta, which will consist of possibly
1417     // two rectangles (but typically only one).
1418     const RenderStyle& outlineStyle = outlineStyleForRepaint();
1419     LayoutUnit outlineWidth = outlineStyle.outlineSize();
1420     LayoutBoxExtent insetShadowExtent = style().getBoxShadowInsetExtent();
1421     LayoutUnit width = absoluteValue(newOutlineBox.width() - oldOutlineBox.width());
1422     if (width) {
1423         LayoutUnit shadowLeft;
1424         LayoutUnit shadowRight;
1425         style().getBoxShadowHorizontalExtent(shadowLeft, shadowRight);
1426         int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0;
1427         LayoutUnit boxWidth = isBox() ? toRenderBox(this)->width() : LayoutUnit();
1428         LayoutUnit minInsetRightShadowExtent = min<LayoutUnit>(-insetShadowExtent.right(), min<LayoutUnit>(newBounds.width(), oldBounds.width()));
1429         LayoutUnit borderWidth = max<LayoutUnit>(borderRight, max<LayoutUnit>(valueForLength(style().borderTopRightRadius().width(), boxWidth, &view()), valueForLength(style().borderBottomRightRadius().width(), boxWidth)));
1430         LayoutUnit decorationsWidth = max<LayoutUnit>(-outlineStyle.outlineOffset(), borderWidth + minInsetRightShadowExtent) + max<LayoutUnit>(outlineWidth, shadowRight);
1431         LayoutRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - decorationsWidth,
1432             newOutlineBox.y(),
1433             width + decorationsWidth,
1434             max(newOutlineBox.height(), oldOutlineBox.height()));
1435         LayoutUnit right = min<LayoutUnit>(newBounds.maxX(), oldBounds.maxX());
1436         if (rightRect.x() < right) {
1437             rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
1438             repaintUsingContainer(repaintContainer, pixelSnappedIntRect(rightRect));
1439         }
1440     }
1441     LayoutUnit height = absoluteValue(newOutlineBox.height() - oldOutlineBox.height());
1442     if (height) {
1443         LayoutUnit shadowTop;
1444         LayoutUnit shadowBottom;
1445         style().getBoxShadowVerticalExtent(shadowTop, shadowBottom);
1446         int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0;
1447         LayoutUnit boxHeight = isBox() ? toRenderBox(this)->height() : LayoutUnit();
1448         LayoutUnit minInsetBottomShadowExtent = min<LayoutUnit>(-insetShadowExtent.bottom(), min<LayoutUnit>(newBounds.height(), oldBounds.height()));
1449         LayoutUnit borderHeight = max<LayoutUnit>(borderBottom, max<LayoutUnit>(valueForLength(style().borderBottomLeftRadius().height(), boxHeight), valueForLength(style().borderBottomRightRadius().height(), boxHeight, &view())));
1450         LayoutUnit decorationsHeight = max<LayoutUnit>(-outlineStyle.outlineOffset(), borderHeight + minInsetBottomShadowExtent) + max<LayoutUnit>(outlineWidth, shadowBottom);
1451         LayoutRect bottomRect(newOutlineBox.x(),
1452             min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - decorationsHeight,
1453             max(newOutlineBox.width(), oldOutlineBox.width()),
1454             height + decorationsHeight);
1455         LayoutUnit bottom = min(newBounds.maxY(), oldBounds.maxY());
1456         if (bottomRect.y() < bottom) {
1457             bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
1458             repaintUsingContainer(repaintContainer, pixelSnappedIntRect(bottomRect));
1459         }
1460     }
1461     return false;
1462 }
1463
1464 bool RenderObject::checkForRepaintDuringLayout() const
1465 {
1466     return !document().view()->needsFullRepaint() && !hasLayer() && everHadLayout();
1467 }
1468
1469 LayoutRect RenderObject::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
1470 {
1471     LayoutRect r(clippedOverflowRectForRepaint(repaintContainer));
1472     r.inflate(outlineWidth);
1473     return r;
1474 }
1475
1476 LayoutRect RenderObject::clippedOverflowRectForRepaint(const RenderLayerModelObject*) const
1477 {
1478     ASSERT_NOT_REACHED();
1479     return LayoutRect();
1480 }
1481
1482 void RenderObject::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
1483 {
1484     if (repaintContainer == this)
1485         return;
1486
1487     if (auto o = parent()) {
1488         if (o->isRenderBlockFlow()) {
1489             RenderBlock* cb = toRenderBlock(o);
1490             if (cb->hasColumns())
1491                 cb->adjustRectForColumns(rect);
1492         }
1493
1494         if (o->hasOverflowClip()) {
1495             RenderBox* boxParent = toRenderBox(o);
1496             boxParent->applyCachedClipAndScrollOffsetForRepaint(rect);
1497             if (rect.isEmpty())
1498                 return;
1499         }
1500
1501         o->computeRectForRepaint(repaintContainer, rect, fixed);
1502     }
1503 }
1504
1505 void RenderObject::computeFloatRectForRepaint(const RenderLayerModelObject*, FloatRect&, bool) const
1506 {
1507     ASSERT_NOT_REACHED();
1508 }
1509
1510 #ifndef NDEBUG
1511
1512 void RenderObject::showTreeForThis() const
1513 {
1514     if (node())
1515         node()->showTreeForThis();
1516 }
1517
1518 void RenderObject::showRenderTreeForThis() const
1519 {
1520     showRenderTree(this, 0);
1521 }
1522
1523 void RenderObject::showLineTreeForThis() const
1524 {
1525     if (containingBlock())
1526         containingBlock()->showLineTreeAndMark(0, 0, 0, 0, this);
1527 }
1528
1529 void RenderObject::showRenderObject() const
1530 {
1531     showRenderObject(0);
1532 }
1533
1534 void RenderObject::showRenderObject(int printedCharacters) const
1535 {
1536     // As this function is intended to be used when debugging, the
1537     // this pointer may be 0.
1538     if (!this) {
1539         fputs("(null)\n", stderr);
1540         return;
1541     }
1542
1543     printedCharacters += fprintf(stderr, "%s %p", renderName(), this);
1544
1545     if (node()) {
1546         if (printedCharacters)
1547             for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
1548                 fputc(' ', stderr);
1549         fputc('\t', stderr);
1550         node()->showNode();
1551     } else
1552         fputc('\n', stderr);
1553 }
1554
1555 void RenderObject::showRenderTreeAndMark(const RenderObject* markedObject1, const char* markedLabel1, const RenderObject* markedObject2, const char* markedLabel2, int depth) const
1556 {
1557     int printedCharacters = 0;
1558     if (markedObject1 == this && markedLabel1)
1559         printedCharacters += fprintf(stderr, "%s", markedLabel1);
1560     if (markedObject2 == this && markedLabel2)
1561         printedCharacters += fprintf(stderr, "%s", markedLabel2);
1562     for (; printedCharacters < depth * 2; printedCharacters++)
1563         fputc(' ', stderr);
1564
1565     showRenderObject(printedCharacters);
1566     if (!this)
1567         return;
1568
1569     for (const RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
1570         child->showRenderTreeAndMark(markedObject1, markedLabel1, markedObject2, markedLabel2, depth + 1);
1571 }
1572
1573 #endif // NDEBUG
1574
1575 Color RenderObject::selectionBackgroundColor() const
1576 {
1577     Color color;
1578     if (style().userSelect() != SELECT_NONE) {
1579         if (frame().selection().shouldShowBlockCursor() && frame().selection().isCaret())
1580             color = style().visitedDependentColor(CSSPropertyColor).blendWithWhite();
1581         else {
1582             RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(PseudoStyleRequest(SELECTION));
1583             if (pseudoStyle && pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
1584                 color = pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).blendWithWhite();
1585             else
1586                 color = frame().selection().isFocusedAndActive() ? theme()->activeSelectionBackgroundColor() : theme()->inactiveSelectionBackgroundColor();
1587         }
1588     }
1589
1590     return color;
1591 }
1592
1593 Color RenderObject::selectionColor(int colorProperty) const
1594 {
1595     Color color;
1596     // If the element is unselectable, or we are only painting the selection,
1597     // don't override the foreground color with the selection foreground color.
1598     if (style().userSelect() == SELECT_NONE
1599         || (view().frameView().paintBehavior() & PaintBehaviorSelectionOnly))
1600         return color;
1601
1602     if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(PseudoStyleRequest(SELECTION))) {
1603         color = pseudoStyle->visitedDependentColor(colorProperty);
1604         if (!color.isValid())
1605             color = pseudoStyle->visitedDependentColor(CSSPropertyColor);
1606     } else
1607         color = frame().selection().isFocusedAndActive() ?
1608                 theme()->activeSelectionForegroundColor() :
1609                 theme()->inactiveSelectionForegroundColor();
1610
1611     return color;
1612 }
1613
1614 Color RenderObject::selectionForegroundColor() const
1615 {
1616     return selectionColor(CSSPropertyWebkitTextFillColor);
1617 }
1618
1619 Color RenderObject::selectionEmphasisMarkColor() const
1620 {
1621     return selectionColor(CSSPropertyWebkitTextEmphasisColor);
1622 }
1623
1624 void RenderObject::selectionStartEnd(int& spos, int& epos) const
1625 {
1626     view().selectionStartEnd(spos, epos);
1627 }
1628
1629 void RenderObject::handleDynamicFloatPositionChange()
1630 {
1631     // We have gone from not affecting the inline status of the parent flow to suddenly
1632     // having an impact.  See if there is a mismatch between the parent flow's
1633     // childrenInline() state and our state.
1634     setInline(style().isDisplayInlineType());
1635     if (isInline() != parent()->childrenInline()) {
1636         if (!isInline())
1637             toRenderBoxModelObject(parent())->childBecameNonInline(this);
1638         else {
1639             // An anonymous block must be made to wrap this inline.
1640             RenderBlock* block = toRenderBlock(parent())->createAnonymousBlock();
1641             parent()->insertChildInternal(block, this, RenderElement::NotifyChildren);
1642             parent()->removeChildInternal(*this, RenderElement::NotifyChildren);
1643             block->insertChildInternal(this, nullptr, RenderElement::NotifyChildren);
1644         }
1645     }
1646 }
1647
1648 void RenderObject::removeAnonymousWrappersForInlinesIfNecessary()
1649 {
1650     // We have changed to floated or out-of-flow positioning so maybe all our parent's
1651     // children can be inline now. Bail if there are any block children left on the line,
1652     // otherwise we can proceed to stripping solitary anonymous wrappers from the inlines.
1653     // FIXME: We should also handle split inlines here - we exclude them at the moment by returning
1654     // if we find a continuation.
1655     RenderObject* curr = parent()->firstChild();
1656     while (curr && ((curr->isAnonymousBlock() && !toRenderBlock(curr)->isAnonymousBlockContinuation()) || curr->style().isFloating() || curr->style().hasOutOfFlowPosition()))
1657         curr = curr->nextSibling();
1658
1659     if (curr)
1660         return;
1661
1662     curr = parent()->firstChild();
1663     RenderBlock* parentBlock = toRenderBlock(parent());
1664     while (curr) {
1665         RenderObject* next = curr->nextSibling();
1666         if (curr->isAnonymousBlock())
1667             parentBlock->collapseAnonymousBoxChild(parentBlock, toRenderBlock(curr));
1668         curr = next;
1669     }
1670 }
1671
1672 FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode) const
1673 {
1674     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1675     mapLocalToContainer(0, transformState, mode | ApplyContainerFlip);
1676     transformState.flatten();
1677     
1678     return transformState.lastPlanarPoint();
1679 }
1680
1681 FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, MapCoordinatesFlags mode) const
1682 {
1683     TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
1684     mapAbsoluteToLocalPoint(mode, transformState);
1685     transformState.flatten();
1686     
1687     return transformState.lastPlanarPoint();
1688 }
1689
1690 FloatQuad RenderObject::absoluteToLocalQuad(const FloatQuad& quad, MapCoordinatesFlags mode) const
1691 {
1692     TransformState transformState(TransformState::UnapplyInverseTransformDirection, quad.boundingBox().center(), quad);
1693     mapAbsoluteToLocalPoint(mode, transformState);
1694     transformState.flatten();
1695     return transformState.lastPlanarQuad();
1696 }
1697
1698 void RenderObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
1699 {
1700     if (repaintContainer == this)
1701         return;
1702
1703     auto o = parent();
1704     if (!o)
1705         return;
1706
1707     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
1708     LayoutPoint centerPoint = roundedLayoutPoint(transformState.mappedPoint());
1709     if (mode & ApplyContainerFlip && o->isBox()) {
1710         if (o->style().isFlippedBlocksWritingMode())
1711             transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(roundedLayoutPoint(transformState.mappedPoint())) - centerPoint);
1712         mode &= ~ApplyContainerFlip;
1713     }
1714
1715     LayoutSize columnOffset;
1716     o->adjustForColumns(columnOffset, roundedLayoutPoint(transformState.mappedPoint()));
1717     if (!columnOffset.isZero())
1718         transformState.move(columnOffset);
1719
1720     if (o->hasOverflowClip())
1721         transformState.move(-toRenderBox(o)->scrolledContentOffset());
1722
1723     o->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed);
1724 }
1725
1726 const RenderObject* RenderObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
1727 {
1728     ASSERT_UNUSED(ancestorToStopAt, ancestorToStopAt != this);
1729
1730     auto container = parent();
1731     if (!container)
1732         return 0;
1733
1734     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
1735     LayoutSize offset;
1736     if (container->hasOverflowClip())
1737         offset = -toRenderBox(container)->scrolledContentOffset();
1738
1739     geometryMap.push(this, offset, hasColumns());
1740     
1741     return container;
1742 }
1743
1744 void RenderObject::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
1745 {
1746     auto o = parent();
1747     if (o) {
1748         o->mapAbsoluteToLocalPoint(mode, transformState);
1749         if (o->hasOverflowClip())
1750             transformState.move(toRenderBox(o)->scrolledContentOffset());
1751     }
1752 }
1753
1754 bool RenderObject::shouldUseTransformFromContainer(const RenderObject* containerObject) const
1755 {
1756 #if ENABLE(3D_RENDERING)
1757     // hasTransform() indicates whether the object has transform, transform-style or perspective. We just care about transform,
1758     // so check the layer's transform directly.
1759     return (hasLayer() && toRenderLayerModelObject(this)->layer()->transform()) || (containerObject && containerObject->style().hasPerspective());
1760 #else
1761     UNUSED_PARAM(containerObject);
1762     return hasTransform();
1763 #endif
1764 }
1765
1766 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
1767 {
1768     transform.makeIdentity();
1769     transform.translate(offsetInContainer.width(), offsetInContainer.height());
1770     RenderLayer* layer;
1771     if (hasLayer() && (layer = toRenderLayerModelObject(this)->layer()) && layer->transform())
1772         transform.multiply(layer->currentTransform());
1773     
1774 #if ENABLE(3D_RENDERING)
1775     if (containerObject && containerObject->hasLayer() && containerObject->style().hasPerspective()) {
1776         // Perpsective on the container affects us, so we have to factor it in here.
1777         ASSERT(containerObject->hasLayer());
1778         FloatPoint perspectiveOrigin = toRenderLayerModelObject(containerObject)->layer()->perspectiveOrigin();
1779
1780         TransformationMatrix perspectiveMatrix;
1781         perspectiveMatrix.applyPerspective(containerObject->style().perspective());
1782         
1783         transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
1784         transform = perspectiveMatrix * transform;
1785         transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
1786     }
1787 #else
1788     UNUSED_PARAM(containerObject);
1789 #endif
1790 }
1791
1792 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
1793 {
1794     // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
1795     // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
1796     TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
1797     mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
1798     transformState.flatten();
1799     
1800     return transformState.lastPlanarQuad();
1801 }
1802
1803 FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
1804 {
1805     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1806     mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
1807     transformState.flatten();
1808
1809     return transformState.lastPlanarPoint();
1810 }
1811
1812 LayoutSize RenderObject::offsetFromContainer(RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
1813 {
1814     ASSERT(o == container());
1815
1816     LayoutSize offset;
1817
1818     o->adjustForColumns(offset, point);
1819
1820     if (o->hasOverflowClip())
1821         offset -= toRenderBox(o)->scrolledContentOffset();
1822
1823     if (offsetDependsOnPoint)
1824         *offsetDependsOnPoint = hasColumns() || o->isRenderFlowThread();
1825
1826     return offset;
1827 }
1828
1829 LayoutSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
1830 {
1831     LayoutSize offset;
1832     LayoutPoint referencePoint;
1833     const RenderObject* currContainer = this;
1834     do {
1835         auto nextContainer = currContainer->container();
1836         ASSERT(nextContainer);  // This means we reached the top without finding container.
1837         if (!nextContainer)
1838             break;
1839         ASSERT(!currContainer->hasTransform());
1840         LayoutSize currentOffset = currContainer->offsetFromContainer(nextContainer, referencePoint);
1841         offset += currentOffset;
1842         referencePoint.move(currentOffset);
1843         currContainer = nextContainer;
1844     } while (currContainer != container);
1845
1846     return offset;
1847 }
1848
1849 LayoutRect RenderObject::localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine)
1850 {
1851     if (extraWidthToEndOfLine)
1852         *extraWidthToEndOfLine = 0;
1853
1854     return LayoutRect();
1855 }
1856
1857 bool RenderObject::isRooted(RenderView** view) const
1858 {
1859     const RenderObject* o = this;
1860     while (o->parent())
1861         o = o->parent();
1862
1863     if (!o->isRenderView())
1864         return false;
1865
1866     if (view)
1867         *view = &const_cast<RenderView&>(toRenderView(*o));
1868
1869     return true;
1870 }
1871
1872 RespectImageOrientationEnum RenderObject::shouldRespectImageOrientation() const
1873 {
1874 #if USE(CG) || USE(CAIRO) || PLATFORM(BLACKBERRY)
1875     // This can only be enabled for ports which honor the orientation flag in their drawing code.
1876     if (document().isImageDocument())
1877         return RespectImageOrientation;
1878 #endif
1879     // Respect the image's orientation if it's being used as a full-page image or it's
1880     // an <img> and the setting to respect it everywhere is set.
1881     return (frame().settings().shouldRespectImageOrientation() && node() && isHTMLImageElement(node())) ? RespectImageOrientation : DoNotRespectImageOrientation;
1882 }
1883
1884 bool RenderObject::hasOutlineAnnotation() const
1885 {
1886     return node() && node()->isLink() && document().printing();
1887 }
1888
1889 bool RenderObject::hasEntirelyFixedBackground() const
1890 {
1891     return style().hasEntirelyFixedBackground();
1892 }
1893
1894 RenderElement* RenderObject::container(const RenderLayerModelObject* repaintContainer, bool* repaintContainerSkipped) const
1895 {
1896     if (repaintContainerSkipped)
1897         *repaintContainerSkipped = false;
1898
1899     // This method is extremely similar to containingBlock(), but with a few notable
1900     // exceptions.
1901     // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when
1902     // the object is not part of the primary document subtree yet.
1903     // (2) For normal flow elements, it just returns the parent.
1904     // (3) For absolute positioned elements, it will return a relative positioned inline.
1905     // containingBlock() simply skips relpositioned inlines and lets an enclosing block handle
1906     // the layout of the positioned object.  This does mean that computePositionedLogicalWidth and
1907     // computePositionedLogicalHeight have to use container().
1908     auto o = parent();
1909
1910     if (isText())
1911         return o;
1912
1913     EPosition pos = style().position();
1914     if (pos == FixedPosition) {
1915         // container() can be called on an object that is not in the
1916         // tree yet.  We don't call view() since it will assert if it
1917         // can't get back to the canvas.  Instead we just walk as high up
1918         // as we can.  If we're in the tree, we'll get the root.  If we
1919         // aren't we'll get the root of our little subtree (most likely
1920         // we'll just return 0).
1921         // FIXME: The definition of view() has changed to not crawl up the render tree.  It might
1922         // be safe now to use it.
1923         while (o && o->parent() && !(o->hasTransform() && o->isRenderBlock())) {
1924 #if ENABLE(SVG)
1925             // foreignObject is the containing block for its contents.
1926             if (o->isSVGForeignObject())
1927                 break;
1928 #endif
1929             // The render flow thread is the top most containing block
1930             // for the fixed positioned elements.
1931             if (o->isOutOfFlowRenderFlowThread())
1932                 break;
1933
1934             if (repaintContainerSkipped && o == repaintContainer)
1935                 *repaintContainerSkipped = true;
1936
1937             o = o->parent();
1938         }
1939     } else if (pos == AbsolutePosition) {
1940         // Same goes here.  We technically just want our containing block, but
1941         // we may not have one if we're part of an uninstalled subtree.  We'll
1942         // climb as high as we can though.
1943         while (o && o->style().position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
1944 #if ENABLE(SVG)
1945             if (o->isSVGForeignObject()) // foreignObject is the containing block for contents inside it
1946                 break;
1947 #endif
1948             if (repaintContainerSkipped && o == repaintContainer)
1949                 *repaintContainerSkipped = true;
1950
1951             o = o->parent();
1952         }
1953     }
1954
1955     return o;
1956 }
1957
1958 bool RenderObject::isSelectionBorder() const
1959 {
1960     SelectionState st = selectionState();
1961     return st == SelectionStart || st == SelectionEnd || st == SelectionBoth;
1962 }
1963
1964 inline void RenderObject::clearLayoutRootIfNeeded() const
1965 {
1966     if (documentBeingDestroyed())
1967         return;
1968
1969     if (view().frameView().layoutRoot() == this) {
1970         ASSERT_NOT_REACHED();
1971         // This indicates a failure to layout the child, which is why
1972         // the layout root is still set to |this|. Make sure to clear it
1973         // since we are getting destroyed.
1974         view().frameView().clearLayoutRoot();
1975     }
1976 }
1977
1978 void RenderObject::willBeDestroyed()
1979 {
1980     // If this renderer is being autoscrolled, stop the autoscroll timer
1981     
1982     // FIXME: RenderObject::destroy should not get called with a renderer whose document
1983     // has a null frame, so we assert this. However, we don't want release builds to crash which is why we
1984     // check that the frame is not null.
1985     if (frame().eventHandler().autoscrollRenderer() == this)
1986         frame().eventHandler().stopAutoscrollTimer(true);
1987
1988     // For accessibility management, notify the parent of the imminent change to its child set.
1989     // We do it now, before remove(), while the parent pointer is still available.
1990     if (AXObjectCache* cache = document().existingAXObjectCache())
1991         cache->childrenChanged(this->parent());
1992
1993     removeFromParent();
1994
1995     ASSERT(documentBeingDestroyed() || !isRenderElement() || !view().frameView().hasSlowRepaintObject(toRenderElement(this)));
1996
1997     // The remove() call above may invoke axObjectCache()->childrenChanged() on the parent, which may require the AX render
1998     // object for this renderer. So we remove the AX render object now, after the renderer is removed.
1999     if (AXObjectCache* cache = document().existingAXObjectCache())
2000         cache->remove(this);
2001
2002 #ifndef NDEBUG
2003     if (!documentBeingDestroyed() && view().hasRenderNamedFlowThreads()) {
2004         // After remove, the object and the associated information should not be in any flow thread.
2005         const RenderNamedFlowThreadList* flowThreadList = view().flowThreadController().renderNamedFlowThreadList();
2006         for (RenderNamedFlowThreadList::const_iterator iter = flowThreadList->begin(); iter != flowThreadList->end(); ++iter) {
2007             const RenderNamedFlowThread* renderFlowThread = *iter;
2008             ASSERT(!renderFlowThread->hasChild(this));
2009             ASSERT(!renderFlowThread->hasChildInfo(this));
2010         }
2011     }
2012 #endif
2013
2014     // If this renderer had a parent, remove should have destroyed any counters
2015     // attached to this renderer and marked the affected other counters for
2016     // reevaluation. This apparently redundant check is here for the case when
2017     // this renderer had no parent at the time remove() was called.
2018
2019     if (hasCounterNodeMap())
2020         RenderCounter::destroyCounterNodes(this);
2021
2022     // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
2023     // be moved into RenderBoxModelObject::destroy.
2024     if (hasLayer()) {
2025         setHasLayer(false);
2026         toRenderLayerModelObject(this)->destroyLayer();
2027     }
2028
2029     clearLayoutRootIfNeeded();
2030 }
2031
2032 void RenderObject::insertedIntoTree()
2033 {
2034     // FIXME: We should ASSERT(isRooted()) here but generated content makes some out-of-order insertion.
2035
2036     if (!isFloating() && parent()->childrenInline())
2037         parent()->dirtyLinesFromChangedChild(this);
2038
2039     if (RenderNamedFlowThread* containerFlowThread = parent()->renderNamedFlowThreadWrapper())
2040         containerFlowThread->addFlowChild(this);
2041 }
2042
2043 void RenderObject::willBeRemovedFromTree()
2044 {
2045     // FIXME: We should ASSERT(isRooted()) but we have some out-of-order removals which would need to be fixed first.
2046
2047     removeFromRenderFlowThread();
2048
2049     if (RenderNamedFlowThread* containerFlowThread = parent()->renderNamedFlowThreadWrapper())
2050         containerFlowThread->removeFlowChild(this);
2051
2052 #if ENABLE(SVG)
2053     // Update cached boundaries in SVG renderers, if a child is removed.
2054     parent()->setNeedsBoundariesUpdate();
2055 #endif
2056 }
2057
2058 void RenderObject::removeFromRenderFlowThread()
2059 {
2060     if (flowThreadState() == NotInsideFlowThread)
2061         return;
2062     
2063     // Sometimes we remove the element from the flow, but it's not destroyed at that time.
2064     // It's only until later when we actually destroy it and remove all the children from it. 
2065     // Currently, that happens for firstLetter elements and list markers.
2066     // Pass in the flow thread so that we don't have to look it up for all the children.
2067     removeFromRenderFlowThreadRecursive(flowThreadContainingBlock());
2068 }
2069
2070 void RenderObject::removeFromRenderFlowThreadRecursive(RenderFlowThread* renderFlowThread)
2071 {
2072     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
2073         child->removeFromRenderFlowThreadRecursive(renderFlowThread);
2074
2075     RenderFlowThread* localFlowThread = renderFlowThread;
2076     if (flowThreadState() == InsideInFlowThread)
2077         localFlowThread = flowThreadContainingBlock(); // We have to ask. We can't just assume we are in the same flow thread.
2078     if (localFlowThread)
2079         localFlowThread->removeFlowChildInfo(this);
2080     setFlowThreadState(NotInsideFlowThread);
2081 }
2082
2083 void RenderObject::destroyAndCleanupAnonymousWrappers()
2084 {
2085     // If the tree is destroyed, there is no need for a clean-up phase.
2086     if (documentBeingDestroyed()) {
2087         destroy();
2088         return;
2089     }
2090
2091     RenderObject* destroyRoot = this;
2092     for (auto destroyRootParent = destroyRoot->parent(); destroyRootParent && destroyRootParent->isAnonymous(); destroyRoot = destroyRootParent, destroyRootParent = destroyRootParent->parent()) {
2093         // Currently we only remove anonymous cells' and table sections' wrappers but we should remove all unneeded
2094         // wrappers. See http://webkit.org/b/52123 as an example where this is needed.
2095         if (!destroyRootParent->isTableCell() && !destroyRootParent->isTableSection())
2096             break;
2097
2098         if (destroyRootParent->firstChild() != this || destroyRootParent->lastChild() != this)
2099             break;
2100     }
2101
2102     destroyRoot->destroy();
2103
2104     // WARNING: |this| is deleted here.
2105 }
2106
2107 void RenderObject::destroy()
2108 {
2109     willBeDestroyed();
2110     delete this;
2111 }
2112
2113 VisiblePosition RenderObject::positionForPoint(const LayoutPoint&)
2114 {
2115     return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
2116 }
2117
2118 void RenderObject::updateDragState(bool dragOn)
2119 {
2120     bool valueChanged = (dragOn != isDragging());
2121     setIsDragging(dragOn);
2122     if (valueChanged && node() && (style().affectedByDrag() || (node()->isElementNode() && toElement(node())->childrenAffectedByDrag())))
2123         node()->setNeedsStyleRecalc();
2124     for (RenderObject* curr = firstChildSlow(); curr; curr = curr->nextSibling())
2125         curr->updateDragState(dragOn);
2126 }
2127
2128 bool RenderObject::isComposited() const
2129 {
2130     return hasLayer() && toRenderLayerModelObject(this)->layer()->isComposited();
2131 }
2132
2133 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
2134 {
2135     bool inside = false;
2136     if (hitTestFilter != HitTestSelf) {
2137         // First test the foreground layer (lines and inlines).
2138         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestForeground);
2139
2140         // Test floats next.
2141         if (!inside)
2142             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestFloat);
2143
2144         // Finally test to see if the mouse is in the background (within a child block's background).
2145         if (!inside)
2146             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestChildBlockBackgrounds);
2147     }
2148
2149     // See if the mouse is inside us but not any of our descendants
2150     if (hitTestFilter != HitTestDescendants && !inside)
2151         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestBlockBackground);
2152
2153     return inside;
2154 }
2155
2156 void RenderObject::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
2157 {
2158     if (result.innerNode())
2159         return;
2160
2161     Node* node = this->node();
2162
2163     // If we hit the anonymous renderers inside generated content we should
2164     // actually hit the generated content so walk up to the PseudoElement.
2165     if (!node && parent() && parent()->isBeforeOrAfterContent()) {
2166         for (auto renderer = parent(); renderer && !node; renderer = renderer->parent())
2167             node = renderer->element();
2168     }
2169
2170     if (node) {
2171         result.setInnerNode(node);
2172         if (!result.innerNonSharedNode())
2173             result.setInnerNonSharedNode(node);
2174         result.setLocalPoint(point);
2175     }
2176 }
2177
2178 bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& /*locationInContainer*/, const LayoutPoint& /*accumulatedOffset*/, HitTestAction)
2179 {
2180     return false;
2181 }
2182
2183 RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
2184 {
2185     if (pseudo < FIRST_INTERNAL_PSEUDOID && !style().hasPseudoStyle(pseudo))
2186         return 0;
2187
2188     RenderStyle* cachedStyle = style().getCachedPseudoStyle(pseudo);
2189     if (cachedStyle)
2190         return cachedStyle;
2191     
2192     RefPtr<RenderStyle> result = getUncachedPseudoStyle(PseudoStyleRequest(pseudo), parentStyle);
2193     if (result)
2194         return style().addCachedPseudoStyle(result.release());
2195     return 0;
2196 }
2197
2198 PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, RenderStyle* ownStyle) const
2199 {
2200     if (pseudoStyleRequest.pseudoId < FIRST_INTERNAL_PSEUDOID && !ownStyle && !style().hasPseudoStyle(pseudoStyleRequest.pseudoId))
2201         return 0;
2202     
2203     if (!parentStyle) {
2204         ASSERT(!ownStyle);
2205         parentStyle = &style();
2206     }
2207
2208     // FIXME: This "find nearest element parent" should be a helper function.
2209     Node* n = node();
2210     while (n && !n->isElementNode())
2211         n = n->parentNode();
2212     if (!n)
2213         return 0;
2214     Element* element = toElement(n);
2215
2216     if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) {
2217         RefPtr<RenderStyle> result = document().ensureStyleResolver().styleForElement(element, parentStyle, DisallowStyleSharing);
2218         result->setStyleType(FIRST_LINE_INHERITED);
2219         return result.release();
2220     }
2221
2222     return document().ensureStyleResolver().pseudoStyleForElement(element, pseudoStyleRequest, parentStyle);
2223 }
2224
2225 static Color decorationColor(RenderStyle* style)
2226 {
2227     Color result;
2228 #if ENABLE(CSS3_TEXT_DECORATION)
2229     // Check for text decoration color first.
2230     result = style->visitedDependentColor(CSSPropertyWebkitTextDecorationColor);
2231     if (result.isValid())
2232         return result;
2233 #endif // CSS3_TEXT_DECORATION
2234     if (style->textStrokeWidth() > 0) {
2235         // Prefer stroke color if possible but not if it's fully transparent.
2236         result = style->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
2237         if (result.alpha())
2238             return result;
2239     }
2240     
2241     result = style->visitedDependentColor(CSSPropertyWebkitTextFillColor);
2242     return result;
2243 }
2244
2245 void RenderObject::getTextDecorationColors(int decorations, Color& underline, Color& overline,
2246                                            Color& linethrough, bool quirksMode, bool firstlineStyle)
2247 {
2248     RenderObject* curr = this;
2249     RenderStyle* styleToUse = 0;
2250     TextDecoration currDecs = TextDecorationNone;
2251     Color resultColor;
2252     do {
2253         styleToUse = firstlineStyle ? &curr->firstLineStyle() : &curr->style();
2254         currDecs = styleToUse->textDecoration();
2255         resultColor = decorationColor(styleToUse);
2256         // Parameter 'decorations' is cast as an int to enable the bitwise operations below.
2257         if (currDecs) {
2258             if (currDecs & TextDecorationUnderline) {
2259                 decorations &= ~TextDecorationUnderline;
2260                 underline = resultColor;
2261             }
2262             if (currDecs & TextDecorationOverline) {
2263                 decorations &= ~TextDecorationOverline;
2264                 overline = resultColor;
2265             }
2266             if (currDecs & TextDecorationLineThrough) {
2267                 decorations &= ~TextDecorationLineThrough;
2268                 linethrough = resultColor;
2269             }
2270         }
2271         if (curr->isRubyText())
2272             return;
2273         curr = curr->parent();
2274         if (curr && curr->isAnonymousBlock() && toRenderBlock(curr)->continuation())
2275             curr = toRenderBlock(curr)->continuation();
2276     } while (curr && decorations && (!quirksMode || !curr->node() || (!isHTMLAnchorElement(curr->node()) && !curr->node()->hasTagName(fontTag))));
2277
2278     // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
2279     if (decorations && curr) {
2280         styleToUse = firstlineStyle ? &curr->firstLineStyle() : &curr->style();
2281         resultColor = decorationColor(styleToUse);
2282         if (decorations & TextDecorationUnderline)
2283             underline = resultColor;
2284         if (decorations & TextDecorationOverline)
2285             overline = resultColor;
2286         if (decorations & TextDecorationLineThrough)
2287             linethrough = resultColor;
2288     }
2289 }
2290
2291 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
2292 void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
2293 {
2294     // Convert the style regions to absolute coordinates.
2295     if (style().visibility() != VISIBLE || !isBox())
2296         return;
2297     
2298     RenderBox* box = toRenderBox(this);
2299     FloatPoint absPos = localToAbsolute();
2300
2301 #if ENABLE(DASHBOARD_SUPPORT)
2302     const Vector<StyleDashboardRegion>& styleRegions = style().dashboardRegions();
2303     unsigned i, count = styleRegions.size();
2304     for (i = 0; i < count; i++) {
2305         StyleDashboardRegion styleRegion = styleRegions[i];
2306
2307         LayoutUnit w = box->width();
2308         LayoutUnit h = box->height();
2309
2310         AnnotatedRegionValue region;
2311         region.label = styleRegion.label;
2312         region.bounds = LayoutRect(styleRegion.offset.left().value(),
2313                                    styleRegion.offset.top().value(),
2314                                    w - styleRegion.offset.left().value() - styleRegion.offset.right().value(),
2315                                    h - styleRegion.offset.top().value() - styleRegion.offset.bottom().value());
2316         region.type = styleRegion.type;
2317
2318         region.clip = region.bounds;
2319         computeAbsoluteRepaintRect(region.clip);
2320         if (region.clip.height() < 0) {
2321             region.clip.setHeight(0);
2322             region.clip.setWidth(0);
2323         }
2324
2325         region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
2326         region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
2327
2328         regions.append(region);
2329     }
2330 #else // ENABLE(DRAGGABLE_REGION)
2331     if (style().getDraggableRegionMode() == DraggableRegionNone)
2332         return;
2333     AnnotatedRegionValue region;
2334     region.draggable = style().getDraggableRegionMode() == DraggableRegionDrag;
2335     region.bounds = LayoutRect(absPos.x(), absPos.y(), box->width(), box->height());
2336     regions.append(region);
2337 #endif
2338 }
2339
2340 void RenderObject::collectAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
2341 {
2342     // RenderTexts don't have their own style, they just use their parent's style,
2343     // so we don't want to include them.
2344     if (isText())
2345         return;
2346
2347     addAnnotatedRegions(regions);
2348     for (RenderObject* curr = toRenderElement(this)->firstChild(); curr; curr = curr->nextSibling())
2349         curr->collectAnnotatedRegions(regions);
2350 }
2351 #endif
2352
2353 bool RenderObject::willRenderImage(CachedImage*)
2354 {
2355     // Without visibility we won't render (and therefore don't care about animation).
2356     if (style().visibility() != VISIBLE)
2357         return false;
2358
2359     // We will not render a new image when Active DOM is suspended
2360     if (document().activeDOMObjectsAreSuspended())
2361         return false;
2362
2363     // If we're not in a window (i.e., we're dormant from being put in the b/f cache or in a background tab)
2364     // then we don't want to render either.
2365     return !document().inPageCache() && !document().view()->isOffscreen();
2366 }
2367
2368 int RenderObject::maximalOutlineSize(PaintPhase p) const
2369 {
2370     if (p != PaintPhaseOutline && p != PaintPhaseSelfOutline && p != PaintPhaseChildOutlines)
2371         return 0;
2372     return view().maximalOutlineSize();
2373 }
2374
2375 int RenderObject::caretMinOffset() const
2376 {
2377     return 0;
2378 }
2379
2380 int RenderObject::caretMaxOffset() const
2381 {
2382     if (isReplaced())
2383         return node() ? max(1U, node()->childNodeCount()) : 1;
2384     if (isHR())
2385         return 1;
2386     return 0;
2387 }
2388
2389 int RenderObject::previousOffset(int current) const
2390 {
2391     return current - 1;
2392 }
2393
2394 int RenderObject::previousOffsetForBackwardDeletion(int current) const
2395 {
2396     return current - 1;
2397 }
2398
2399 int RenderObject::nextOffset(int current) const
2400 {
2401     return current + 1;
2402 }
2403
2404 void RenderObject::adjustRectForOutlineAndShadow(LayoutRect& rect) const
2405 {
2406     int outlineSize = outlineStyleForRepaint().outlineSize();
2407     if (const ShadowData* boxShadow = style().boxShadow()) {
2408         boxShadow->adjustRectForShadow(rect, outlineSize);
2409         return;
2410     }
2411
2412     rect.inflate(outlineSize);
2413 }
2414
2415 AnimationController& RenderObject::animation() const
2416 {
2417     return frame().animation();
2418 }
2419
2420 void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
2421 {
2422     imageChanged(static_cast<WrappedImagePtr>(image), rect);
2423 }
2424
2425 RenderBoxModelObject* RenderObject::offsetParent() const
2426 {
2427     // If any of the following holds true return null and stop this algorithm:
2428     // A is the root element.
2429     // A is the HTML body element.
2430     // The computed value of the position property for element A is fixed.
2431     if (isRoot() || isBody() || (isOutOfFlowPositioned() && style().position() == FixedPosition))
2432         return 0;
2433
2434     // If A is an area HTML element which has a map HTML element somewhere in the ancestor
2435     // chain return the nearest ancestor map HTML element and stop this algorithm.
2436     // FIXME: Implement!
2437     
2438     // Return the nearest ancestor element of A for which at least one of the following is
2439     // true and stop this algorithm if such an ancestor is found:
2440     //     * The computed value of the position property is not static.
2441     //     * It is the HTML body element.
2442     //     * The computed value of the position property of A is static and the ancestor
2443     //       is one of the following HTML elements: td, th, or table.
2444     //     * Our own extension: if there is a difference in the effective zoom
2445
2446     bool skipTables = isPositioned();
2447     float currZoom = style().effectiveZoom();
2448     auto curr = parent();
2449     while (curr && (!curr->element() || (!curr->isPositioned() && !curr->isBody())) && !curr->isRenderNamedFlowThread()) {
2450         Element* element = curr->element();
2451         if (!skipTables && element && (isHTMLTableElement(element) || element->hasTagName(tdTag) || element->hasTagName(thTag)))
2452             break;
2453  
2454         float newZoom = curr->style().effectiveZoom();
2455         if (currZoom != newZoom)
2456             break;
2457         currZoom = newZoom;
2458         curr = curr->parent();
2459     }
2460     
2461     // CSS regions specification says that region flows should return the body element as their offsetParent.
2462     if (curr && curr->isRenderNamedFlowThread())
2463         curr = document().body() ? document().body()->renderer() : 0;
2464     
2465     return curr && curr->isBoxModelObject() ? toRenderBoxModelObject(curr) : 0;
2466 }
2467
2468 VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity) const
2469 {
2470     // If this is a non-anonymous renderer in an editable area, then it's simple.
2471     if (Node* node = nonPseudoNode()) {
2472         if (!node->rendererIsEditable()) {
2473             // If it can be found, we prefer a visually equivalent position that is editable. 
2474             Position position = createLegacyEditingPosition(node, offset);
2475             Position candidate = position.downstream(CanCrossEditingBoundary);
2476             if (candidate.deprecatedNode()->rendererIsEditable())
2477                 return VisiblePosition(candidate, affinity);
2478             candidate = position.upstream(CanCrossEditingBoundary);
2479             if (candidate.deprecatedNode()->rendererIsEditable())
2480                 return VisiblePosition(candidate, affinity);
2481         }
2482         // FIXME: Eliminate legacy editing positions
2483         return VisiblePosition(createLegacyEditingPosition(node, offset), affinity);
2484     }
2485
2486     // We don't want to cross the boundary between editable and non-editable
2487     // regions of the document, but that is either impossible or at least
2488     // extremely unlikely in any normal case because we stop as soon as we
2489     // find a single non-anonymous renderer.
2490
2491     // Find a nearby non-anonymous renderer.
2492     const RenderObject* child = this;
2493     while (const auto parent = child->parent()) {
2494         // Find non-anonymous content after.
2495         const RenderObject* renderer = child;
2496         while ((renderer = renderer->nextInPreOrder(parent))) {
2497             if (Node* node = renderer->nonPseudoNode())
2498                 return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
2499         }
2500
2501         // Find non-anonymous content before.
2502         renderer = child;
2503         while ((renderer = renderer->previousInPreOrder())) {
2504             if (renderer == parent)
2505                 break;
2506             if (Node* node = renderer->nonPseudoNode())
2507                 return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
2508         }
2509
2510         // Use the parent itself unless it too is anonymous.
2511         if (Element* element = parent->nonPseudoElement())
2512             return VisiblePosition(firstPositionInOrBeforeNode(element), DOWNSTREAM);
2513
2514         // Repeat at the next level up.
2515         child = parent;
2516     }
2517
2518     // Everything was anonymous. Give up.
2519     return VisiblePosition();
2520 }
2521
2522 VisiblePosition RenderObject::createVisiblePosition(const Position& position) const
2523 {
2524     if (position.isNotNull())
2525         return VisiblePosition(position);
2526
2527     ASSERT(!node());
2528     return createVisiblePosition(0, DOWNSTREAM);
2529 }
2530
2531 CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
2532 {
2533     return SetCursorBasedOnStyle;
2534 }
2535
2536 bool RenderObject::canUpdateSelectionOnRootLineBoxes()
2537 {
2538     if (needsLayout())
2539         return false;
2540
2541     RenderBlock* containingBlock = this->containingBlock();
2542     return containingBlock ? !containingBlock->needsLayout() : true;
2543 }
2544
2545 // We only create "generated" child renderers like one for first-letter if:
2546 // - the firstLetterBlock can have children in the DOM and
2547 // - the block doesn't have any special assumption on its text children.
2548 // This correctly prevents form controls from having such renderers.
2549 bool RenderObject::canHaveGeneratedChildren() const
2550 {
2551     return canHaveChildren();
2552 }
2553
2554 Node* RenderObject::generatingPseudoHostElement() const
2555 {
2556     return toPseudoElement(node())->hostElement();
2557 }
2558
2559 bool RenderObject::canBeReplacedWithInlineRunIn() const
2560 {
2561     return true;
2562 }
2563
2564 #if ENABLE(SVG)
2565
2566 RenderSVGResourceContainer* RenderObject::toRenderSVGResourceContainer()
2567 {
2568     ASSERT_NOT_REACHED();
2569     return 0;
2570 }
2571
2572 void RenderObject::setNeedsBoundariesUpdate()
2573 {
2574     if (auto renderer = parent())
2575         renderer->setNeedsBoundariesUpdate();
2576 }
2577
2578 FloatRect RenderObject::objectBoundingBox() const
2579 {
2580     ASSERT_NOT_REACHED();
2581     return FloatRect();
2582 }
2583
2584 FloatRect RenderObject::strokeBoundingBox() const
2585 {
2586     ASSERT_NOT_REACHED();
2587     return FloatRect();
2588 }
2589
2590 // Returns the smallest rectangle enclosing all of the painted content
2591 // respecting clipping, masking, filters, opacity, stroke-width and markers
2592 FloatRect RenderObject::repaintRectInLocalCoordinates() const
2593 {
2594     ASSERT_NOT_REACHED();
2595     return FloatRect();
2596 }
2597
2598 AffineTransform RenderObject::localTransform() const
2599 {
2600     static const AffineTransform identity;
2601     return identity;
2602 }
2603
2604 const AffineTransform& RenderObject::localToParentTransform() const
2605 {
2606     static const AffineTransform identity;
2607     return identity;
2608 }
2609
2610 bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
2611 {
2612     ASSERT_NOT_REACHED();
2613     return false;
2614 }
2615
2616 #endif // ENABLE(SVG)
2617
2618 } // namespace WebCore
2619
2620 #ifndef NDEBUG
2621
2622 void showTree(const WebCore::RenderObject* object)
2623 {
2624     if (object)
2625         object->showTreeForThis();
2626 }
2627
2628 void showLineTree(const WebCore::RenderObject* object)
2629 {
2630     if (object)
2631         object->showLineTreeForThis();
2632 }
2633
2634 void showRenderTree(const WebCore::RenderObject* object1)
2635 {
2636     showRenderTree(object1, 0);
2637 }
2638
2639 void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2)
2640 {
2641     if (object1) {
2642         const WebCore::RenderObject* root = object1;
2643         while (root->parent())
2644             root = root->parent();
2645         root->showRenderTreeAndMark(object1, "*", object2, "-", 0);
2646     }
2647 }
2648
2649 #endif