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