37b1a4ecfd71ce4ecc5e5cc0398b64891a3ff5e7
[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 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 "Chrome.h"
32 #include "ContentData.h"
33 #include "CursorList.h"
34 #include "DashArray.h"
35 #include "EditingBoundary.h"
36 #include "FloatQuad.h"
37 #include "FlowThreadController.h"
38 #include "Frame.h"
39 #include "FrameView.h"
40 #include "GraphicsContext.h"
41 #include "HTMLElement.h"
42 #include "HTMLNames.h"
43 #include "HitTestResult.h"
44 #include "Page.h"
45 #include "RenderArena.h"
46 #include "RenderCounter.h"
47 #include "RenderDeprecatedFlexibleBox.h"
48 #include "RenderFlexibleBox.h"
49 #include "RenderImage.h"
50 #include "RenderImageResourceStyleImage.h"
51 #include "RenderInline.h"
52 #include "RenderLayer.h"
53 #include "RenderListItem.h"
54 #include "RenderMultiColumnBlock.h"
55 #include "RenderNamedFlowThread.h"
56 #include "RenderRegion.h"
57 #include "RenderRuby.h"
58 #include "RenderRubyText.h"
59 #include "RenderTableCaption.h"
60 #include "RenderTableCell.h"
61 #include "RenderTableCol.h"
62 #include "RenderTableRow.h"
63 #include "RenderTheme.h"
64 #include "RenderView.h"
65 #include "Settings.h"
66 #include "StyleResolver.h"
67 #include "TransformState.h"
68 #include "htmlediting.h"
69 #include <algorithm>
70 #include <stdio.h>
71 #include <wtf/RefCountedLeakCounter.h>
72 #include <wtf/UnusedParam.h>
73
74 #if USE(ACCELERATED_COMPOSITING)
75 #include "RenderLayerCompositor.h"
76 #endif
77
78 #if ENABLE(SVG)
79 #include "RenderSVGResourceContainer.h"
80 #include "SVGRenderSupport.h"
81 #endif
82
83 using namespace std;
84
85 namespace WebCore {
86
87 using namespace HTMLNames;
88
89 #ifndef NDEBUG
90 static void* baseOfRenderObjectBeingDeleted;
91 #endif
92
93 struct SameSizeAsRenderObject {
94     virtual ~SameSizeAsRenderObject() { } // Allocate vtable pointer.
95     void* pointers[5];
96 #ifndef NDEBUG
97     unsigned m_debugBitfields : 2;
98 #endif
99     unsigned m_bitfields;
100 };
101
102 COMPILE_ASSERT(sizeof(RenderObject) == sizeof(SameSizeAsRenderObject), RenderObject_should_stay_small);
103
104 bool RenderObject::s_affectsParentBlock = false;
105
106 RenderObjectAncestorLineboxDirtySet* RenderObject::s_ancestorLineboxDirtySet = 0;
107
108 void* RenderObject::operator new(size_t sz, RenderArena* renderArena)
109 {
110     return renderArena->allocate(sz);
111 }
112
113 void RenderObject::operator delete(void* ptr, size_t sz)
114 {
115     ASSERT(baseOfRenderObjectBeingDeleted == ptr);
116
117     // Stash size where destroy can find it.
118     *(size_t *)ptr = sz;
119 }
120
121 RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
122 {
123     Document* doc = node->document();
124     RenderArena* arena = doc->renderArena();
125
126     // Minimal support for content properties replacing an entire element.
127     // Works only if we have exactly one piece of content and it's a URL.
128     // Otherwise acts as if we didn't support this feature.
129     const ContentData* contentData = style->contentData();
130     if (contentData && !contentData->next() && contentData->isImage() && doc != node) {
131         RenderImage* image = new (arena) RenderImage(node);
132         image->setStyle(style);
133         if (const StyleImage* styleImage = static_cast<const ImageContentData*>(contentData)->image()) {
134             image->setImageResource(RenderImageResourceStyleImage::create(const_cast<StyleImage*>(styleImage)));
135             image->setIsGeneratedContent();
136         } else
137             image->setImageResource(RenderImageResource::create());
138         return image;
139     }
140
141     if (node->hasTagName(rubyTag)) {
142         if (style->display() == INLINE)
143             return new (arena) RenderRubyAsInline(node);
144         else if (style->display() == BLOCK)
145             return new (arena) RenderRubyAsBlock(node);
146     }
147     // treat <rt> as ruby text ONLY if it still has its default treatment of block
148     if (node->hasTagName(rtTag) && style->display() == BLOCK)
149         return new (arena) RenderRubyText(node);
150
151     switch (style->display()) {
152 #if ENABLE(CSS_GRID_LAYOUT)
153     // For now, we don't show grid elements.
154     case GRID:
155     case INLINE_GRID:
156 #endif
157     case NONE:
158         return 0;
159     case INLINE:
160         return new (arena) RenderInline(node);
161     case BLOCK:
162     case INLINE_BLOCK:
163     case RUN_IN:
164     case COMPACT:
165         // Only non-replaced block elements can become a region.
166         if (doc->cssRegionsEnabled() && !style->regionThread().isEmpty() && doc->renderView())
167             return new (arena) RenderRegion(node, doc->renderView()->flowThreadController()->ensureRenderFlowThreadWithName(style->regionThread()));
168         if ((!style->hasAutoColumnCount() || !style->hasAutoColumnWidth()) && doc->regionBasedColumnsEnabled())
169             return new (arena) RenderMultiColumnBlock(node);
170         return new (arena) RenderBlock(node);
171     case LIST_ITEM:
172         return new (arena) RenderListItem(node);
173     case TABLE:
174     case INLINE_TABLE:
175         return new (arena) RenderTable(node);
176     case TABLE_ROW_GROUP:
177     case TABLE_HEADER_GROUP:
178     case TABLE_FOOTER_GROUP:
179         return new (arena) RenderTableSection(node);
180     case TABLE_ROW:
181         return new (arena) RenderTableRow(node);
182     case TABLE_COLUMN_GROUP:
183     case TABLE_COLUMN:
184         return new (arena) RenderTableCol(node);
185     case TABLE_CELL:
186         return new (arena) RenderTableCell(node);
187     case TABLE_CAPTION:
188         return new (arena) RenderTableCaption(node);
189     case BOX:
190     case INLINE_BOX:
191         return new (arena) RenderDeprecatedFlexibleBox(node);
192     case FLEXBOX:
193     case INLINE_FLEXBOX:
194         return new (arena) RenderFlexibleBox(node);
195     }
196
197     return 0;
198 }
199
200 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, renderObjectCounter, ("RenderObject"));
201
202 RenderObject::RenderObject(Node* node)
203     : CachedImageClient()
204     , m_style(0)
205     , m_node(node)
206     , m_parent(0)
207     , m_previous(0)
208     , m_next(0)
209 #ifndef NDEBUG
210     , m_hasAXObject(false)
211     , m_setNeedsLayoutForbidden(false)
212 #endif
213     , m_bitfields(node)
214 {
215 #ifndef NDEBUG
216     renderObjectCounter.increment();
217 #endif
218     ASSERT(node);
219 }
220
221 RenderObject::~RenderObject()
222 {
223     ASSERT(!node() || documentBeingDestroyed() || !frame()->view() || frame()->view()->layoutRoot() != this);
224 #ifndef NDEBUG
225     ASSERT(!m_hasAXObject);
226     renderObjectCounter.decrement();
227 #endif
228 }
229
230 RenderTheme* RenderObject::theme() const
231 {
232     ASSERT(document()->page());
233
234     return document()->page()->theme();
235 }
236
237 bool RenderObject::isDescendantOf(const RenderObject* obj) const
238 {
239     for (const RenderObject* r = this; r; r = r->m_parent) {
240         if (r == obj)
241             return true;
242     }
243     return false;
244 }
245
246 bool RenderObject::isBody() const
247 {
248     return node() && node()->hasTagName(bodyTag);
249 }
250
251 bool RenderObject::isHR() const
252 {
253     return node() && node()->hasTagName(hrTag);
254 }
255
256 bool RenderObject::isLegend() const
257 {
258     return node() && node()->hasTagName(legendTag);
259 }
260
261 bool RenderObject::isHTMLMarquee() const
262 {
263     return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);
264 }
265
266 void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
267 {
268     RenderObjectChildList* children = virtualChildren();
269     ASSERT(children);
270     if (!children)
271         return;
272
273     bool needsTable = false;
274
275     if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
276         needsTable = !isTable();
277     else if (newChild->isTableCaption())
278         needsTable = !isTable();
279     else if (newChild->isTableSection())
280         needsTable = !isTable();
281     else if (newChild->isTableRow())
282         needsTable = !isTableSection();
283     else if (newChild->isTableCell()) {
284         needsTable = !isTableRow();
285         // I'm not 100% sure this is the best way to fix this, but without this
286         // change we recurse infinitely when trying to render the CSS2 test page:
287         // http://www.bath.ac.uk/%7Epy8ieh/internet/eviltests/htmlbodyheadrendering2.html.
288         // See Radar 2925291.
289         if (needsTable && isTableCell() && !children->firstChild() && !newChild->isTableCell())
290             needsTable = false;
291     }
292
293     if (needsTable) {
294         RenderTable* table;
295         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : children->lastChild();
296         if (afterChild && afterChild->isAnonymous() && afterChild->isTable() && !afterChild->isBeforeContent())
297             table = toRenderTable(afterChild);
298         else {
299             table = RenderTable::createAnonymousWithParentRenderer(this);
300             addChild(table, beforeChild);
301         }
302         table->addChild(newChild);
303     } else {
304         // Just add it...
305         children->insertChildNode(this, newChild, beforeChild);
306     }
307
308     if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE)
309         toRenderText(newChild)->transformText();
310
311     // SVG creates renderers for <g display="none">, as SVG requires children of hidden
312     // <g>s to have renderers - at least that's how our implementation works. Consider:
313     // <g display="none"><foreignObject><body style="position: relative">FOO...
314     // - requiresLayer() would return true for the <body>, creating a new RenderLayer
315     // - when the document is painted, both layers are painted. The <body> layer doesn't
316     //   know that it's inside a "hidden SVG subtree", and thus paints, even if it shouldn't.
317     // To avoid the problem alltogether, detect early if we're inside a hidden SVG subtree
318     // and stop creating layers at all for these cases - they're not used anyways.
319     if (newChild->hasLayer() && !layerCreationAllowedForSubtree())
320         toRenderBoxModelObject(newChild)->layer()->removeOnlyThisLayer();
321 }
322
323 void RenderObject::removeChild(RenderObject* oldChild)
324 {
325     RenderObjectChildList* children = virtualChildren();
326     ASSERT(children);
327     if (!children)
328         return;
329
330     // We do this here instead of in removeChildNode, since the only extremely low-level uses of remove/appendChildNode
331     // cannot affect the positioned object list, and the floating object list is irrelevant (since the list gets cleared on
332     // layout anyway).
333     if (oldChild->isFloatingOrPositioned())
334         toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
335         
336     children->removeChildNode(this, oldChild);
337 }
338
339 RenderObject* RenderObject::nextInPreOrder() const
340 {
341     if (RenderObject* o = firstChild())
342         return o;
343
344     return nextInPreOrderAfterChildren();
345 }
346
347 RenderObject* RenderObject::nextInPreOrderAfterChildren() const
348 {
349     RenderObject* o;
350     if (!(o = nextSibling())) {
351         o = parent();
352         while (o && !o->nextSibling())
353             o = o->parent();
354         if (o)
355             o = o->nextSibling();
356     }
357
358     return o;
359 }
360
361 RenderObject* RenderObject::nextInPreOrder(const RenderObject* stayWithin) const
362 {
363     if (RenderObject* o = firstChild())
364         return o;
365
366     return nextInPreOrderAfterChildren(stayWithin);
367 }
368
369 RenderObject* RenderObject::nextInPreOrderAfterChildren(const RenderObject* stayWithin) const
370 {
371     if (this == stayWithin)
372         return 0;
373
374     const RenderObject* current = this;
375     RenderObject* next;
376     while (!(next = current->nextSibling())) {
377         current = current->parent();
378         if (!current || current == stayWithin)
379             return 0;
380     }
381     return next;
382 }
383
384 RenderObject* RenderObject::previousInPreOrder() const
385 {
386     if (RenderObject* o = previousSibling()) {
387         while (o->lastChild())
388             o = o->lastChild();
389         return o;
390     }
391
392     return parent();
393 }
394
395 RenderObject* RenderObject::childAt(unsigned index) const
396 {
397     RenderObject* child = firstChild();
398     for (unsigned i = 0; child && i < index; i++)
399         child = child->nextSibling();
400     return child;
401 }
402
403 RenderObject* RenderObject::firstLeafChild() const
404 {
405     RenderObject* r = firstChild();
406     while (r) {
407         RenderObject* n = 0;
408         n = r->firstChild();
409         if (!n)
410             break;
411         r = n;
412     }
413     return r;
414 }
415
416 RenderObject* RenderObject::lastLeafChild() const
417 {
418     RenderObject* r = lastChild();
419     while (r) {
420         RenderObject* n = 0;
421         n = r->lastChild();
422         if (!n)
423             break;
424         r = n;
425     }
426     return r;
427 }
428
429 static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject*& newObject,
430                       RenderLayer*& beforeChild)
431 {
432     if (obj->hasLayer()) {
433         if (!beforeChild && newObject) {
434             // We need to figure out the layer that follows newObject.  We only do
435             // this the first time we find a child layer, and then we update the
436             // pointer values for newObject and beforeChild used by everyone else.
437             beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject);
438             newObject = 0;
439         }
440         parentLayer->addChild(toRenderBoxModelObject(obj)->layer(), beforeChild);
441         return;
442     }
443
444     for (RenderObject* curr = obj->firstChild(); curr; curr = curr->nextSibling())
445         addLayers(curr, parentLayer, newObject, beforeChild);
446 }
447
448 void RenderObject::addLayers(RenderLayer* parentLayer)
449 {
450     if (!parentLayer)
451         return;
452
453     RenderObject* object = this;
454     RenderLayer* beforeChild = 0;
455     WebCore::addLayers(this, parentLayer, object, beforeChild);
456 }
457
458 void RenderObject::removeLayers(RenderLayer* parentLayer)
459 {
460     if (!parentLayer)
461         return;
462
463     if (hasLayer()) {
464         parentLayer->removeChild(toRenderBoxModelObject(this)->layer());
465         return;
466     }
467
468     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
469         curr->removeLayers(parentLayer);
470 }
471
472 void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
473 {
474     if (!newParent)
475         return;
476
477     if (hasLayer()) {
478         RenderLayer* layer = toRenderBoxModelObject(this)->layer();
479         ASSERT(oldParent == layer->parent());
480         if (oldParent)
481             oldParent->removeChild(layer);
482         newParent->addChild(layer);
483         return;
484     }
485
486     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
487         curr->moveLayers(oldParent, newParent);
488 }
489
490 RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint,
491                                          bool checkParent)
492 {
493     // Error check the parent layer passed in.  If it's null, we can't find anything.
494     if (!parentLayer)
495         return 0;
496
497     // Step 1: If our layer is a child of the desired parent, then return our layer.
498     RenderLayer* ourLayer = hasLayer() ? toRenderBoxModelObject(this)->layer() : 0;
499     if (ourLayer && ourLayer->parent() == parentLayer)
500         return ourLayer;
501
502     // Step 2: If we don't have a layer, or our layer is the desired parent, then descend
503     // into our siblings trying to find the next layer whose parent is the desired parent.
504     if (!ourLayer || ourLayer == parentLayer) {
505         for (RenderObject* curr = startPoint ? startPoint->nextSibling() : firstChild();
506              curr; curr = curr->nextSibling()) {
507             RenderLayer* nextLayer = curr->findNextLayer(parentLayer, 0, false);
508             if (nextLayer)
509                 return nextLayer;
510         }
511     }
512
513     // Step 3: If our layer is the desired parent layer, then we're finished.  We didn't
514     // find anything.
515     if (parentLayer == ourLayer)
516         return 0;
517
518     // Step 4: If |checkParent| is set, climb up to our parent and check its siblings that
519     // follow us to see if we can locate a layer.
520     if (checkParent && parent())
521         return parent()->findNextLayer(parentLayer, this, true);
522
523     return 0;
524 }
525
526 RenderLayer* RenderObject::enclosingLayer() const
527 {
528     const RenderObject* curr = this;
529     while (curr) {
530         RenderLayer* layer = curr->hasLayer() ? toRenderBoxModelObject(curr)->layer() : 0;
531         if (layer)
532             return layer;
533         curr = curr->parent();
534     }
535     return 0;
536 }
537
538 bool RenderObject::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
539 {
540     RenderLayer* enclosingLayer = this->enclosingLayer();
541     if (!enclosingLayer)
542         return false;
543
544     enclosingLayer->scrollRectToVisible(rect, alignX, alignY);
545     return true;
546 }
547
548 RenderBox* RenderObject::enclosingBox() const
549 {
550     RenderObject* curr = const_cast<RenderObject*>(this);
551     while (curr) {
552         if (curr->isBox())
553             return toRenderBox(curr);
554         curr = curr->parent();
555     }
556     
557     ASSERT_NOT_REACHED();
558     return 0;
559 }
560
561 RenderBoxModelObject* RenderObject::enclosingBoxModelObject() const
562 {
563     RenderObject* curr = const_cast<RenderObject*>(this);
564     while (curr) {
565         if (curr->isBoxModelObject())
566             return toRenderBoxModelObject(curr);
567         curr = curr->parent();
568     }
569
570     ASSERT_NOT_REACHED();
571     return 0;
572 }
573
574 RenderFlowThread* RenderObject::enclosingRenderFlowThread() const
575 {   
576     if (!inRenderFlowThread())
577         return 0;
578     
579     // See if we have the thread cached because we're in the middle of layout.
580     RenderFlowThread* flowThread = view()->flowThreadController()->currentRenderFlowThread();
581     if (flowThread)
582         return flowThread;
583     
584     // Not in the middle of layout so have to find the thread the slow way.
585     RenderObject* curr = const_cast<RenderObject*>(this);
586     while (curr) {
587         if (curr->isRenderFlowThread())
588             return toRenderFlowThread(curr);
589         curr = curr->parent();
590     }
591     return 0;
592 }
593
594 RenderBlock* RenderObject::firstLineBlock() const
595 {
596     return 0;
597 }
598
599 static inline bool objectIsRelayoutBoundary(const RenderObject* object)
600 {
601     // FIXME: In future it may be possible to broaden this condition in order to improve performance.
602     // Table cells are excluded because even when their CSS height is fixed, their height()
603     // may depend on their contents.
604     return object->isTextControl()
605 #if ENABLE(SVG)
606         || object->isSVGRoot()
607 #endif
608         || (object->hasOverflowClip() && !object->style()->width().isIntrinsicOrAuto() && !object->style()->height().isIntrinsicOrAuto() && !object->style()->height().isPercent() && !object->isTableCell());
609 }
610
611 void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, RenderObject* newRoot)
612 {
613     ASSERT(!scheduleRelayout || !newRoot);
614
615     RenderObject* object = container();
616     RenderObject* last = this;
617
618     bool simplifiedNormalFlowLayout = needsSimplifiedNormalFlowLayout() && !selfNeedsLayout() && !normalChildNeedsLayout();
619
620     while (object) {
621         // Don't mark the outermost object of an unrooted subtree. That object will be
622         // marked when the subtree is added to the document.
623         RenderObject* container = object->container();
624         if (!container && !object->isRenderView())
625             return;
626         if (!last->isText() && last->style()->isPositioned()) {
627             bool willSkipRelativelyPositionedInlines = !object->isRenderBlock() || object->isAnonymousBlock();
628             // Skip relatively positioned inlines and anonymous blocks to get to the enclosing RenderBlock.
629             while (object && (!object->isRenderBlock() || object->isAnonymousBlock()))
630                 object = object->container();
631             if (!object || object->posChildNeedsLayout())
632                 return;
633             if (willSkipRelativelyPositionedInlines)
634                 container = object->container();
635             object->setPosChildNeedsLayout(true);
636             simplifiedNormalFlowLayout = true;
637             ASSERT(!object->isSetNeedsLayoutForbidden());
638         } else if (simplifiedNormalFlowLayout) {
639             if (object->needsSimplifiedNormalFlowLayout())
640                 return;
641             object->setNeedsSimplifiedNormalFlowLayout(true);
642             ASSERT(!object->isSetNeedsLayoutForbidden());
643         } else {
644             if (object->normalChildNeedsLayout())
645                 return;
646             object->setNormalChildNeedsLayout(true);
647             ASSERT(!object->isSetNeedsLayoutForbidden());
648         }
649
650         if (object == newRoot)
651             return;
652
653         last = object;
654         if (scheduleRelayout && objectIsRelayoutBoundary(last))
655             break;
656         object = container;
657     }
658
659     if (scheduleRelayout)
660         last->scheduleRelayout();
661 }
662
663 void RenderObject::setPreferredLogicalWidthsDirty(bool shouldBeDirty, MarkingBehavior markParents)
664 {
665     bool alreadyDirty = preferredLogicalWidthsDirty();
666     m_bitfields.setPreferredLogicalWidthsDirty(shouldBeDirty);
667     if (shouldBeDirty && !alreadyDirty && markParents == MarkContainingBlockChain && (isText() || !style()->isPositioned()))
668         invalidateContainerPreferredLogicalWidths();
669 }
670
671 void RenderObject::invalidateContainerPreferredLogicalWidths()
672 {
673     // In order to avoid pathological behavior when inlines are deeply nested, we do include them
674     // in the chain that we mark dirty (even though they're kind of irrelevant).
675     RenderObject* o = isTableCell() ? containingBlock() : container();
676     while (o && !o->preferredLogicalWidthsDirty()) {
677         // Don't invalidate the outermost object of an unrooted subtree. That object will be 
678         // invalidated when the subtree is added to the document.
679         RenderObject* container = o->isTableCell() ? o->containingBlock() : o->container();
680         if (!container && !o->isRenderView())
681             break;
682
683         o->m_bitfields.setPreferredLogicalWidthsDirty(true);
684         if (o->style()->isPositioned())
685             // A positioned object has no effect on the min/max width of its containing block ever.
686             // We can optimize this case and not go up any further.
687             break;
688         o = container;
689     }
690 }
691
692 void RenderObject::setLayerNeedsFullRepaint()
693 {
694     ASSERT(hasLayer());
695     toRenderBoxModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaint);
696 }
697
698 void RenderObject::setLayerNeedsFullRepaintForPositionedMovementLayout()
699 {
700     ASSERT(hasLayer());
701     toRenderBoxModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout);
702 }
703
704 RenderBlock* RenderObject::containingBlock() const
705 {
706     RenderObject* o = parent();
707     if (!isText() && m_style->position() == FixedPosition) {
708         while (o && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock()))
709             o = o->parent();
710     } else if (!isText() && m_style->position() == AbsolutePosition) {
711         while (o && (o->style()->position() == StaticPosition || (o->isInline() && !o->isReplaced())) && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
712             // For relpositioned inlines, we return the nearest non-anonymous enclosing block. We don't try
713             // to return the inline itself.  This allows us to avoid having a positioned objects
714             // list in all RenderInlines and lets us return a strongly-typed RenderBlock* result
715             // from this method.  The container() method can actually be used to obtain the
716             // inline directly.
717             if (o->style()->position() == RelativePosition && o->isInline() && !o->isReplaced()) {
718                 RenderBlock* relPositionedInlineContainingBlock = o->containingBlock();
719                 while (relPositionedInlineContainingBlock->isAnonymousBlock())
720                     relPositionedInlineContainingBlock = relPositionedInlineContainingBlock->containingBlock();
721                 return relPositionedInlineContainingBlock;
722             }
723 #if ENABLE(SVG)
724             if (o->isSVGForeignObject()) //foreignObject is the containing block for contents inside it
725                 break;
726 #endif
727
728             o = o->parent();
729         }
730     } else {
731         while (o && ((o->isInline() && !o->isReplaced()) || !o->isRenderBlock()))
732             o = o->parent();
733     }
734
735     if (!o || !o->isRenderBlock())
736         return 0; // This can still happen in case of an orphaned tree
737
738     return toRenderBlock(o);
739 }
740
741 static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* layer)
742 {
743     // Nobody will use multiple layers without wanting fancy positioning.
744     if (layer->next())
745         return true;
746
747     // Make sure we have a valid image.
748     StyleImage* img = layer->image();
749     if (!img || !img->canRender(renderer, renderer->style()->effectiveZoom()))
750         return false;
751
752     if (!layer->xPosition().isZero() || !layer->yPosition().isZero())
753         return true;
754
755     if (layer->size().type == SizeLength) {
756         if (layer->size().size.width().isPercent() || layer->size().size.height().isPercent())
757             return true;
758     } else if (layer->size().type == Contain || layer->size().type == Cover || img->usesImageContainerSize())
759         return true;
760
761     return false;
762 }
763
764 bool RenderObject::borderImageIsLoadedAndCanBeRendered() const
765 {
766     ASSERT(style()->hasBorder());
767
768     StyleImage* borderImage = style()->borderImage().image();
769     return borderImage && borderImage->canRender(this, style()->effectiveZoom()) && borderImage->isLoaded();
770 }
771
772 bool RenderObject::mustRepaintBackgroundOrBorder() const
773 {
774     if (hasMask() && mustRepaintFillLayers(this, style()->maskLayers()))
775         return true;
776
777     // If we don't have a background/border/mask, then nothing to do.
778     if (!hasBoxDecorations())
779         return false;
780
781     if (mustRepaintFillLayers(this, style()->backgroundLayers()))
782         return true;
783      
784     // Our fill layers are ok.  Let's check border.
785     if (style()->hasBorder() && borderImageIsLoadedAndCanBeRendered())
786         return true;
787
788     return false;
789 }
790
791 void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
792                                       BoxSide side, Color color, EBorderStyle style,
793                                       int adjacentWidth1, int adjacentWidth2, bool antialias)
794 {
795     int width = (side == BSTop || side == BSBottom ? y2 - y1 : x2 - x1);
796
797     if (style == DOUBLE && width < 3)
798         style = SOLID;
799
800     switch (style) {
801         case BNONE:
802         case BHIDDEN:
803             return;
804         case DOTTED:
805         case DASHED: {
806             graphicsContext->setStrokeColor(color, m_style->colorSpace());
807             graphicsContext->setStrokeThickness(width);
808             StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
809             graphicsContext->setStrokeStyle(style == DASHED ? DashedStroke : DottedStroke);
810
811             if (width > 0) {
812                 bool wasAntialiased = graphicsContext->shouldAntialias();
813                 graphicsContext->setShouldAntialias(antialias);
814
815                 switch (side) {
816                     case BSBottom:
817                     case BSTop:
818                         graphicsContext->drawLine(IntPoint(x1, (y1 + y2) / 2), IntPoint(x2, (y1 + y2) / 2));
819                         break;
820                     case BSRight:
821                     case BSLeft:
822                         graphicsContext->drawLine(IntPoint((x1 + x2) / 2, y1), IntPoint((x1 + x2) / 2, y2));
823                         break;
824                 }
825                 graphicsContext->setShouldAntialias(wasAntialiased);
826                 graphicsContext->setStrokeStyle(oldStrokeStyle);
827             }
828             break;
829         }
830         case DOUBLE: {
831             int third = (width + 1) / 3;
832
833             if (adjacentWidth1 == 0 && adjacentWidth2 == 0) {
834                 StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
835                 graphicsContext->setStrokeStyle(NoStroke);
836                 graphicsContext->setFillColor(color, m_style->colorSpace());
837                 
838                 bool wasAntialiased = graphicsContext->shouldAntialias();
839                 graphicsContext->setShouldAntialias(antialias);
840
841                 switch (side) {
842                     case BSTop:
843                     case BSBottom:
844                         graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, third));
845                         graphicsContext->drawRect(IntRect(x1, y2 - third, x2 - x1, third));
846                         break;
847                     case BSLeft:
848                         graphicsContext->drawRect(IntRect(x1, y1 + 1, third, y2 - y1 - 1));
849                         graphicsContext->drawRect(IntRect(x2 - third, y1 + 1, third, y2 - y1 - 1));
850                         break;
851                     case BSRight:
852                         graphicsContext->drawRect(IntRect(x1, y1 + 1, third, y2 - y1 - 1));
853                         graphicsContext->drawRect(IntRect(x2 - third, y1 + 1, third, y2 - y1 - 1));
854                         break;
855                 }
856
857                 graphicsContext->setShouldAntialias(wasAntialiased);
858                 graphicsContext->setStrokeStyle(oldStrokeStyle);
859             } else {
860                 int adjacent1BigThird = ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 3;
861                 int adjacent2BigThird = ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 3;
862
863                 switch (side) {
864                     case BSTop:
865                         drawLineForBoxSide(graphicsContext, x1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
866                                    y1, x2 - max((-adjacentWidth2 * 2 + 1) / 3, 0), y1 + third,
867                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
868                         drawLineForBoxSide(graphicsContext, x1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
869                                    y2 - third, x2 - max((adjacentWidth2 * 2 + 1) / 3, 0), y2,
870                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
871                         break;
872                     case BSLeft:
873                         drawLineForBoxSide(graphicsContext, x1, y1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
874                                    x1 + third, y2 - max((-adjacentWidth2 * 2 + 1) / 3, 0),
875                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
876                         drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
877                                    x2, y2 - max((adjacentWidth2 * 2 + 1) / 3, 0),
878                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
879                         break;
880                     case BSBottom:
881                         drawLineForBoxSide(graphicsContext, x1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
882                                    y1, x2 - max((adjacentWidth2 * 2 + 1) / 3, 0), y1 + third,
883                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
884                         drawLineForBoxSide(graphicsContext, x1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
885                                    y2 - third, x2 - max((-adjacentWidth2 * 2 + 1) / 3, 0), y2,
886                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
887                         break;
888                     case BSRight:
889                         drawLineForBoxSide(graphicsContext, x1, y1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
890                                    x1 + third, y2 - max((adjacentWidth2 * 2 + 1) / 3, 0),
891                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
892                         drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
893                                    x2, y2 - max((-adjacentWidth2 * 2 + 1) / 3, 0),
894                                    side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
895                         break;
896                     default:
897                         break;
898                 }
899             }
900             break;
901         }
902         case RIDGE:
903         case GROOVE: {
904             EBorderStyle s1;
905             EBorderStyle s2;
906             if (style == GROOVE) {
907                 s1 = INSET;
908                 s2 = OUTSET;
909             } else {
910                 s1 = OUTSET;
911                 s2 = INSET;
912             }
913
914             int adjacent1BigHalf = ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 2;
915             int adjacent2BigHalf = ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 2;
916
917             switch (side) {
918                 case BSTop:
919                     drawLineForBoxSide(graphicsContext, x1 + max(-adjacentWidth1, 0) / 2, y1, x2 - max(-adjacentWidth2, 0) / 2, (y1 + y2 + 1) / 2,
920                                side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
921                     drawLineForBoxSide(graphicsContext, x1 + max(adjacentWidth1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(adjacentWidth2 + 1, 0) / 2, y2,
922                                side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
923                     break;
924                 case BSLeft:
925                     drawLineForBoxSide(graphicsContext, x1, y1 + max(-adjacentWidth1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(-adjacentWidth2, 0) / 2,
926                                side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
927                     drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(adjacentWidth1 + 1, 0) / 2, x2, y2 - max(adjacentWidth2 + 1, 0) / 2,
928                                side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
929                     break;
930                 case BSBottom:
931                     drawLineForBoxSide(graphicsContext, x1 + max(adjacentWidth1, 0) / 2, y1, x2 - max(adjacentWidth2, 0) / 2, (y1 + y2 + 1) / 2,
932                                side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
933                     drawLineForBoxSide(graphicsContext, x1 + max(-adjacentWidth1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(-adjacentWidth2 + 1, 0) / 2, y2,
934                                side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
935                     break;
936                 case BSRight:
937                     drawLineForBoxSide(graphicsContext, x1, y1 + max(adjacentWidth1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(adjacentWidth2, 0) / 2,
938                                side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
939                     drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(-adjacentWidth1 + 1, 0) / 2, x2, y2 - max(-adjacentWidth2 + 1, 0) / 2,
940                                side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
941                     break;
942             }
943             break;
944         }
945         case INSET:
946             // FIXME: Maybe we should lighten the colors on one side like Firefox.
947             // https://bugs.webkit.org/show_bug.cgi?id=58608
948             if (side == BSTop || side == BSLeft)
949                 color = color.dark();
950             // fall through
951         case OUTSET:
952             if (style == OUTSET && (side == BSBottom || side == BSRight))
953                 color = color.dark();
954             // fall through
955         case SOLID: {
956             StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
957             graphicsContext->setStrokeStyle(NoStroke);
958             graphicsContext->setFillColor(color, m_style->colorSpace());
959             ASSERT(x2 >= x1);
960             ASSERT(y2 >= y1);
961             if (!adjacentWidth1 && !adjacentWidth2) {
962                 // Turn off antialiasing to match the behavior of drawConvexPolygon();
963                 // this matters for rects in transformed contexts.
964                 bool wasAntialiased = graphicsContext->shouldAntialias();
965                 graphicsContext->setShouldAntialias(antialias);
966                 graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, y2 - y1));
967                 graphicsContext->setShouldAntialias(wasAntialiased);
968                 graphicsContext->setStrokeStyle(oldStrokeStyle);
969                 return;
970             }
971             FloatPoint quad[4];
972             switch (side) {
973                 case BSTop:
974                     quad[0] = FloatPoint(x1 + max(-adjacentWidth1, 0), y1);
975                     quad[1] = FloatPoint(x1 + max(adjacentWidth1, 0), y2);
976                     quad[2] = FloatPoint(x2 - max(adjacentWidth2, 0), y2);
977                     quad[3] = FloatPoint(x2 - max(-adjacentWidth2, 0), y1);
978                     break;
979                 case BSBottom:
980                     quad[0] = FloatPoint(x1 + max(adjacentWidth1, 0), y1);
981                     quad[1] = FloatPoint(x1 + max(-adjacentWidth1, 0), y2);
982                     quad[2] = FloatPoint(x2 - max(-adjacentWidth2, 0), y2);
983                     quad[3] = FloatPoint(x2 - max(adjacentWidth2, 0), y1);
984                     break;
985                 case BSLeft:
986                     quad[0] = FloatPoint(x1, y1 + max(-adjacentWidth1, 0));
987                     quad[1] = FloatPoint(x1, y2 - max(-adjacentWidth2, 0));
988                     quad[2] = FloatPoint(x2, y2 - max(adjacentWidth2, 0));
989                     quad[3] = FloatPoint(x2, y1 + max(adjacentWidth1, 0));
990                     break;
991                 case BSRight:
992                     quad[0] = FloatPoint(x1, y1 + max(adjacentWidth1, 0));
993                     quad[1] = FloatPoint(x1, y2 - max(adjacentWidth2, 0));
994                     quad[2] = FloatPoint(x2, y2 - max(-adjacentWidth2, 0));
995                     quad[3] = FloatPoint(x2, y1 + max(-adjacentWidth1, 0));
996                     break;
997             }
998
999             graphicsContext->drawConvexPolygon(4, quad, antialias);
1000             graphicsContext->setStrokeStyle(oldStrokeStyle);
1001             break;
1002         }
1003     }
1004 }
1005
1006 #if !HAVE(PATH_BASED_BORDER_RADIUS_DRAWING)
1007 void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, int y, float thickness, const IntSize& radius,
1008                                      int angleStart, int angleSpan, BoxSide s, Color color,
1009                                      EBorderStyle style, bool firstCorner)
1010 {
1011     // FIXME: This function should be removed when all ports implement GraphicsContext::clipConvexPolygon()!!
1012     // At that time, everyone can use RenderObject::drawBoxSideFromPath() instead. This should happen soon.
1013     if ((style == DOUBLE && thickness / 2 < 3) || ((style == RIDGE || style == GROOVE) && thickness / 2 < 2))
1014         style = SOLID;
1015
1016     switch (style) {
1017         case BNONE:
1018         case BHIDDEN:
1019             return;
1020         case DOTTED:
1021         case DASHED:
1022             graphicsContext->setStrokeColor(color, m_style->colorSpace());
1023             graphicsContext->setStrokeStyle(style == DOTTED ? DottedStroke : DashedStroke);
1024             graphicsContext->setStrokeThickness(thickness);
1025             graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
1026             break;
1027         case DOUBLE: {
1028             float third = thickness / 3.0f;
1029             float innerThird = (thickness + 1.0f) / 6.0f;
1030             int shiftForInner = static_cast<int>(innerThird * 2.5f);
1031
1032             int outerY = y;
1033             int outerHeight = radius.height() * 2;
1034             int innerX = x + shiftForInner;
1035             int innerY = y + shiftForInner;
1036             int innerWidth = (radius.width() - shiftForInner) * 2;
1037             int innerHeight = (radius.height() - shiftForInner) * 2;
1038             if (innerThird > 1 && (s == BSTop || (firstCorner && (s == BSLeft || s == BSRight)))) {
1039                 outerHeight += 2;
1040                 innerHeight += 2;
1041             }
1042
1043             graphicsContext->setStrokeStyle(SolidStroke);
1044             graphicsContext->setStrokeColor(color, m_style->colorSpace());
1045             graphicsContext->setStrokeThickness(third);
1046             graphicsContext->strokeArc(IntRect(x, outerY, radius.width() * 2, outerHeight), angleStart, angleSpan);
1047             graphicsContext->setStrokeThickness(innerThird > 2 ? innerThird - 1 : innerThird);
1048             graphicsContext->strokeArc(IntRect(innerX, innerY, innerWidth, innerHeight), angleStart, angleSpan);
1049             break;
1050         }
1051         case GROOVE:
1052         case RIDGE: {
1053             Color c2;
1054             if ((style == RIDGE && (s == BSTop || s == BSLeft)) ||
1055                     (style == GROOVE && (s == BSBottom || s == BSRight)))
1056                 c2 = color.dark();
1057             else {
1058                 c2 = color;
1059                 color = color.dark();
1060             }
1061
1062             graphicsContext->setStrokeStyle(SolidStroke);
1063             graphicsContext->setStrokeColor(color, m_style->colorSpace());
1064             graphicsContext->setStrokeThickness(thickness);
1065             graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
1066
1067             float halfThickness = (thickness + 1.0f) / 4.0f;
1068             int shiftForInner = static_cast<int>(halfThickness * 1.5f);
1069             graphicsContext->setStrokeColor(c2, m_style->colorSpace());
1070             graphicsContext->setStrokeThickness(halfThickness > 2 ? halfThickness - 1 : halfThickness);
1071             graphicsContext->strokeArc(IntRect(x + shiftForInner, y + shiftForInner, (radius.width() - shiftForInner) * 2,
1072                                        (radius.height() - shiftForInner) * 2), angleStart, angleSpan);
1073             break;
1074         }
1075         case INSET:
1076             if (s == BSTop || s == BSLeft)
1077                 color = color.dark();
1078         case OUTSET:
1079             if (style == OUTSET && (s == BSBottom || s == BSRight))
1080                 color = color.dark();
1081         case SOLID:
1082             graphicsContext->setStrokeStyle(SolidStroke);
1083             graphicsContext->setStrokeColor(color, m_style->colorSpace());
1084             graphicsContext->setStrokeThickness(thickness);
1085             graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
1086             break;
1087     }
1088 }
1089 #endif
1090     
1091 void RenderObject::paintFocusRing(GraphicsContext* context, const LayoutPoint& paintOffset, RenderStyle* style)
1092 {
1093     Vector<IntRect> focusRingRects;
1094     addFocusRingRects(focusRingRects, paintOffset);
1095     if (style->outlineStyleIsAuto())
1096         context->drawFocusRing(focusRingRects, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
1097     else
1098         addPDFURLRect(context, unionRect(focusRingRects));
1099 }        
1100
1101 void RenderObject::addPDFURLRect(GraphicsContext* context, const LayoutRect& rect)
1102 {
1103     if (rect.isEmpty())
1104         return;
1105     Node* n = node();
1106     if (!n || !n->isLink() || !n->isElementNode())
1107         return;
1108     const AtomicString& href = static_cast<Element*>(n)->getAttribute(hrefAttr);
1109     if (href.isNull())
1110         return;
1111     context->setURLForRect(n->document()->completeURL(href), pixelSnappedIntRect(rect));
1112 }
1113
1114 void RenderObject::paintOutline(GraphicsContext* graphicsContext, const LayoutRect& paintRect)
1115 {
1116     if (!hasOutline())
1117         return;
1118
1119     RenderStyle* styleToUse = style();
1120     LayoutUnit outlineWidth = styleToUse->outlineWidth();
1121     EBorderStyle outlineStyle = styleToUse->outlineStyle();
1122
1123     Color outlineColor = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
1124
1125     int outlineOffset = styleToUse->outlineOffset();
1126
1127     if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
1128         if (!theme()->supportsFocusRing(styleToUse)) {
1129             // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
1130             paintFocusRing(graphicsContext, paintRect.location(), styleToUse);
1131         }
1132     }
1133
1134     if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE)
1135         return;
1136
1137     IntRect inner = pixelSnappedIntRect(paintRect);
1138     inner.inflate(outlineOffset);
1139
1140     IntRect outer = pixelSnappedIntRect(inner);
1141     outer.inflate(outlineWidth);
1142
1143     // FIXME: This prevents outlines from painting inside the object. See bug 12042
1144     if (outer.isEmpty())
1145         return;
1146
1147     bool useTransparencyLayer = outlineColor.hasAlpha();
1148     if (useTransparencyLayer) {
1149         if (outlineStyle == SOLID) {
1150             Path path;
1151             path.addRect(outer);
1152             path.addRect(inner);
1153             graphicsContext->setFillRule(RULE_EVENODD);
1154             graphicsContext->setFillColor(outlineColor, styleToUse->colorSpace());
1155             graphicsContext->fillPath(path);
1156             return;
1157         }
1158         graphicsContext->beginTransparencyLayer(static_cast<float>(outlineColor.alpha()) / 255);
1159         outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue());
1160     }
1161
1162     int leftOuter = outer.x();
1163     int leftInner = inner.x();
1164     int rightOuter = outer.maxX();
1165     int rightInner = inner.maxX();
1166     int topOuter = outer.y();
1167     int topInner = inner.y();
1168     int bottomOuter = outer.maxY();
1169     int bottomInner = inner.maxY();
1170     
1171     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, leftInner, bottomOuter, BSLeft, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1172     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, rightOuter, topInner, BSTop, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1173     drawLineForBoxSide(graphicsContext, rightInner, topOuter, rightOuter, bottomOuter, BSRight, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1174     drawLineForBoxSide(graphicsContext, leftOuter, bottomInner, rightOuter, bottomOuter, BSBottom, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1175
1176     if (useTransparencyLayer)
1177         graphicsContext->endTransparencyLayer();
1178 }
1179
1180 IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
1181 {
1182     if (useTransforms) {
1183         Vector<FloatQuad> quads;
1184         absoluteQuads(quads);
1185
1186         size_t n = quads.size();
1187         if (!n)
1188             return IntRect();
1189     
1190         IntRect result = quads[0].enclosingBoundingBox();
1191         for (size_t i = 1; i < n; ++i)
1192             result.unite(quads[i].enclosingBoundingBox());
1193         return result;
1194     }
1195
1196     FloatPoint absPos = localToAbsolute();
1197     Vector<IntRect> rects;
1198     absoluteRects(rects, flooredLayoutPoint(absPos));
1199
1200     size_t n = rects.size();
1201     if (!n)
1202         return IntRect();
1203
1204     LayoutRect result = rects[0];
1205     for (size_t i = 1; i < n; ++i)
1206         result.unite(rects[i]);
1207     return pixelSnappedIntRect(result);
1208 }
1209
1210 void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
1211 {
1212     Vector<IntRect> rects;
1213     // FIXME: addFocusRingRects() needs to be passed this transform-unaware
1214     // localToAbsolute() offset here because RenderInline::addFocusRingRects()
1215     // implicitly assumes that. This doesn't work correctly with transformed
1216     // descendants.
1217     FloatPoint absolutePoint = localToAbsolute();
1218     addFocusRingRects(rects, flooredLayoutPoint(absolutePoint));
1219     size_t count = rects.size(); 
1220     for (size_t i = 0; i < count; ++i) {
1221         IntRect rect = rects[i];
1222         rect.move(-absolutePoint.x(), -absolutePoint.y());
1223         quads.append(localToAbsoluteQuad(FloatQuad(rect)));
1224     }
1225 }
1226
1227 void RenderObject::addAbsoluteRectForLayer(LayoutRect& result)
1228 {
1229     if (hasLayer())
1230         result.unite(absoluteBoundingBoxRectIgnoringTransforms());
1231     for (RenderObject* current = firstChild(); current; current = current->nextSibling())
1232         current->addAbsoluteRectForLayer(result);
1233 }
1234
1235 LayoutRect RenderObject::paintingRootRect(LayoutRect& topLevelRect)
1236 {
1237     LayoutRect result = absoluteBoundingBoxRectIgnoringTransforms();
1238     topLevelRect = result;
1239     for (RenderObject* current = firstChild(); current; current = current->nextSibling())
1240         current->addAbsoluteRectForLayer(result);
1241     return result;
1242 }
1243
1244 void RenderObject::paint(PaintInfo&, const LayoutPoint&)
1245 {
1246 }
1247
1248 RenderBoxModelObject* RenderObject::containerForRepaint() const
1249 {
1250     RenderView* v = view();
1251     if (!v)
1252         return 0;
1253     
1254     RenderBoxModelObject* repaintContainer = 0;
1255
1256 #if USE(ACCELERATED_COMPOSITING)
1257     if (v->usesCompositing()) {
1258         RenderLayer* compLayer = enclosingLayer()->enclosingCompositingLayerForRepaint();
1259         if (compLayer)
1260             repaintContainer = compLayer->renderer();
1261     }
1262 #endif
1263     
1264 #if ENABLE(CSS_FILTERS)
1265     if (RenderLayer* parentLayer = enclosingLayer()) {
1266         RenderLayer* enclosingFilterLayer = parentLayer->enclosingFilterLayer();
1267         if (enclosingFilterLayer)
1268             return enclosingFilterLayer->renderer();
1269     }
1270 #endif
1271
1272     // If we have a flow thread, then we need to do individual repaints within the RenderRegions instead.
1273     // Return the flow thread as a repaint container in order to create a chokepoint that allows us to change
1274     // repainting to do individual region repaints.
1275     // FIXME: Composited layers inside a flow thread will bypass this mechanism and will malfunction. It's not
1276     // clear how to address this problem for composited descendants of a RenderFlowThread.
1277     if (!repaintContainer && inRenderFlowThread())
1278         repaintContainer = enclosingRenderFlowThread();
1279     return repaintContainer;
1280 }
1281
1282 void RenderObject::repaintUsingContainer(RenderBoxModelObject* repaintContainer, const LayoutRect& r, bool immediate)
1283 {
1284     if (!repaintContainer) {
1285         view()->repaintViewRectangle(r, immediate);
1286         return;
1287     }
1288
1289     if (repaintContainer->isRenderFlowThread()) {
1290         toRenderFlowThread(repaintContainer)->repaintRectangleInRegions(r, immediate);
1291         return;
1292     }
1293
1294 #if ENABLE(CSS_FILTERS)
1295     if (repaintContainer->hasFilter() && repaintContainer->layer() && repaintContainer->layer()->requiresFullLayerImageForFilters()) {
1296         repaintContainer->layer()->setFilterBackendNeedsRepaintingInRect(r, immediate);
1297         return;
1298     }
1299 #endif
1300
1301 #if USE(ACCELERATED_COMPOSITING)
1302     RenderView* v = view();
1303     if (repaintContainer->isRenderView()) {
1304         ASSERT(repaintContainer == v);
1305         bool viewHasCompositedLayer = v->hasLayer() && v->layer()->isComposited();
1306         if (!viewHasCompositedLayer || v->layer()->backing()->paintsIntoWindow()) {
1307             LayoutRect repaintRectangle = r;
1308             if (viewHasCompositedLayer &&  v->layer()->transform())
1309                 repaintRectangle = v->layer()->transform()->mapRect(r);
1310             v->repaintViewRectangle(repaintRectangle, immediate);
1311             return;
1312         }
1313     }
1314     
1315     if (v->usesCompositing()) {
1316         ASSERT(repaintContainer->hasLayer() && repaintContainer->layer()->isComposited());
1317         repaintContainer->layer()->setBackingNeedsRepaintInRect(r);
1318     }
1319 #else
1320     if (repaintContainer->isRenderView())
1321         toRenderView(repaintContainer)->repaintViewRectangle(r, immediate);
1322 #endif
1323 }
1324
1325 void RenderObject::repaint(bool immediate)
1326 {
1327     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1328     RenderView* view;
1329     if (!isRooted(&view))
1330         return;
1331
1332     if (view->printing())
1333         return; // Don't repaint if we're printing.
1334
1335     RenderBoxModelObject* repaintContainer = containerForRepaint();
1336     repaintUsingContainer(repaintContainer ? repaintContainer : view, clippedOverflowRectForRepaint(repaintContainer), immediate);
1337 }
1338
1339 void RenderObject::repaintRectangle(const LayoutRect& r, bool immediate)
1340 {
1341     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1342     RenderView* view;
1343     if (!isRooted(&view))
1344         return;
1345
1346     if (view->printing())
1347         return; // Don't repaint if we're printing.
1348
1349     LayoutRect dirtyRect(r);
1350
1351     // FIXME: layoutDelta needs to be applied in parts before/after transforms and
1352     // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
1353     dirtyRect.move(view->layoutDelta());
1354
1355     RenderBoxModelObject* repaintContainer = containerForRepaint();
1356     computeRectForRepaint(repaintContainer, dirtyRect);
1357     repaintUsingContainer(repaintContainer ? repaintContainer : view, dirtyRect, immediate);
1358 }
1359
1360 IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
1361 {
1362     return pixelSnappedIntRect(absoluteClippedOverflowRect());
1363 }
1364
1365 bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr, const LayoutRect* newOutlineBoxRectPtr)
1366 {
1367     RenderView* v = view();
1368     if (v->printing())
1369         return false; // Don't repaint if we're printing.
1370
1371     // This ASSERT fails due to animations.  See https://bugs.webkit.org/show_bug.cgi?id=37048
1372     // ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForRepaint(repaintContainer));
1373     LayoutRect newBounds = newBoundsPtr ? *newBoundsPtr : clippedOverflowRectForRepaint(repaintContainer);
1374     LayoutRect newOutlineBox;
1375
1376     bool fullRepaint = selfNeedsLayout();
1377     // Presumably a background or a border exists if border-fit:lines was specified.
1378     if (!fullRepaint && style()->borderFit() == BorderFitLines)
1379         fullRepaint = true;
1380     if (!fullRepaint) {
1381         // This ASSERT fails due to animations.  See https://bugs.webkit.org/show_bug.cgi?id=37048
1382         // ASSERT(!newOutlineBoxRectPtr || *newOutlineBoxRectPtr == outlineBoundsForRepaint(repaintContainer));
1383         newOutlineBox = newOutlineBoxRectPtr ? *newOutlineBoxRectPtr : outlineBoundsForRepaint(repaintContainer);
1384         if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
1385             fullRepaint = true;
1386     }
1387
1388     if (!repaintContainer)
1389         repaintContainer = v;
1390
1391     if (fullRepaint) {
1392         repaintUsingContainer(repaintContainer, oldBounds);
1393         if (newBounds != oldBounds)
1394             repaintUsingContainer(repaintContainer, newBounds);
1395         return true;
1396     }
1397
1398     if (newBounds == oldBounds && newOutlineBox == oldOutlineBox)
1399         return false;
1400
1401     LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
1402     if (deltaLeft > 0)
1403         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
1404     else if (deltaLeft < 0)
1405         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
1406
1407     LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
1408     if (deltaRight > 0)
1409         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
1410     else if (deltaRight < 0)
1411         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
1412
1413     LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
1414     if (deltaTop > 0)
1415         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
1416     else if (deltaTop < 0)
1417         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
1418
1419     LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
1420     if (deltaBottom > 0)
1421         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
1422     else if (deltaBottom < 0)
1423         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
1424
1425     if (newOutlineBox == oldOutlineBox)
1426         return false;
1427
1428     // We didn't move, but we did change size.  Invalidate the delta, which will consist of possibly
1429     // two rectangles (but typically only one).
1430     RenderStyle* outlineStyle = outlineStyleForRepaint();
1431     LayoutUnit ow = outlineStyle->outlineSize();
1432     LayoutUnit width = absoluteValue(newOutlineBox.width() - oldOutlineBox.width());
1433     if (width) {
1434         LayoutUnit shadowLeft;
1435         LayoutUnit shadowRight;
1436         style()->getBoxShadowHorizontalExtent(shadowLeft, shadowRight);
1437
1438         int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0;
1439         LayoutUnit boxWidth = isBox() ? toRenderBox(this)->width() : ZERO_LAYOUT_UNIT;
1440         LayoutUnit borderWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), max<LayoutUnit>(borderRight, max<LayoutUnit>(valueForLength(style()->borderTopRightRadius().width(), boxWidth, v), valueForLength(style()->borderBottomRightRadius().width(), boxWidth, v)))) + max<LayoutUnit>(ow, shadowRight);
1441         LayoutRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - borderWidth,
1442             newOutlineBox.y(),
1443             width + borderWidth,
1444             max(newOutlineBox.height(), oldOutlineBox.height()));
1445         LayoutUnit right = min<LayoutUnit>(newBounds.maxX(), oldBounds.maxX());
1446         if (rightRect.x() < right) {
1447             rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
1448             repaintUsingContainer(repaintContainer, rightRect);
1449         }
1450     }
1451     LayoutUnit height = absoluteValue(newOutlineBox.height() - oldOutlineBox.height());
1452     if (height) {
1453         LayoutUnit shadowTop;
1454         LayoutUnit shadowBottom;
1455         style()->getBoxShadowVerticalExtent(shadowTop, shadowBottom);
1456
1457         int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0;
1458         LayoutUnit boxHeight = isBox() ? toRenderBox(this)->height() : ZERO_LAYOUT_UNIT;
1459         LayoutUnit borderHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), max<LayoutUnit>(borderBottom, max<LayoutUnit>(valueForLength(style()->borderBottomLeftRadius().height(), boxHeight, v), valueForLength(style()->borderBottomRightRadius().height(), boxHeight, v)))) + max<LayoutUnit>(ow, shadowBottom);
1460         LayoutRect bottomRect(newOutlineBox.x(),
1461             min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - borderHeight,
1462             max(newOutlineBox.width(), oldOutlineBox.width()),
1463             height + borderHeight);
1464         LayoutUnit bottom = min(newBounds.maxY(), oldBounds.maxY());
1465         if (bottomRect.y() < bottom) {
1466             bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
1467             repaintUsingContainer(repaintContainer, bottomRect);
1468         }
1469     }
1470     return false;
1471 }
1472
1473 void RenderObject::repaintDuringLayoutIfMoved(const LayoutRect&)
1474 {
1475 }
1476
1477 void RenderObject::repaintOverhangingFloats(bool)
1478 {
1479 }
1480
1481 bool RenderObject::checkForRepaintDuringLayout() const
1482 {
1483     // FIXME: <https://bugs.webkit.org/show_bug.cgi?id=20885> It is probably safe to also require
1484     // m_everHadLayout. Currently, only RenderBlock::layoutBlock() adds this condition. See also
1485     // <https://bugs.webkit.org/show_bug.cgi?id=15129>.
1486     return !document()->view()->needsFullRepaint() && !hasLayer();
1487 }
1488
1489 LayoutRect RenderObject::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, LayoutUnit outlineWidth) const
1490 {
1491     LayoutRect r(clippedOverflowRectForRepaint(repaintContainer));
1492     r.inflate(outlineWidth);
1493     return r;
1494 }
1495
1496 LayoutRect RenderObject::clippedOverflowRectForRepaint(RenderBoxModelObject*) const
1497 {
1498     ASSERT_NOT_REACHED();
1499     return LayoutRect();
1500 }
1501
1502 void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
1503 {
1504     if (repaintContainer == this)
1505         return;
1506
1507     if (RenderObject* o = parent()) {
1508         if (o->isBlockFlow()) {
1509             RenderBlock* cb = toRenderBlock(o);
1510             if (cb->hasColumns())
1511                 cb->adjustRectForColumns(rect);
1512         }
1513
1514         if (o->hasOverflowClip()) {
1515             // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the
1516             // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint
1517             // anyway if its size does change.
1518             RenderBox* boxParent = toRenderBox(o);
1519
1520             LayoutRect repaintRect(rect);
1521             repaintRect.move(-boxParent->scrolledContentOffset()); // For overflow:auto/scroll/hidden.
1522
1523             LayoutRect boxRect(LayoutPoint(), boxParent->cachedSizeForOverflowClip());
1524             rect = intersection(repaintRect, boxRect);
1525             if (rect.isEmpty())
1526                 return;
1527         }
1528
1529         o->computeRectForRepaint(repaintContainer, rect, fixed);
1530     }
1531 }
1532
1533 void RenderObject::computeFloatRectForRepaint(RenderBoxModelObject*, FloatRect&, bool) const
1534 {
1535     ASSERT_NOT_REACHED();
1536 }
1537
1538 void RenderObject::dirtyLinesFromChangedChild(RenderObject*)
1539 {
1540 }
1541
1542 #ifndef NDEBUG
1543
1544 void RenderObject::showTreeForThis() const
1545 {
1546     if (node())
1547         node()->showTreeForThis();
1548 }
1549
1550 void RenderObject::showRenderTreeForThis() const
1551 {
1552     showRenderTree(this, 0);
1553 }
1554
1555 void RenderObject::showLineTreeForThis() const
1556 {
1557     if (containingBlock())
1558         containingBlock()->showLineTreeAndMark(0, 0, 0, 0, this);
1559 }
1560
1561 void RenderObject::showRenderObject() const
1562 {
1563     showRenderObject(0);
1564 }
1565
1566 void RenderObject::showRenderObject(int printedCharacters) const
1567 {
1568     // As this function is intended to be used when debugging, the
1569     // this pointer may be 0.
1570     if (!this) {
1571         fputs("(null)\n", stderr);
1572         return;
1573     }
1574
1575     printedCharacters += fprintf(stderr, "%s %p", renderName(), this);
1576
1577     if (node()) {
1578         if (printedCharacters)
1579             for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
1580                 fputc(' ', stderr);
1581         fputc('\t', stderr);
1582         node()->showNode();
1583     } else
1584         fputc('\n', stderr);
1585 }
1586
1587 void RenderObject::showRenderTreeAndMark(const RenderObject* markedObject1, const char* markedLabel1, const RenderObject* markedObject2, const char* markedLabel2, int depth) const
1588 {
1589     int printedCharacters = 0;
1590     if (markedObject1 == this && markedLabel1)
1591         printedCharacters += fprintf(stderr, "%s", markedLabel1);
1592     if (markedObject2 == this && markedLabel2)
1593         printedCharacters += fprintf(stderr, "%s", markedLabel2);
1594     for (; printedCharacters < depth * 2; printedCharacters++)
1595         fputc(' ', stderr);
1596
1597     showRenderObject(printedCharacters);
1598     if (!this)
1599         return;
1600
1601     for (const RenderObject* child = firstChild(); child; child = child->nextSibling())
1602         child->showRenderTreeAndMark(markedObject1, markedLabel1, markedObject2, markedLabel2, depth + 1);
1603 }
1604
1605 #endif // NDEBUG
1606
1607 Color RenderObject::selectionBackgroundColor() const
1608 {
1609     Color color;
1610     if (style()->userSelect() != SELECT_NONE) {
1611         RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION);
1612         if (pseudoStyle && pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
1613             color = pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).blendWithWhite();
1614         else
1615             color = frame()->selection()->isFocusedAndActive() ?
1616                     theme()->activeSelectionBackgroundColor() :
1617                     theme()->inactiveSelectionBackgroundColor();
1618     }
1619
1620     return color;
1621 }
1622
1623 Color RenderObject::selectionColor(int colorProperty) const
1624 {
1625     Color color;
1626     // If the element is unselectable, or we are only painting the selection,
1627     // don't override the foreground color with the selection foreground color.
1628     if (style()->userSelect() == SELECT_NONE
1629         || (frame()->view()->paintBehavior() & PaintBehaviorSelectionOnly))
1630         return color;
1631
1632     if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION)) {
1633         color = pseudoStyle->visitedDependentColor(colorProperty);
1634         if (!color.isValid())
1635             color = pseudoStyle->visitedDependentColor(CSSPropertyColor);
1636     } else
1637         color = frame()->selection()->isFocusedAndActive() ?
1638                 theme()->activeSelectionForegroundColor() :
1639                 theme()->inactiveSelectionForegroundColor();
1640
1641     return color;
1642 }
1643
1644 Color RenderObject::selectionForegroundColor() const
1645 {
1646     return selectionColor(CSSPropertyWebkitTextFillColor);
1647 }
1648
1649 Color RenderObject::selectionEmphasisMarkColor() const
1650 {
1651     return selectionColor(CSSPropertyWebkitTextEmphasisColor);
1652 }
1653
1654 void RenderObject::selectionStartEnd(int& spos, int& epos) const
1655 {
1656     view()->selectionStartEnd(spos, epos);
1657 }
1658
1659 void RenderObject::handleDynamicFloatPositionChange()
1660 {
1661     // We have gone from not affecting the inline status of the parent flow to suddenly
1662     // having an impact.  See if there is a mismatch between the parent flow's
1663     // childrenInline() state and our state.
1664     setInline(style()->isDisplayInlineType());
1665     if (isInline() != parent()->childrenInline()) {
1666         if (!isInline())
1667             toRenderBoxModelObject(parent())->childBecameNonInline(this);
1668         else {
1669             // An anonymous block must be made to wrap this inline.
1670             RenderBlock* block = toRenderBlock(parent())->createAnonymousBlock();
1671             RenderObjectChildList* childlist = parent()->virtualChildren();
1672             childlist->insertChildNode(parent(), block, this);
1673             block->children()->appendChildNode(block, childlist->removeChildNode(parent(), this));
1674         }
1675     }
1676 }
1677
1678 void RenderObject::setAnimatableStyle(PassRefPtr<RenderStyle> style)
1679 {
1680     if (!isText() && style)
1681         setStyle(animation()->updateAnimations(this, style.get()));
1682     else
1683         setStyle(style);
1684 }
1685
1686 StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
1687 {
1688 #if USE(ACCELERATED_COMPOSITING)
1689     // If transform changed, and we are not composited, need to do a layout.
1690     if (contextSensitiveProperties & ContextSensitivePropertyTransform) {
1691         // Text nodes share style with their parents but transforms don't apply to them,
1692         // hence the !isText() check.
1693         // FIXME: when transforms are taken into account for overflow, we will need to do a layout.
1694         if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited())) {
1695             // We need to set at least SimplifiedLayout, but if PositionedMovementOnly is already set
1696             // then we actually need SimplifiedLayoutAndPositionedMovement.
1697             if (!hasLayer())
1698                 diff = StyleDifferenceLayout; // FIXME: Do this for now since SimplifiedLayout cannot handle updating floating objects lists.
1699             else if (diff < StyleDifferenceLayoutPositionedMovementOnly)
1700                 diff = StyleDifferenceSimplifiedLayout;
1701             else if (diff < StyleDifferenceSimplifiedLayout)
1702                 diff = StyleDifferenceSimplifiedLayoutAndPositionedMovement;
1703         } else if (diff < StyleDifferenceRecompositeLayer)
1704             diff = StyleDifferenceRecompositeLayer;
1705     }
1706
1707     // If opacity changed, and we are not composited, need to repaint (also
1708     // ignoring text nodes)
1709     if (contextSensitiveProperties & ContextSensitivePropertyOpacity) {
1710         if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited()))
1711             diff = StyleDifferenceRepaintLayer;
1712         else if (diff < StyleDifferenceRecompositeLayer)
1713             diff = StyleDifferenceRecompositeLayer;
1714     }
1715     
1716 #if ENABLE(CSS_FILTERS)
1717     if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLayer()) {
1718         RenderLayer* layer = toRenderBoxModelObject(this)->layer();
1719         if (!layer->isComposited() || layer->paintsWithFilters())
1720             diff = StyleDifferenceRepaintLayer;
1721         else if (diff < StyleDifferenceRecompositeLayer)
1722             diff = StyleDifferenceRecompositeLayer;
1723     }
1724 #endif
1725     
1726     // The answer to requiresLayer() for plugins and iframes can change outside of the style system,
1727     // since it depends on whether we decide to composite these elements. When the layer status of
1728     // one of these elements changes, we need to force a layout.
1729     if (diff == StyleDifferenceEqual && style() && isBoxModelObject()) {
1730         if (hasLayer() != toRenderBoxModelObject(this)->requiresLayer())
1731             diff = StyleDifferenceLayout;
1732     }
1733 #else
1734     UNUSED_PARAM(contextSensitiveProperties);
1735 #endif
1736
1737     // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
1738     if (diff == StyleDifferenceRepaintLayer && !hasLayer())
1739         diff = StyleDifferenceRepaint;
1740
1741     return diff;
1742 }
1743
1744 void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
1745 {
1746     if (m_style == style) {
1747 #if USE(ACCELERATED_COMPOSITING)
1748         // We need to run through adjustStyleDifference() for iframes and plugins, so
1749         // style sharing is disabled for them. That should ensure that we never hit this code path.
1750         ASSERT(!isRenderIFrame() && !isEmbeddedObject() &&!isApplet());
1751 #endif
1752         return;
1753     }
1754
1755     StyleDifference diff = StyleDifferenceEqual;
1756     unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
1757     if (m_style)
1758         diff = m_style->diff(style.get(), contextSensitiveProperties);
1759
1760     diff = adjustStyleDifference(diff, contextSensitiveProperties);
1761
1762     styleWillChange(diff, style.get());
1763     
1764     RefPtr<RenderStyle> oldStyle = m_style.release();
1765     m_style = style;
1766
1767     updateFillImages(oldStyle ? oldStyle->backgroundLayers() : 0, m_style ? m_style->backgroundLayers() : 0);
1768     updateFillImages(oldStyle ? oldStyle->maskLayers() : 0, m_style ? m_style->maskLayers() : 0);
1769
1770     updateImage(oldStyle ? oldStyle->borderImage().image() : 0, m_style ? m_style->borderImage().image() : 0);
1771     updateImage(oldStyle ? oldStyle->maskBoxImage().image() : 0, m_style ? m_style->maskBoxImage().image() : 0);
1772
1773     // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen
1774     // during styleDidChange (it's used by clippedOverflowRectForRepaint()).
1775     if (m_style->outlineWidth() > 0 && m_style->outlineSize() > maximalOutlineSize(PaintPhaseOutline))
1776         toRenderView(document()->renderer())->setMaximalOutlineSize(m_style->outlineSize());
1777
1778     styleDidChange(diff, oldStyle.get());
1779
1780     if (!m_parent || isText())
1781         return;
1782
1783     // Now that the layer (if any) has been updated, we need to adjust the diff again,
1784     // check whether we should layout now, and decide if we need to repaint.
1785     StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
1786     
1787     if (diff <= StyleDifferenceLayoutPositionedMovementOnly) {
1788         if (updatedDiff == StyleDifferenceLayout)
1789             setNeedsLayoutAndPrefWidthsRecalc();
1790         else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly)
1791             setNeedsPositionedMovementLayout();
1792         else if (updatedDiff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
1793             setNeedsPositionedMovementLayout();
1794             setNeedsSimplifiedNormalFlowLayout();
1795         } else if (updatedDiff == StyleDifferenceSimplifiedLayout)
1796             setNeedsSimplifiedNormalFlowLayout();
1797     }
1798     
1799     if (updatedDiff == StyleDifferenceRepaintLayer || updatedDiff == StyleDifferenceRepaint) {
1800         // Do a repaint with the new style now, e.g., for example if we go from
1801         // not having an outline to having an outline.
1802         repaint();
1803     }
1804 }
1805
1806 void RenderObject::setStyleInternal(PassRefPtr<RenderStyle> style)
1807 {
1808     m_style = style;
1809 }
1810
1811 void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
1812 {
1813     if (m_style) {
1814         // If our z-index changes value or our visibility changes,
1815         // we need to dirty our stacking context's z-order list.
1816         if (newStyle) {
1817             bool visibilityChanged = m_style->visibility() != newStyle->visibility() 
1818                 || m_style->zIndex() != newStyle->zIndex() 
1819                 || m_style->hasAutoZIndex() != newStyle->hasAutoZIndex();
1820 #if ENABLE(DASHBOARD_SUPPORT)
1821             if (visibilityChanged)
1822                 document()->setDashboardRegionsDirty(true);
1823 #endif
1824             if (visibilityChanged && AXObjectCache::accessibilityEnabled())
1825                 document()->axObjectCache()->childrenChanged(this);
1826
1827             // Keep layer hierarchy visibility bits up to date if visibility changes.
1828             if (m_style->visibility() != newStyle->visibility()) {
1829                 if (RenderLayer* l = enclosingLayer()) {
1830                     if (newStyle->visibility() == VISIBLE)
1831                         l->setHasVisibleContent(true);
1832                     else if (l->hasVisibleContent() && (this == l->renderer() || l->renderer()->style()->visibility() != VISIBLE)) {
1833                         l->dirtyVisibleContentStatus();
1834                         if (diff > StyleDifferenceRepaintLayer)
1835                             repaint();
1836                     }
1837                 }
1838             }
1839         }
1840
1841         if (m_parent && (diff == StyleDifferenceRepaint || newStyle->outlineSize() < m_style->outlineSize()))
1842             repaint();
1843         if (isFloating() && (m_style->floating() != newStyle->floating()))
1844             // For changes in float styles, we need to conceivably remove ourselves
1845             // from the floating objects list.
1846             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
1847         else if (isPositioned() && (m_style->position() != newStyle->position()))
1848             // For changes in positioning styles, we need to conceivably remove ourselves
1849             // from the positioned objects list.
1850             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
1851
1852         s_affectsParentBlock = isFloatingOrPositioned() &&
1853             (!newStyle->isFloating() && newStyle->position() != AbsolutePosition && newStyle->position() != FixedPosition)
1854             && parent() && (parent()->isBlockFlow() || parent()->isRenderInline());
1855
1856         // reset style flags
1857         if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositionedMovementOnly) {
1858             setFloating(false);
1859             setPositioned(false);
1860             setRelPositioned(false);
1861         }
1862         setHorizontalWritingMode(true);
1863         setPaintBackground(false);
1864         setHasOverflowClip(false);
1865         setHasTransform(false);
1866         setHasReflection(false);
1867     } else
1868         s_affectsParentBlock = false;
1869
1870     if (view()->frameView()) {
1871         bool shouldBlitOnFixedBackgroundImage = false;
1872 #if ENABLE(FAST_MOBILE_SCROLLING)
1873         // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
1874         // when scrolling a page with a fixed background image. As an optimization, assuming there are
1875         // no fixed positoned elements on the page, we can acclerate scrolling (via blitting) if we
1876         // ignore the CSS property "background-attachment: fixed".
1877 #if PLATFORM(QT)
1878         if (view()->frameView()->delegatesScrolling())
1879 #endif
1880             shouldBlitOnFixedBackgroundImage = true;
1881 #endif
1882
1883         bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
1884         bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
1885         if (oldStyleSlowScroll != newStyleSlowScroll) {
1886             if (oldStyleSlowScroll)
1887                 view()->frameView()->removeSlowRepaintObject();
1888             if (newStyleSlowScroll)
1889                 view()->frameView()->addSlowRepaintObject();
1890         }
1891     }
1892 }
1893
1894 static bool areNonIdenticalCursorListsEqual(const RenderStyle* a, const RenderStyle* b)
1895 {
1896     ASSERT(a->cursors() != b->cursors());
1897     return a->cursors() && b->cursors() && *a->cursors() == *b->cursors();
1898 }
1899
1900 static inline bool areCursorsEqual(const RenderStyle* a, const RenderStyle* b)
1901 {
1902     return a->cursor() == b->cursor() && (a->cursors() == b->cursors() || areNonIdenticalCursorListsEqual(a, b));
1903 }
1904
1905 void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
1906 {
1907     if (s_affectsParentBlock)
1908         handleDynamicFloatPositionChange();
1909
1910     if (!m_parent)
1911         return;
1912     
1913     if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) {
1914         RenderCounter::rendererStyleChanged(this, oldStyle, m_style.get());
1915
1916         // If the object already needs layout, then setNeedsLayout won't do
1917         // any work. But if the containing block has changed, then we may need
1918         // to mark the new containing blocks for layout. The change that can
1919         // directly affect the containing block of this object is a change to
1920         // the position style.
1921         if (needsLayout() && oldStyle->position() != m_style->position())
1922             markContainingBlocksForLayout();
1923
1924         if (diff == StyleDifferenceLayout)
1925             setNeedsLayoutAndPrefWidthsRecalc();
1926         else
1927             setNeedsSimplifiedNormalFlowLayout();
1928     } else if (diff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
1929         setNeedsPositionedMovementLayout();
1930         setNeedsSimplifiedNormalFlowLayout();
1931     } else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
1932         setNeedsPositionedMovementLayout();
1933
1934     // Don't check for repaint here; we need to wait until the layer has been
1935     // updated by subclasses before we know if we have to repaint (in setStyle()).
1936
1937     if (oldStyle && !areCursorsEqual(oldStyle, style())) {
1938         if (Frame* frame = this->frame())
1939             frame->eventHandler()->dispatchFakeMouseMoveEventSoon();
1940     }
1941 }
1942
1943 void RenderObject::propagateStyleToAnonymousChildren(bool blockChildrenOnly)
1944 {
1945     // FIXME: We could save this call when the change only affected non-inherited properties.
1946     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
1947         if (!child->isAnonymous() || child->style()->styleType() != NOPSEUDO)
1948             continue;
1949
1950         if (blockChildrenOnly && !child->isRenderBlock())
1951             continue;
1952
1953 #if ENABLE(FULLSCREEN_API)
1954         if (child->isRenderFullScreen() || child->isRenderFullScreenPlaceholder())
1955             continue;
1956 #endif
1957
1958         RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
1959         if (style()->specifiesColumns()) {
1960             if (child->style()->specifiesColumns())
1961                 newStyle->inheritColumnPropertiesFrom(style());
1962             if (child->style()->columnSpan())
1963                 newStyle->setColumnSpan(ColumnSpanAll);
1964         }
1965
1966         // Preserve the position style of anonymous block continuations as they can have relative position when
1967         // they contain block descendants of relative positioned inlines.
1968         if (child->isRelPositioned() && toRenderBlock(child)->isAnonymousBlockContinuation())
1969             newStyle->setPosition(child->style()->position());
1970
1971         newStyle->setDisplay(child->style()->display());
1972         child->setStyle(newStyle.release());
1973     }
1974 }
1975
1976 void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers)
1977 {
1978     // Optimize the common case
1979     if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && (oldLayers->image() == newLayers->image()))
1980         return;
1981     
1982     // Go through the new layers and addClients first, to avoid removing all clients of an image.
1983     for (const FillLayer* currNew = newLayers; currNew; currNew = currNew->next()) {
1984         if (currNew->image())
1985             currNew->image()->addClient(this);
1986     }
1987
1988     for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) {
1989         if (currOld->image())
1990             currOld->image()->removeClient(this);
1991     }
1992 }
1993
1994 void RenderObject::updateImage(StyleImage* oldImage, StyleImage* newImage)
1995 {
1996     if (oldImage != newImage) {
1997         if (oldImage)
1998             oldImage->removeClient(this);
1999         if (newImage)
2000             newImage->addClient(this);
2001     }
2002 }
2003
2004 LayoutRect RenderObject::viewRect() const
2005 {
2006     return view()->viewRect();
2007 }
2008
2009 FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, bool fixed, bool useTransforms) const
2010 {
2011     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
2012     mapLocalToContainer(0, fixed, useTransforms, transformState);
2013     transformState.flatten();
2014     
2015     return transformState.lastPlanarPoint();
2016 }
2017
2018 FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, bool fixed, bool useTransforms) const
2019 {
2020     TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
2021     mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
2022     transformState.flatten();
2023     
2024     return transformState.lastPlanarPoint();
2025 }
2026
2027 void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState, bool* wasFixed) const
2028 {
2029     if (repaintContainer == this)
2030         return;
2031
2032     RenderObject* o = parent();
2033     if (!o)
2034         return;
2035
2036     LayoutPoint centerPoint = roundedLayoutPoint(transformState.mappedPoint());
2037     if (o->isBox() && o->style()->isFlippedBlocksWritingMode())
2038         transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(roundedLayoutPoint(transformState.mappedPoint())) - centerPoint);
2039
2040     LayoutSize columnOffset;
2041     o->adjustForColumns(columnOffset, roundedLayoutPoint(transformState.mappedPoint()));
2042     if (!columnOffset.isZero())
2043         transformState.move(columnOffset);
2044
2045     if (o->hasOverflowClip())
2046         transformState.move(-toRenderBox(o)->scrolledContentOffset());
2047
2048     o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState, wasFixed);
2049 }
2050
2051 void RenderObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
2052 {
2053     RenderObject* o = parent();
2054     if (o) {
2055         o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
2056         if (o->hasOverflowClip())
2057             transformState.move(toRenderBox(o)->scrolledContentOffset());
2058     }
2059 }
2060
2061 bool RenderObject::shouldUseTransformFromContainer(const RenderObject* containerObject) const
2062 {
2063 #if ENABLE(3D_RENDERING)
2064     // hasTransform() indicates whether the object has transform, transform-style or perspective. We just care about transform,
2065     // so check the layer's transform directly.
2066     return (hasLayer() && toRenderBoxModelObject(this)->layer()->transform()) || (containerObject && containerObject->style()->hasPerspective());
2067 #else
2068     UNUSED_PARAM(containerObject);
2069     return hasTransform();
2070 #endif
2071 }
2072
2073 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
2074 {
2075     transform.makeIdentity();
2076     transform.translate(offsetInContainer.width(), offsetInContainer.height());
2077     RenderLayer* layer;
2078     if (hasLayer() && (layer = toRenderBoxModelObject(this)->layer()) && layer->transform())
2079         transform.multiply(layer->currentTransform());
2080     
2081 #if ENABLE(3D_RENDERING)
2082     if (containerObject && containerObject->hasLayer() && containerObject->style()->hasPerspective()) {
2083         // Perpsective on the container affects us, so we have to factor it in here.
2084         ASSERT(containerObject->hasLayer());
2085         FloatPoint perspectiveOrigin = toRenderBoxModelObject(containerObject)->layer()->perspectiveOrigin();
2086
2087         TransformationMatrix perspectiveMatrix;
2088         perspectiveMatrix.applyPerspective(containerObject->style()->perspective());
2089         
2090         transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
2091         transform = perspectiveMatrix * transform;
2092         transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
2093     }
2094 #else
2095     UNUSED_PARAM(containerObject);
2096 #endif
2097 }
2098
2099 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool fixed, bool* wasFixed) const
2100 {
2101     // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
2102     // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
2103     TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
2104     mapLocalToContainer(repaintContainer, fixed, true, transformState, wasFixed);
2105     transformState.flatten();
2106     
2107     return transformState.lastPlanarQuad();
2108 }
2109
2110 FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, RenderBoxModelObject* repaintContainer, bool fixed, bool* wasFixed) const
2111 {
2112     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
2113     mapLocalToContainer(repaintContainer, fixed, true, transformState, wasFixed);
2114     transformState.flatten();
2115
2116     return transformState.lastPlanarPoint();
2117 }
2118
2119 LayoutSize RenderObject::offsetFromContainer(RenderObject* o, const LayoutPoint& point) const
2120 {
2121     ASSERT(o == container());
2122
2123     LayoutSize offset;
2124
2125     o->adjustForColumns(offset, point);
2126
2127     if (o->hasOverflowClip())
2128         offset -= toRenderBox(o)->scrolledContentOffset();
2129
2130     return offset;
2131 }
2132
2133 LayoutSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
2134 {
2135     LayoutSize offset;
2136     LayoutPoint referencePoint;
2137     const RenderObject* currContainer = this;
2138     do {
2139         RenderObject* nextContainer = currContainer->container();
2140         ASSERT(nextContainer);  // This means we reached the top without finding container.
2141         if (!nextContainer)
2142             break;
2143         ASSERT(!currContainer->hasTransform());
2144         LayoutSize currentOffset = currContainer->offsetFromContainer(nextContainer, referencePoint);
2145         offset += currentOffset;
2146         referencePoint.move(currentOffset);
2147         currContainer = nextContainer;
2148     } while (currContainer != container);
2149
2150     return offset;
2151 }
2152
2153 LayoutRect RenderObject::localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine)
2154 {
2155     if (extraWidthToEndOfLine)
2156         *extraWidthToEndOfLine = 0;
2157
2158     return LayoutRect();
2159 }
2160
2161 bool RenderObject::isRooted(RenderView** view)
2162 {
2163     RenderObject* o = this;
2164     while (o->parent())
2165         o = o->parent();
2166
2167     if (!o->isRenderView())
2168         return false;
2169
2170     if (view)
2171         *view = toRenderView(o);
2172
2173     return true;
2174 }
2175
2176 RenderObject* RenderObject::rendererForRootBackground()
2177 {
2178     ASSERT(isRoot());
2179     if (!hasBackground() && node() && node()->hasTagName(HTMLNames::htmlTag)) {
2180         // Locate the <body> element using the DOM. This is easier than trying
2181         // to crawl around a render tree with potential :before/:after content and
2182         // anonymous blocks created by inline <body> tags etc. We can locate the <body>
2183         // render object very easily via the DOM.
2184         HTMLElement* body = document()->body();
2185         RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
2186         if (bodyObject)
2187             return bodyObject;
2188     }
2189     
2190     return this;
2191 }
2192
2193 RespectImageOrientationEnum RenderObject::shouldRespectImageOrientation() const
2194 {
2195     // Respect the image's orientation if it's being used as a full-page image or it's
2196     // an <img> and the setting to respect it everywhere is set.
2197     return document()->isImageDocument() || (document()->settings() && document()->settings()->shouldRespectImageOrientation() && node() && node()->hasTagName(HTMLNames::imgTag)) ? RespectImageOrientation : DoNotRespectImageOrientation;
2198 }
2199
2200 bool RenderObject::hasOutlineAnnotation() const
2201 {
2202     return node() && node()->isLink() && document()->printing();
2203 }
2204
2205 RenderObject* RenderObject::container(RenderBoxModelObject* repaintContainer, bool* repaintContainerSkipped) const
2206 {
2207     if (repaintContainerSkipped)
2208         *repaintContainerSkipped = false;
2209
2210     // This method is extremely similar to containingBlock(), but with a few notable
2211     // exceptions.
2212     // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when
2213     // the object is not part of the primary document subtree yet.
2214     // (2) For normal flow elements, it just returns the parent.
2215     // (3) For absolute positioned elements, it will return a relative positioned inline.
2216     // containingBlock() simply skips relpositioned inlines and lets an enclosing block handle
2217     // the layout of the positioned object.  This does mean that computePositionedLogicalWidth and
2218     // computePositionedLogicalHeight have to use container().
2219     RenderObject* o = parent();
2220
2221     if (isText())
2222         return o;
2223
2224     EPosition pos = m_style->position();
2225     if (pos == FixedPosition) {
2226         // container() can be called on an object that is not in the
2227         // tree yet.  We don't call view() since it will assert if it
2228         // can't get back to the canvas.  Instead we just walk as high up
2229         // as we can.  If we're in the tree, we'll get the root.  If we
2230         // aren't we'll get the root of our little subtree (most likely
2231         // we'll just return 0).
2232         // FIXME: The definition of view() has changed to not crawl up the render tree.  It might
2233         // be safe now to use it.
2234         while (o && o->parent() && !(o->hasTransform() && o->isRenderBlock())) {
2235             if (repaintContainerSkipped && o == repaintContainer)
2236                 *repaintContainerSkipped = true;
2237             o = o->parent();
2238         }
2239     } else if (pos == AbsolutePosition) {
2240         // Same goes here.  We technically just want our containing block, but
2241         // we may not have one if we're part of an uninstalled subtree.  We'll
2242         // climb as high as we can though.
2243         while (o && o->style()->position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
2244             if (repaintContainerSkipped && o == repaintContainer)
2245                 *repaintContainerSkipped = true;
2246 #if ENABLE(SVG)
2247             if (o->isSVGForeignObject()) // foreignObject is the containing block for contents inside it
2248                 break;
2249 #endif
2250             o = o->parent();
2251         }
2252     }
2253
2254     return o;
2255 }
2256
2257 bool RenderObject::isSelectionBorder() const
2258 {
2259     SelectionState st = selectionState();
2260     return st == SelectionStart || st == SelectionEnd || st == SelectionBoth;
2261 }
2262
2263 inline void RenderObject::clearLayoutRootIfNeeded() const
2264 {
2265     if (node() && !documentBeingDestroyed() && frame()) {
2266         if (FrameView* view = frame()->view()) {
2267             if (view->layoutRoot() == this) {
2268                 ASSERT_NOT_REACHED();
2269                 // This indicates a failure to layout the child, which is why
2270                 // the layout root is still set to |this|. Make sure to clear it
2271                 // since we are getting destroyed.
2272                 view->clearLayoutRoot();
2273             }
2274         }
2275     }
2276 }
2277
2278 void RenderObject::willBeDestroyed()
2279 {
2280     // Destroy any leftover anonymous children.
2281     RenderObjectChildList* children = virtualChildren();
2282     if (children)
2283         children->destroyLeftoverChildren();
2284
2285     // If this renderer is being autoscrolled, stop the autoscroll timer
2286     
2287     // FIXME: RenderObject::destroy should not get called with a renderer whose document
2288     // has a null frame, so we assert this. However, we don't want release builds to crash which is why we
2289     // check that the frame is not null.
2290     ASSERT(frame());
2291     if (frame() && frame()->eventHandler()->autoscrollRenderer() == this)
2292         frame()->eventHandler()->stopAutoscrollTimer(true);
2293
2294     if (AXObjectCache::accessibilityEnabled()) {
2295         document()->axObjectCache()->childrenChanged(this->parent());
2296         document()->axObjectCache()->remove(this);
2297     }
2298     animation()->cancelAnimations(this);
2299
2300     remove();
2301
2302 #ifndef NDEBUG
2303     if (!documentBeingDestroyed() && view() && view()->hasRenderNamedFlowThreads()) {
2304         // After remove, the object and the associated information should not be in any flow thread.
2305         const RenderNamedFlowThreadList* flowThreadList = view()->flowThreadController()->renderNamedFlowThreadList();
2306         for (RenderNamedFlowThreadList::const_iterator iter = flowThreadList->begin(); iter != flowThreadList->end(); ++iter) {
2307             const RenderNamedFlowThread* renderFlowThread = *iter;
2308             ASSERT(!renderFlowThread->hasChild(this));
2309             ASSERT(!renderFlowThread->hasChildInfo(this));
2310         }
2311     }
2312 #endif
2313
2314     // If this renderer had a parent, remove should have destroyed any counters
2315     // attached to this renderer and marked the affected other counters for
2316     // reevaluation. This apparently redundant check is here for the case when
2317     // this renderer had no parent at the time remove() was called.
2318
2319     if (hasCounterNodeMap())
2320         RenderCounter::destroyCounterNodes(this);
2321
2322     // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
2323     // be moved into RenderBoxModelObject::destroy.
2324     if (hasLayer()) {
2325         setHasLayer(false);
2326         toRenderBoxModelObject(this)->destroyLayer();
2327     }
2328
2329     setAncestorLineBoxDirty(false);
2330
2331     clearLayoutRootIfNeeded();
2332 }
2333
2334 void RenderObject::destroyAndCleanupAnonymousWrappers()
2335 {
2336     RenderObject* parent = this->parent();
2337
2338     // If the tree is destroyed or our parent is not anonymous, there is no need for a clean-up phase.
2339     if (documentBeingDestroyed() || !parent || !parent->isAnonymous()) {
2340         destroy();
2341         return;
2342     }
2343
2344     bool parentIsLeftOverAnonymousWrapper = false;
2345
2346     // Currently we only remove anonymous cells' wrapper but we should remove all unneeded
2347     // wrappers. See http://webkit.org/b/52123 as an example where this is needed.
2348     if (parent->isTableCell())
2349         parentIsLeftOverAnonymousWrapper = parent->firstChild() == this && parent->lastChild() == this;
2350
2351     destroy();
2352
2353     // WARNING: |this| is deleted here.
2354
2355     if (parentIsLeftOverAnonymousWrapper) {
2356         ASSERT(!parent->firstChild());
2357         parent->destroyAndCleanupAnonymousWrappers();
2358     }
2359 }
2360
2361 void RenderObject::destroy()
2362 {
2363     willBeDestroyed();
2364     arenaDelete(renderArena(), this);
2365 }
2366
2367 void RenderObject::arenaDelete(RenderArena* arena, void* base)
2368 {
2369     if (m_style) {
2370         for (const FillLayer* bgLayer = m_style->backgroundLayers(); bgLayer; bgLayer = bgLayer->next()) {
2371             if (StyleImage* backgroundImage = bgLayer->image())
2372                 backgroundImage->removeClient(this);
2373         }
2374
2375         for (const FillLayer* maskLayer = m_style->maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
2376             if (StyleImage* maskImage = maskLayer->image())
2377                 maskImage->removeClient(this);
2378         }
2379
2380         if (StyleImage* borderImage = m_style->borderImage().image())
2381             borderImage->removeClient(this);
2382
2383         if (StyleImage* maskBoxImage = m_style->maskBoxImage().image())
2384             maskBoxImage->removeClient(this);
2385     }
2386
2387 #ifndef NDEBUG
2388     void* savedBase = baseOfRenderObjectBeingDeleted;
2389     baseOfRenderObjectBeingDeleted = base;
2390 #endif
2391     delete this;
2392 #ifndef NDEBUG
2393     baseOfRenderObjectBeingDeleted = savedBase;
2394 #endif
2395
2396     // Recover the size left there for us by operator delete and free the memory.
2397     arena->free(*(size_t*)base, base);
2398 }
2399
2400 VisiblePosition RenderObject::positionForPoint(const LayoutPoint&)
2401 {
2402     return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
2403 }
2404
2405 void RenderObject::updateDragState(bool dragOn)
2406 {
2407     bool valueChanged = (dragOn != isDragging());
2408     setIsDragging(dragOn);
2409     if (valueChanged && style()->affectedByDragRules() && node())
2410         node()->setNeedsStyleRecalc();
2411     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
2412         curr->updateDragState(dragOn);
2413 }
2414
2415 bool RenderObject::isComposited() const
2416 {
2417     return hasLayer() && toRenderBoxModelObject(this)->layer()->isComposited();
2418 }
2419
2420 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
2421 {
2422     bool inside = false;
2423     if (hitTestFilter != HitTestSelf) {
2424         // First test the foreground layer (lines and inlines).
2425         inside = nodeAtPoint(request, result, pointInContainer, accumulatedOffset, HitTestForeground);
2426
2427         // Test floats next.
2428         if (!inside)
2429             inside = nodeAtPoint(request, result, pointInContainer, accumulatedOffset, HitTestFloat);
2430
2431         // Finally test to see if the mouse is in the background (within a child block's background).
2432         if (!inside)
2433             inside = nodeAtPoint(request, result, pointInContainer, accumulatedOffset, HitTestChildBlockBackgrounds);
2434     }
2435
2436     // See if the mouse is inside us but not any of our descendants
2437     if (hitTestFilter != HitTestDescendants && !inside)
2438         inside = nodeAtPoint(request, result, pointInContainer, accumulatedOffset, HitTestBlockBackground);
2439
2440     return inside;
2441 }
2442
2443 void RenderObject::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
2444 {
2445     if (result.innerNode())
2446         return;
2447
2448     Node* n = node();
2449     if (n) {
2450         result.setInnerNode(n);
2451         if (!result.innerNonSharedNode())
2452             result.setInnerNonSharedNode(n);
2453         result.setLocalPoint(point);
2454     }
2455 }
2456
2457 bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& /*pointInContainer*/, const LayoutPoint& /*accumulatedOffset*/, HitTestAction)
2458 {
2459     return false;
2460 }
2461
2462 void RenderObject::scheduleRelayout()
2463 {
2464     if (isRenderView()) {
2465         FrameView* view = toRenderView(this)->frameView();
2466         if (view)
2467             view->scheduleRelayout();
2468     } else {
2469         if (isRooted()) {
2470             if (RenderView* renderView = view()) {
2471                 if (FrameView* frameView = renderView->frameView())
2472                     frameView->scheduleRelayoutOfSubtree(this);
2473             }
2474         }
2475     }
2476 }
2477
2478 void RenderObject::layout()
2479 {
2480     ASSERT(needsLayout());
2481     RenderObject* child = firstChild();
2482     while (child) {
2483         child->layoutIfNeeded();
2484         ASSERT(!child->needsLayout());
2485         child = child->nextSibling();
2486     }
2487     setNeedsLayout(false);
2488 }
2489
2490 PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const
2491 {
2492     if (!document()->usesFirstLineRules())
2493         return 0;
2494
2495     ASSERT(!isText());
2496
2497     RefPtr<RenderStyle> result;
2498
2499     if (isBlockFlow()) {
2500         if (RenderBlock* firstLineBlock = this->firstLineBlock())
2501             result = firstLineBlock->getUncachedPseudoStyle(FIRST_LINE, style, firstLineBlock == this ? style : 0);
2502     } else if (!isAnonymous() && isRenderInline()) {
2503         RenderStyle* parentStyle = parent()->firstLineStyle();
2504         if (parentStyle != parent()->style())
2505             result = getUncachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle, style);
2506     }
2507
2508     return result.release();
2509 }
2510
2511 RenderStyle* RenderObject::firstLineStyleSlowCase() const
2512 {
2513     ASSERT(document()->usesFirstLineRules());
2514
2515     RenderStyle* style = m_style.get();
2516     const RenderObject* renderer = isText() ? parent() : this;
2517     if (renderer->isBlockFlow()) {
2518         if (RenderBlock* firstLineBlock = renderer->firstLineBlock())
2519             style = firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style);
2520     } else if (!renderer->isAnonymous() && renderer->isRenderInline()) {
2521         RenderStyle* parentStyle = renderer->parent()->firstLineStyle();
2522         if (parentStyle != renderer->parent()->style()) {
2523             // A first-line style is in effect. Cache a first-line style for ourselves.
2524             renderer->style()->setHasPseudoStyle(FIRST_LINE_INHERITED);
2525             style = renderer->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle);
2526         }
2527     }
2528
2529     return style;
2530 }
2531
2532 RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
2533 {
2534     if (pseudo < FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
2535         return 0;
2536
2537     RenderStyle* cachedStyle = style()->getCachedPseudoStyle(pseudo);
2538     if (cachedStyle)
2539         return cachedStyle;
2540     
2541     RefPtr<RenderStyle> result = getUncachedPseudoStyle(pseudo, parentStyle);
2542     if (result)
2543         return style()->addCachedPseudoStyle(result.release());
2544     return 0;
2545 }
2546
2547 PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle, RenderStyle* ownStyle) const
2548 {
2549     if (pseudo < FIRST_INTERNAL_PSEUDOID && !ownStyle && !style()->hasPseudoStyle(pseudo))
2550         return 0;
2551     
2552     if (!parentStyle) {
2553         ASSERT(!ownStyle);
2554         parentStyle = style();
2555     }
2556
2557     // FIXME: This "find nearest element parent" should be a helper function.
2558     Node* n = node();
2559     while (n && !n->isElementNode())
2560         n = n->parentNode();
2561     if (!n)
2562         return 0;
2563     Element* element = toElement(n);
2564
2565     if (pseudo == FIRST_LINE_INHERITED) {
2566         RefPtr<RenderStyle> result = document()->styleResolver()->styleForElement(element, parentStyle, DisallowStyleSharing);
2567         result->setStyleType(FIRST_LINE_INHERITED);
2568         return result.release();
2569     }
2570     return document()->styleResolver()->pseudoStyleForElement(pseudo, element, parentStyle);
2571 }
2572
2573 static Color decorationColor(RenderObject* renderer)
2574 {
2575     Color result;
2576     if (renderer->style()->textStrokeWidth() > 0) {
2577         // Prefer stroke color if possible but not if it's fully transparent.
2578         result = renderer->style()->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
2579         if (result.alpha())
2580             return result;
2581     }
2582     
2583     result = renderer->style()->visitedDependentColor(CSSPropertyWebkitTextFillColor);
2584     return result;
2585 }
2586
2587 void RenderObject::getTextDecorationColors(int decorations, Color& underline, Color& overline,
2588                                            Color& linethrough, bool quirksMode)
2589 {
2590     RenderObject* curr = this;
2591     do {
2592         int currDecs = curr->style()->textDecoration();
2593         if (currDecs) {
2594             if (currDecs & UNDERLINE) {
2595                 decorations &= ~UNDERLINE;
2596                 underline = decorationColor(curr);
2597             }
2598             if (currDecs & OVERLINE) {
2599                 decorations &= ~OVERLINE;
2600                 overline = decorationColor(curr);
2601             }
2602             if (currDecs & LINE_THROUGH) {
2603                 decorations &= ~LINE_THROUGH;
2604                 linethrough = decorationColor(curr);
2605             }
2606         }
2607         if (curr->isFloating() || curr->isPositioned() || curr->isRubyText())
2608             return;
2609         curr = curr->parent();
2610         if (curr && curr->isAnonymousBlock() && toRenderBlock(curr)->continuation())
2611             curr = toRenderBlock(curr)->continuation();
2612     } while (curr && decorations && (!quirksMode || !curr->node() ||
2613                                      (!curr->node()->hasTagName(aTag) && !curr->node()->hasTagName(fontTag))));
2614
2615     // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
2616     if (decorations && curr) {
2617         if (decorations & UNDERLINE)
2618             underline = decorationColor(curr);
2619         if (decorations & OVERLINE)
2620             overline = decorationColor(curr);
2621         if (decorations & LINE_THROUGH)
2622             linethrough = decorationColor(curr);
2623     }
2624 }
2625
2626 #if ENABLE(DASHBOARD_SUPPORT)
2627 void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions)
2628 {
2629     // Convert the style regions to absolute coordinates.
2630     if (style()->visibility() != VISIBLE || !isBox())
2631         return;
2632     
2633     RenderBox* box = toRenderBox(this);
2634
2635     const Vector<StyleDashboardRegion>& styleRegions = style()->dashboardRegions();
2636     unsigned i, count = styleRegions.size();
2637     for (i = 0; i < count; i++) {
2638         StyleDashboardRegion styleRegion = styleRegions[i];
2639
2640         LayoutUnit w = box->width();
2641         LayoutUnit h = box->height();
2642
2643         DashboardRegionValue region;
2644         region.label = styleRegion.label;
2645         region.bounds = LayoutRect(styleRegion.offset.left().value(),
2646                                    styleRegion.offset.top().value(),
2647                                    w - styleRegion.offset.left().value() - styleRegion.offset.right().value(),
2648                                    h - styleRegion.offset.top().value() - styleRegion.offset.bottom().value());
2649         region.type = styleRegion.type;
2650
2651         region.clip = region.bounds;
2652         computeAbsoluteRepaintRect(region.clip);
2653         if (region.clip.height() < 0) {
2654             region.clip.setHeight(0);
2655             region.clip.setWidth(0);
2656         }
2657
2658         FloatPoint absPos = localToAbsolute();
2659         region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
2660         region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
2661
2662         regions.append(region);
2663     }
2664 }
2665
2666 void RenderObject::collectDashboardRegions(Vector<DashboardRegionValue>& regions)
2667 {
2668     // RenderTexts don't have their own style, they just use their parent's style,
2669     // so we don't want to include them.
2670     if (isText())
2671         return;
2672
2673     addDashboardRegions(regions);
2674     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
2675         curr->collectDashboardRegions(regions);
2676 }
2677 #endif
2678
2679 bool RenderObject::willRenderImage(CachedImage*)
2680 {
2681     // Without visibility we won't render (and therefore don't care about animation).
2682     if (style()->visibility() != VISIBLE)
2683         return false;
2684
2685     // We will not render a new image when Active DOM is suspended
2686     if (document()->activeDOMObjectsAreSuspended())
2687         return false;
2688
2689     // 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)
2690     // then we don't want to render either.
2691     return !document()->inPageCache() && !document()->view()->isOffscreen();
2692 }
2693
2694 int RenderObject::maximalOutlineSize(PaintPhase p) const
2695 {
2696     if (p != PaintPhaseOutline && p != PaintPhaseSelfOutline && p != PaintPhaseChildOutlines)
2697         return 0;
2698     return toRenderView(document()->renderer())->maximalOutlineSize();
2699 }
2700
2701 int RenderObject::caretMinOffset() const
2702 {
2703     return 0;
2704 }
2705
2706 int RenderObject::caretMaxOffset() const
2707 {
2708     if (isReplaced())
2709         return node() ? max(1U, node()->childNodeCount()) : 1;
2710     if (isHR())
2711         return 1;
2712     return 0;
2713 }
2714
2715 int RenderObject::previousOffset(int current) const
2716 {
2717     return current - 1;
2718 }
2719
2720 int RenderObject::previousOffsetForBackwardDeletion(int current) const
2721 {
2722     return current - 1;
2723 }
2724
2725 int RenderObject::nextOffset(int current) const
2726 {
2727     return current + 1;
2728 }
2729
2730 void RenderObject::adjustRectForOutlineAndShadow(LayoutRect& rect) const
2731 {
2732     int outlineSize = outlineStyleForRepaint()->outlineSize();
2733     if (const ShadowData* boxShadow = style()->boxShadow()) {
2734         boxShadow->adjustRectForShadow(rect, outlineSize);
2735         return;
2736     }
2737
2738     rect.inflate(outlineSize);
2739 }
2740
2741 AnimationController* RenderObject::animation() const
2742 {
2743     return frame()->animation();
2744 }
2745
2746 void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
2747 {
2748     imageChanged(static_cast<WrappedImagePtr>(image), rect);
2749 }
2750
2751 RenderBoxModelObject* RenderObject::offsetParent() const
2752 {
2753     // If any of the following holds true return null and stop this algorithm:
2754     // A is the root element.
2755     // A is the HTML body element.
2756     // The computed value of the position property for element A is fixed.
2757     if (isRoot() || isBody() || (isPositioned() && style()->position() == FixedPosition))
2758         return 0;
2759
2760     // If A is an area HTML element which has a map HTML element somewhere in the ancestor
2761     // chain return the nearest ancestor map HTML element and stop this algorithm.
2762     // FIXME: Implement!
2763     
2764     // Return the nearest ancestor element of A for which at least one of the following is
2765     // true and stop this algorithm if such an ancestor is found:
2766     //     * The computed value of the position property is not static.
2767     //     * It is the HTML body element.
2768     //     * The computed value of the position property of A is static and the ancestor
2769     //       is one of the following HTML elements: td, th, or table.
2770     //     * Our own extension: if there is a difference in the effective zoom
2771
2772     bool skipTables = isPositioned() || isRelPositioned();
2773     float currZoom = style()->effectiveZoom();
2774     RenderObject* curr = parent();
2775     while (curr && (!curr->node() || (!curr->isPositioned() && !curr->isRelPositioned() && !curr->isBody()))) {
2776         Node* element = curr->node();
2777         if (!skipTables && element && (element->hasTagName(tableTag) || element->hasTagName(tdTag) || element->hasTagName(thTag)))
2778             break;
2779
2780         float newZoom = curr->style()->effectiveZoom();
2781         if (currZoom != newZoom)
2782             break;
2783         currZoom = newZoom;
2784         curr = curr->parent();
2785     }
2786     return curr && curr->isBoxModelObject() ? toRenderBoxModelObject(curr) : 0;
2787 }
2788
2789 VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity)
2790 {
2791     // If this is a non-anonymous renderer in an editable area, then it's simple.
2792     if (Node* node = this->node()) {
2793         if (!node->rendererIsEditable()) {
2794             // If it can be found, we prefer a visually equivalent position that is editable. 
2795             Position position = createLegacyEditingPosition(node, offset);
2796             Position candidate = position.downstream(CanCrossEditingBoundary);
2797             if (candidate.deprecatedNode()->rendererIsEditable())
2798                 return VisiblePosition(candidate, affinity);
2799             candidate = position.upstream(CanCrossEditingBoundary);
2800             if (candidate.deprecatedNode()->rendererIsEditable())
2801                 return VisiblePosition(candidate, affinity);
2802         }
2803         // FIXME: Eliminate legacy editing positions
2804         return VisiblePosition(createLegacyEditingPosition(node, offset), affinity);
2805     }
2806
2807     // We don't want to cross the boundary between editable and non-editable
2808     // regions of the document, but that is either impossible or at least
2809     // extremely unlikely in any normal case because we stop as soon as we
2810     // find a single non-anonymous renderer.
2811
2812     // Find a nearby non-anonymous renderer.
2813     RenderObject* child = this;
2814     while (RenderObject* parent = child->parent()) {
2815         // Find non-anonymous content after.
2816         RenderObject* renderer = child;
2817         while ((renderer = renderer->nextInPreOrder(parent))) {
2818             if (Node* node = renderer->node())
2819                 return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
2820         }
2821
2822         // Find non-anonymous content before.
2823         renderer = child;
2824         while ((renderer = renderer->previousInPreOrder())) {
2825             if (renderer == parent)
2826                 break;
2827             if (Node* node = renderer->node())
2828                 return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
2829         }
2830
2831         // Use the parent itself unless it too is anonymous.
2832         if (Node* node = parent->node())
2833             return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
2834
2835         // Repeat at the next level up.
2836         child = parent;
2837     }
2838
2839     // Everything was anonymous. Give up.
2840     return VisiblePosition();
2841 }
2842
2843 VisiblePosition RenderObject::createVisiblePosition(const Position& position)
2844 {
2845     if (position.isNotNull())
2846         return VisiblePosition(position);
2847
2848     ASSERT(!node());
2849     return createVisiblePosition(0, DOWNSTREAM);
2850 }
2851
2852 CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
2853 {
2854     return SetCursorBasedOnStyle;
2855 }
2856
2857 bool RenderObject::canUpdateSelectionOnRootLineBoxes()
2858 {
2859     if (needsLayout())
2860         return false;
2861
2862     RenderBlock* containingBlock = this->containingBlock();
2863     return containingBlock ? !containingBlock->needsLayout() : true;
2864 }
2865
2866 #if ENABLE(SVG)
2867
2868 RenderSVGResourceContainer* RenderObject::toRenderSVGResourceContainer()
2869 {
2870     ASSERT_NOT_REACHED();
2871     return 0;
2872 }
2873
2874 void RenderObject::setNeedsBoundariesUpdate()
2875 {
2876     if (RenderObject* renderer = parent())
2877         renderer->setNeedsBoundariesUpdate();
2878 }
2879
2880 FloatRect RenderObject::objectBoundingBox() const
2881 {
2882     ASSERT_NOT_REACHED();
2883     return FloatRect();
2884 }
2885
2886 FloatRect RenderObject::strokeBoundingBox() const
2887 {
2888     ASSERT_NOT_REACHED();
2889     return FloatRect();
2890 }
2891
2892 // Returns the smallest rectangle enclosing all of the painted content
2893 // respecting clipping, masking, filters, opacity, stroke-width and markers
2894 FloatRect RenderObject::repaintRectInLocalCoordinates() const
2895 {
2896     ASSERT_NOT_REACHED();
2897     return FloatRect();
2898 }
2899
2900 AffineTransform RenderObject::localTransform() const
2901 {
2902     static const AffineTransform identity;
2903     return identity;
2904 }
2905
2906 const AffineTransform& RenderObject::localToParentTransform() const
2907 {
2908     static const AffineTransform identity;
2909     return identity;
2910 }
2911
2912 bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
2913 {
2914     ASSERT_NOT_REACHED();
2915     return false;
2916 }
2917
2918 #endif // ENABLE(SVG)
2919
2920 } // namespace WebCore
2921
2922 #ifndef NDEBUG
2923
2924 void showTree(const WebCore::RenderObject* object)
2925 {
2926     if (object)
2927         object->showTreeForThis();
2928 }
2929
2930 void showLineTree(const WebCore::RenderObject* object)
2931 {
2932     if (object)
2933         object->showLineTreeForThis();
2934 }
2935
2936 void showRenderTree(const WebCore::RenderObject* object1)
2937 {
2938     showRenderTree(object1, 0);
2939 }
2940
2941 void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2)
2942 {
2943     if (object1) {
2944         const WebCore::RenderObject* root = object1;
2945         while (root->parent())
2946             root = root->parent();
2947         root->showRenderTreeAndMark(object1, "*", object2, "-", 0);
2948     }
2949 }
2950
2951 #endif