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