Safari crashes when calling execCommand on formatted html in special case
[WebKit-https.git] / 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 Apple Inc. All rights reserved.
7  * Copyright (C) 2009 Google Inc. All rights reserved.
8  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26
27 #include "config.h"
28 #include "RenderObject.h"
29
30 #include "AXObjectCache.h"
31 #include "CSSStyleSelector.h"
32 #include "FloatQuad.h"
33 #include "Frame.h"
34 #include "FrameView.h"
35 #include "GraphicsContext.h"
36 #include "HTMLNames.h"
37 #include "HitTestResult.h"
38 #include "Page.h"
39 #include "RenderArena.h"
40 #include "RenderCounter.h"
41 #include "RenderFlexibleBox.h"
42 #include "RenderImageGeneratedContent.h"
43 #include "RenderInline.h"
44 #include "RenderListItem.h"
45 #include "RenderRuby.h"
46 #include "RenderRubyText.h"
47 #include "RenderTableCell.h"
48 #include "RenderTableCol.h"
49 #include "RenderTableRow.h"
50 #include "RenderTheme.h"
51 #include "RenderView.h"
52 #include "TransformState.h"
53 #include "htmlediting.h"
54 #include <algorithm>
55 #include <stdio.h>
56 #include <wtf/RefCountedLeakCounter.h>
57 #include <wtf/UnusedParam.h>
58
59 #if USE(ACCELERATED_COMPOSITING)
60 #include "RenderLayerCompositor.h"
61 #endif
62
63 #if ENABLE(WML)
64 #include "WMLNames.h"
65 #endif
66
67 using namespace std;
68
69 namespace WebCore {
70
71 using namespace HTMLNames;
72
73 #ifndef NDEBUG
74 static void* baseOfRenderObjectBeingDeleted;
75 #endif
76
77 bool RenderObject::s_affectsParentBlock = false;
78
79 void* RenderObject::operator new(size_t sz, RenderArena* renderArena) throw()
80 {
81     return renderArena->allocate(sz);
82 }
83
84 void RenderObject::operator delete(void* ptr, size_t sz)
85 {
86     ASSERT(baseOfRenderObjectBeingDeleted == ptr);
87
88     // Stash size where destroy can find it.
89     *(size_t *)ptr = sz;
90 }
91
92 RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
93 {
94     Document* doc = node->document();
95     RenderArena* arena = doc->renderArena();
96
97     // Minimal support for content properties replacing an entire element.
98     // Works only if we have exactly one piece of content and it's a URL.
99     // Otherwise acts as if we didn't support this feature.
100     const ContentData* contentData = style->contentData();
101     if (contentData && !contentData->next() && contentData->isImage() && doc != node) {
102         RenderImageGeneratedContent* image = new (arena) RenderImageGeneratedContent(node);
103         image->setStyle(style);
104         if (StyleImage* styleImage = contentData->image())
105             image->setStyleImage(styleImage);
106         return image;
107     }
108
109     if (node->hasTagName(rubyTag)) {
110         if (style->display() == INLINE)
111             return new (arena) RenderRubyAsInline(node);
112         else
113             return new (arena) RenderRubyAsBlock(node);
114     }
115     // treat <rt> as ruby text ONLY if it still has its default treatment of block
116     if (node->hasTagName(rtTag) && style->display() == BLOCK)
117         return new (arena) RenderRubyText(node); 
118
119     switch (style->display()) {
120         case NONE:
121             return 0;
122         case INLINE:
123             return new (arena) RenderInline(node);
124         case BLOCK:
125         case INLINE_BLOCK:
126         case RUN_IN:
127         case COMPACT:
128             return new (arena) RenderBlock(node);
129         case LIST_ITEM:
130             return new (arena) RenderListItem(node);
131         case TABLE:
132         case INLINE_TABLE:
133             return new (arena) RenderTable(node);
134         case TABLE_ROW_GROUP:
135         case TABLE_HEADER_GROUP:
136         case TABLE_FOOTER_GROUP:
137             return new (arena) RenderTableSection(node);
138         case TABLE_ROW:
139             return new (arena) RenderTableRow(node);
140         case TABLE_COLUMN_GROUP:
141         case TABLE_COLUMN:
142             return new (arena) RenderTableCol(node);
143         case TABLE_CELL:
144             return new (arena) RenderTableCell(node);
145         case TABLE_CAPTION:
146 #if ENABLE(WCSS)
147         // As per the section 17.1 of the spec WAP-239-WCSS-20011026-a.pdf, 
148         // the marquee box inherits and extends the characteristics of the 
149         // principal block box ([CSS2] section 9.2.1).
150         case WAP_MARQUEE:
151 #endif
152             return new (arena) RenderBlock(node);
153         case BOX:
154         case INLINE_BOX:
155             return new (arena) RenderFlexibleBox(node);
156     }
157
158     return 0;
159 }
160
161 #ifndef NDEBUG 
162 static WTF::RefCountedLeakCounter renderObjectCounter("RenderObject");
163 #endif
164
165 RenderObject::RenderObject(Node* node)
166     : CachedResourceClient()
167     , m_style(0)
168     , m_node(node)
169     , m_parent(0)
170     , m_previous(0)
171     , m_next(0)
172 #ifndef NDEBUG
173     , m_hasAXObject(false)
174     , m_setNeedsLayoutForbidden(false)
175 #endif
176     , m_needsLayout(false)
177     , m_needsPositionedMovementLayout(false)
178     , m_normalChildNeedsLayout(false)
179     , m_posChildNeedsLayout(false)
180     , m_prefWidthsDirty(false)
181     , m_floating(false)
182     , m_positioned(false)
183     , m_relPositioned(false)
184     , m_paintBackground(false)
185     , m_isAnonymous(node == node->document())
186     , m_isText(false)
187     , m_isBox(false)
188     , m_inline(true)
189     , m_replaced(false)
190     , m_isDragging(false)
191     , m_hasLayer(false)
192     , m_hasOverflowClip(false)
193     , m_hasTransform(false)
194     , m_hasReflection(false)
195     , m_hasOverrideSize(false)
196     , m_hasCounterNodeMap(false)
197     , m_everHadLayout(false)
198     , m_childrenInline(false)
199     , m_topMarginQuirk(false) 
200     , m_bottomMarginQuirk(false)
201     , m_hasMarkupTruncation(false)
202     , m_selectionState(SelectionNone)
203     , m_hasColumns(false)
204     , m_cellWidthChanged(false)
205 {
206 #ifndef NDEBUG
207     renderObjectCounter.increment();
208 #endif
209     ASSERT(node);
210 }
211
212 RenderObject::~RenderObject()
213 {
214     ASSERT(!node() || documentBeingDestroyed() || !document()->frame()->view() || document()->frame()->view()->layoutRoot() != this);
215 #ifndef NDEBUG
216     ASSERT(!m_hasAXObject);
217     renderObjectCounter.decrement();
218 #endif
219 }
220
221 RenderTheme* RenderObject::theme() const
222 {
223     ASSERT(document()->page());
224
225     return document()->page()->theme();
226 }
227
228 bool RenderObject::isDescendantOf(const RenderObject* obj) const
229 {
230     for (const RenderObject* r = this; r; r = r->m_parent) {
231         if (r == obj)
232             return true;
233     }
234     return false;
235 }
236
237 bool RenderObject::isBody() const
238 {
239     return node() && node()->hasTagName(bodyTag);
240 }
241
242 bool RenderObject::isHR() const
243 {
244     return node() && node()->hasTagName(hrTag);
245 }
246
247 bool RenderObject::isHTMLMarquee() const
248 {
249     return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);
250 }
251
252 static void updateListMarkerNumbers(RenderObject* child)
253 {
254     for (RenderObject* sibling = child; sibling; sibling = sibling->nextSibling()) {
255         if (sibling->isListItem())
256             toRenderListItem(sibling)->updateValue();
257     }
258 }
259
260 void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
261 {
262     RenderObjectChildList* children = virtualChildren();
263     ASSERT(children);
264     if (!children)
265         return;
266
267     bool needsTable = false;
268
269     if (newChild->isListItem())
270         updateListMarkerNumbers(beforeChild ? beforeChild : children->lastChild());
271     else if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
272         needsTable = !isTable();
273     else if (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
274         needsTable = !isTable();
275     else if (newChild->isTableSection())
276         needsTable = !isTable();
277     else if (newChild->isTableRow())
278         needsTable = !isTableSection();
279     else if (newChild->isTableCell()) {
280         needsTable = !isTableRow();
281         // I'm not 100% sure this is the best way to fix this, but without this
282         // change we recurse infinitely when trying to render the CSS2 test page:
283         // http://www.bath.ac.uk/%7Epy8ieh/internet/eviltests/htmlbodyheadrendering2.html.
284         // See Radar 2925291.
285         if (needsTable && isTableCell() && !children->firstChild() && !newChild->isTableCell())
286             needsTable = false;
287     }
288
289     if (needsTable) {
290         RenderTable* table;
291         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : children->lastChild();
292         if (afterChild && afterChild->isAnonymous() && afterChild->isTable())
293             table = toRenderTable(afterChild);
294         else {
295             table = new (renderArena()) RenderTable(document() /* is anonymous */);
296             RefPtr<RenderStyle> newStyle = RenderStyle::create();
297             newStyle->inheritFrom(style());
298             newStyle->setDisplay(TABLE);
299             table->setStyle(newStyle.release());
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         RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalText();
310         if (textToTransform)
311             toRenderText(newChild)->setText(textToTransform.release(), true);
312     }
313 }
314
315 void RenderObject::removeChild(RenderObject* oldChild)
316 {
317     RenderObjectChildList* children = virtualChildren();
318     ASSERT(children);
319     if (!children)
320         return;
321
322     // We do this here instead of in removeChildNode, since the only extremely low-level uses of remove/appendChildNode
323     // cannot affect the positioned object list, and the floating object list is irrelevant (since the list gets cleared on
324     // layout anyway).
325     if (oldChild->isFloatingOrPositioned())
326         toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
327         
328     children->removeChildNode(this, oldChild);
329 }
330
331 RenderObject* RenderObject::nextInPreOrder() const
332 {
333     if (RenderObject* o = firstChild())
334         return o;
335
336     return nextInPreOrderAfterChildren();
337 }
338
339 RenderObject* RenderObject::nextInPreOrderAfterChildren() const
340 {
341     RenderObject* o;
342     if (!(o = nextSibling())) {
343         o = parent();
344         while (o && !o->nextSibling())
345             o = o->parent();
346         if (o)
347             o = o->nextSibling();
348     }
349
350     return o;
351 }
352
353 RenderObject* RenderObject::nextInPreOrder(RenderObject* stayWithin) const
354 {
355     if (RenderObject* o = firstChild())
356         return o;
357
358     return nextInPreOrderAfterChildren(stayWithin);
359 }
360
361 RenderObject* RenderObject::nextInPreOrderAfterChildren(RenderObject* stayWithin) const
362 {
363     if (this == stayWithin)
364         return 0;
365
366     RenderObject* o;
367     if (!(o = nextSibling())) {
368         o = parent();
369         while (o && !o->nextSibling()) {
370             if (o == stayWithin)
371                 return 0;
372             o = o->parent();
373         }
374         if (o)
375             o = o->nextSibling();
376     }
377
378     return o;
379 }
380
381 RenderObject* RenderObject::previousInPreOrder() const
382 {
383     if (RenderObject* o = previousSibling()) {
384         while (o->lastChild())
385             o = o->lastChild();
386         return o;
387     }
388
389     return parent();
390 }
391
392 RenderObject* RenderObject::childAt(unsigned index) const
393 {
394     RenderObject* child = firstChild();
395     for (unsigned i = 0; child && i < index; i++)
396         child = child->nextSibling();
397     return child;
398 }
399
400 RenderObject* RenderObject::firstLeafChild() const
401 {
402     RenderObject* r = firstChild();
403     while (r) {
404         RenderObject* n = 0;
405         n = r->firstChild();
406         if (!n)
407             break;
408         r = n;
409     }
410     return r;
411 }
412
413 RenderObject* RenderObject::lastLeafChild() const
414 {
415     RenderObject* r = lastChild();
416     while (r) {
417         RenderObject* n = 0;
418         n = r->lastChild();
419         if (!n)
420             break;
421         r = n;
422     }
423     return r;
424 }
425
426 static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject*& newObject,
427                       RenderLayer*& beforeChild)
428 {
429     if (obj->hasLayer()) {
430         if (!beforeChild && newObject) {
431             // We need to figure out the layer that follows newObject.  We only do
432             // this the first time we find a child layer, and then we update the
433             // pointer values for newObject and beforeChild used by everyone else.
434             beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject);
435             newObject = 0;
436         }
437         parentLayer->addChild(toRenderBoxModelObject(obj)->layer(), beforeChild);
438         return;
439     }
440
441     for (RenderObject* curr = obj->firstChild(); curr; curr = curr->nextSibling())
442         addLayers(curr, parentLayer, newObject, beforeChild);
443 }
444
445 void RenderObject::addLayers(RenderLayer* parentLayer, RenderObject* newObject)
446 {
447     if (!parentLayer)
448         return;
449
450     RenderObject* object = newObject;
451     RenderLayer* beforeChild = 0;
452     WebCore::addLayers(this, parentLayer, object, beforeChild);
453 }
454
455 void RenderObject::removeLayers(RenderLayer* parentLayer)
456 {
457     if (!parentLayer)
458         return;
459
460     if (hasLayer()) {
461         parentLayer->removeChild(toRenderBoxModelObject(this)->layer());
462         return;
463     }
464
465     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
466         curr->removeLayers(parentLayer);
467 }
468
469 void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
470 {
471     if (!newParent)
472         return;
473
474     if (hasLayer()) {
475         RenderLayer* layer = toRenderBoxModelObject(this)->layer();
476         ASSERT(oldParent == layer->parent());
477         if (oldParent)
478             oldParent->removeChild(layer);
479         newParent->addChild(layer);
480         return;
481     }
482
483     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
484         curr->moveLayers(oldParent, newParent);
485 }
486
487 RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint,
488                                          bool checkParent)
489 {
490     // Error check the parent layer passed in.  If it's null, we can't find anything.
491     if (!parentLayer)
492         return 0;
493
494     // Step 1: If our layer is a child of the desired parent, then return our layer.
495     RenderLayer* ourLayer = hasLayer() ? toRenderBoxModelObject(this)->layer() : 0;
496     if (ourLayer && ourLayer->parent() == parentLayer)
497         return ourLayer;
498
499     // Step 2: If we don't have a layer, or our layer is the desired parent, then descend
500     // into our siblings trying to find the next layer whose parent is the desired parent.
501     if (!ourLayer || ourLayer == parentLayer) {
502         for (RenderObject* curr = startPoint ? startPoint->nextSibling() : firstChild();
503              curr; curr = curr->nextSibling()) {
504             RenderLayer* nextLayer = curr->findNextLayer(parentLayer, 0, false);
505             if (nextLayer)
506                 return nextLayer;
507         }
508     }
509
510     // Step 3: If our layer is the desired parent layer, then we're finished.  We didn't
511     // find anything.
512     if (parentLayer == ourLayer)
513         return 0;
514
515     // Step 4: If |checkParent| is set, climb up to our parent and check its siblings that
516     // follow us to see if we can locate a layer.
517     if (checkParent && parent())
518         return parent()->findNextLayer(parentLayer, this, true);
519
520     return 0;
521 }
522
523 RenderLayer* RenderObject::enclosingLayer() const
524 {
525     const RenderObject* curr = this;
526     while (curr) {
527         RenderLayer* layer = curr->hasLayer() ? toRenderBoxModelObject(curr)->layer() : 0;
528         if (layer)
529             return layer;
530         curr = curr->parent();
531     }
532     return 0;
533 }
534
535 RenderLayer* RenderObject::enclosingSelfPaintingLayer() const
536 {
537     const RenderObject* curr = this;
538     while (curr) {
539         RenderLayer* layer = curr->hasLayer() ? toRenderBoxModelObject(curr)->layer() : 0;
540         if (layer && layer->isSelfPaintingLayer())
541             return layer;
542         curr = curr->parent();
543     }
544     return 0;
545 }
546
547 RenderBox* RenderObject::enclosingBox() const
548 {
549     RenderObject* curr = const_cast<RenderObject*>(this);
550     while (curr) {
551         if (curr->isBox())
552             return toRenderBox(curr);
553         curr = curr->parent();
554     }
555     
556     ASSERT_NOT_REACHED();
557     return 0;
558 }
559
560 RenderBlock* RenderObject::firstLineBlock() const
561 {
562     return 0;
563 }
564
565 void RenderObject::setPrefWidthsDirty(bool b, bool markParents)
566 {
567     bool alreadyDirty = m_prefWidthsDirty;
568     m_prefWidthsDirty = b;
569     if (b && !alreadyDirty && markParents && (isText() || (style()->position() != FixedPosition && style()->position() != AbsolutePosition)))
570         invalidateContainerPrefWidths();
571 }
572
573 void RenderObject::invalidateContainerPrefWidths()
574 {
575     // In order to avoid pathological behavior when inlines are deeply nested, we do include them
576     // in the chain that we mark dirty (even though they're kind of irrelevant).
577     RenderObject* o = isTableCell() ? containingBlock() : container();
578     while (o && !o->m_prefWidthsDirty) {
579         // Don't invalidate the outermost object of an unrooted subtree. That object will be 
580         // invalidated when the subtree is added to the document.
581         RenderObject* container = o->isTableCell() ? o->containingBlock() : o->container();
582         if (!container && !o->isRenderView())
583             break;
584
585         o->m_prefWidthsDirty = true;
586         if (o->style()->position() == FixedPosition || o->style()->position() == AbsolutePosition)
587             // A positioned object has no effect on the min/max width of its containing block ever.
588             // We can optimize this case and not go up any further.
589             break;
590         o = container;
591     }
592 }
593
594 void RenderObject::setLayerNeedsFullRepaint()
595 {
596     ASSERT(hasLayer());
597     toRenderBoxModelObject(this)->layer()->setNeedsFullRepaint(true);
598 }
599
600 RenderBlock* RenderObject::containingBlock() const
601 {
602     if (isTableCell()) {
603         const RenderTableCell* cell = toRenderTableCell(this);
604         if (parent() && cell->section())
605             return cell->table();
606         return 0;
607     }
608
609     if (isRenderView())
610         return const_cast<RenderView*>(toRenderView(this));
611
612     RenderObject* o = parent();
613     if (!isText() && m_style->position() == FixedPosition) {
614         while (o && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock()))
615             o = o->parent();
616     } else if (!isText() && m_style->position() == AbsolutePosition) {
617         while (o && (o->style()->position() == StaticPosition || (o->isInline() && !o->isReplaced())) && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
618             // For relpositioned inlines, we return the nearest enclosing block.  We don't try
619             // to return the inline itself.  This allows us to avoid having a positioned objects
620             // list in all RenderInlines and lets us return a strongly-typed RenderBlock* result
621             // from this method.  The container() method can actually be used to obtain the
622             // inline directly.
623             if (o->style()->position() == RelativePosition && o->isInline() && !o->isReplaced())
624                 return o->containingBlock();
625 #if ENABLE(SVG)
626             if (o->isSVGForeignObject()) //foreignObject is the containing block for contents inside it
627                 break;
628 #endif
629
630             o = o->parent();
631         }
632     } else {
633         while (o && ((o->isInline() && !o->isReplaced()) || o->isTableRow() || o->isTableSection()
634                      || o->isTableCol() || o->isFrameSet() || o->isMedia()
635 #if ENABLE(SVG)
636                      || o->isSVGContainer() || o->isSVGRoot()
637 #endif
638                      ))
639             o = o->parent();
640     }
641
642     if (!o || !o->isRenderBlock())
643         return 0; // This can still happen in case of an orphaned tree
644
645     return toRenderBlock(o);
646 }
647
648 static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* layer)
649 {
650     // Nobody will use multiple layers without wanting fancy positioning.
651     if (layer->next())
652         return true;
653
654     // Make sure we have a valid image.
655     StyleImage* img = layer->image();
656     if (!img || !img->canRender(renderer->style()->effectiveZoom()))
657         return false;
658
659     if (!layer->xPosition().isZero() || !layer->yPosition().isZero())
660         return true;
661
662     if (layer->size().type == SizeLength) {
663         if (layer->size().size.width().isPercent() || layer->size().size.height().isPercent())
664             return true;
665     } else if (layer->size().type == Contain || layer->size().type == Cover || img->usesImageContainerSize())
666         return true;
667
668     return false;
669 }
670
671 bool RenderObject::mustRepaintBackgroundOrBorder() const
672 {
673     if (hasMask() && mustRepaintFillLayers(this, style()->maskLayers()))
674         return true;
675
676     // If we don't have a background/border/mask, then nothing to do.
677     if (!hasBoxDecorations())
678         return false;
679
680     if (mustRepaintFillLayers(this, style()->backgroundLayers()))
681         return true;
682      
683     // Our fill layers are ok.  Let's check border.
684     if (style()->hasBorder()) {
685         // Border images are not ok.
686         StyleImage* borderImage = style()->borderImage().image();
687         bool shouldPaintBorderImage = borderImage && borderImage->canRender(style()->effectiveZoom());
688
689         // If the image hasn't loaded, we're still using the normal border style.
690         if (shouldPaintBorderImage && borderImage->isLoaded())
691             return true;
692     }
693
694     return false;
695 }
696
697 void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
698                                       BoxSide s, Color c, const Color& textcolor, EBorderStyle style,
699                                       int adjbw1, int adjbw2)
700 {
701     int width = (s == BSTop || s == BSBottom ? y2 - y1 : x2 - x1);
702
703     if (style == DOUBLE && width < 3)
704         style = SOLID;
705
706     if (!c.isValid()) {
707         if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE)
708             c.setRGB(238, 238, 238);
709         else
710             c = textcolor;
711     }
712
713     switch (style) {
714         case BNONE:
715         case BHIDDEN:
716             return;
717         case DOTTED:
718         case DASHED:
719             graphicsContext->setStrokeColor(c);
720             graphicsContext->setStrokeThickness(width);
721             graphicsContext->setStrokeStyle(style == DASHED ? DashedStroke : DottedStroke);
722
723             if (width > 0)
724                 switch (s) {
725                     case BSBottom:
726                     case BSTop:
727                         graphicsContext->drawLine(IntPoint(x1, (y1 + y2) / 2), IntPoint(x2, (y1 + y2) / 2));
728                         break;
729                     case BSRight:
730                     case BSLeft:
731                         graphicsContext->drawLine(IntPoint((x1 + x2) / 2, y1), IntPoint((x1 + x2) / 2, y2));
732                         break;
733                 }
734             break;
735         case DOUBLE: {
736             int third = (width + 1) / 3;
737
738             if (adjbw1 == 0 && adjbw2 == 0) {
739                 graphicsContext->setStrokeStyle(NoStroke);
740                 graphicsContext->setFillColor(c);
741                 switch (s) {
742                     case BSTop:
743                     case BSBottom:
744                         graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, third));
745                         graphicsContext->drawRect(IntRect(x1, y2 - third, x2 - x1, third));
746                         break;
747                     case BSLeft:
748                         graphicsContext->drawRect(IntRect(x1, y1 + 1, third, y2 - y1 - 1));
749                         graphicsContext->drawRect(IntRect(x2 - third, y1 + 1, third, y2 - y1 - 1));
750                         break;
751                     case BSRight:
752                         graphicsContext->drawRect(IntRect(x1, y1 + 1, third, y2 - y1 - 1));
753                         graphicsContext->drawRect(IntRect(x2 - third, y1 + 1, third, y2 - y1 - 1));
754                         break;
755                 }
756             } else {
757                 int adjbw1bigthird = ((adjbw1 > 0) ? adjbw1 + 1 : adjbw1 - 1) / 3;
758                 int adjbw2bigthird = ((adjbw2 > 0) ? adjbw2 + 1 : adjbw2 - 1) / 3;
759
760                 switch (s) {
761                     case BSTop:
762                         drawLineForBoxSide(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
763                                    y1, x2 - max((-adjbw2 * 2 + 1) / 3, 0), y1 + third,
764                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
765                         drawLineForBoxSide(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
766                                    y2 - third, x2 - max((adjbw2 * 2 + 1) / 3, 0), y2,
767                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
768                         break;
769                     case BSLeft:
770                         drawLineForBoxSide(graphicsContext, x1, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
771                                    x1 + third, y2 - max((-adjbw2 * 2 + 1) / 3, 0),
772                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
773                         drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((adjbw1 * 2 + 1) / 3, 0),
774                                    x2, y2 - max((adjbw2 * 2 + 1) / 3, 0),
775                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
776                         break;
777                     case BSBottom:
778                         drawLineForBoxSide(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
779                                    y1, x2 - max((adjbw2 * 2 + 1) / 3, 0), y1 + third,
780                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
781                         drawLineForBoxSide(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
782                                    y2 - third, x2 - max((-adjbw2 * 2 + 1) / 3, 0), y2,
783                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
784                         break;
785                     case BSRight:
786                         drawLineForBoxSide(graphicsContext, x1, y1 + max((adjbw1 * 2 + 1) / 3, 0),
787                                    x1 + third, y2 - max((adjbw2 * 2 + 1) / 3, 0),
788                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
789                         drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
790                                    x2, y2 - max((-adjbw2 * 2 + 1) / 3, 0),
791                                    s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
792                         break;
793                     default:
794                         break;
795                 }
796             }
797             break;
798         }
799         case RIDGE:
800         case GROOVE:
801         {
802             EBorderStyle s1;
803             EBorderStyle s2;
804             if (style == GROOVE) {
805                 s1 = INSET;
806                 s2 = OUTSET;
807             } else {
808                 s1 = OUTSET;
809                 s2 = INSET;
810             }
811
812             int adjbw1bighalf = ((adjbw1 > 0) ? adjbw1 + 1 : adjbw1 - 1) / 2;
813             int adjbw2bighalf = ((adjbw2 > 0) ? adjbw2 + 1 : adjbw2 - 1) / 2;
814
815             switch (s) {
816                 case BSTop:
817                     drawLineForBoxSide(graphicsContext, x1 + max(-adjbw1, 0) / 2, y1, x2 - max(-adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
818                                s, c, textcolor, s1, adjbw1bighalf, adjbw2bighalf);
819                     drawLineForBoxSide(graphicsContext, x1 + max(adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(adjbw2 + 1, 0) / 2, y2,
820                                s, c, textcolor, s2, adjbw1 / 2, adjbw2 / 2);
821                     break;
822                 case BSLeft:
823                     drawLineForBoxSide(graphicsContext, x1, y1 + max(-adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(-adjbw2, 0) / 2,
824                                s, c, textcolor, s1, adjbw1bighalf, adjbw2bighalf);
825                     drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(adjbw1 + 1, 0) / 2, x2, y2 - max(adjbw2 + 1, 0) / 2,
826                                s, c, textcolor, s2, adjbw1 / 2, adjbw2 / 2);
827                     break;
828                 case BSBottom:
829                     drawLineForBoxSide(graphicsContext, x1 + max(adjbw1, 0) / 2, y1, x2 - max(adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
830                                s, c, textcolor, s2, adjbw1bighalf, adjbw2bighalf);
831                     drawLineForBoxSide(graphicsContext, x1 + max(-adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(-adjbw2 + 1, 0) / 2, y2,
832                                s, c, textcolor, s1, adjbw1/2, adjbw2/2);
833                     break;
834                 case BSRight:
835                     drawLineForBoxSide(graphicsContext, x1, y1 + max(adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(adjbw2, 0) / 2,
836                                s, c, textcolor, s2, adjbw1bighalf, adjbw2bighalf);
837                     drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(-adjbw1 + 1, 0) / 2, x2, y2 - max(-adjbw2 + 1, 0) / 2,
838                                s, c, textcolor, s1, adjbw1/2, adjbw2/2);
839                     break;
840             }
841             break;
842         }
843         case INSET:
844             if (s == BSTop || s == BSLeft)
845                 c = c.dark();
846             // fall through
847         case OUTSET:
848             if (style == OUTSET && (s == BSBottom || s == BSRight))
849                 c = c.dark();
850             // fall through
851         case SOLID: {
852             graphicsContext->setStrokeStyle(NoStroke);
853             graphicsContext->setFillColor(c);
854             ASSERT(x2 >= x1);
855             ASSERT(y2 >= y1);
856             if (!adjbw1 && !adjbw2) {
857                 graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, y2 - y1));
858                 return;
859             }
860             FloatPoint quad[4];
861             switch (s) {
862                 case BSTop:
863                     quad[0] = FloatPoint(x1 + max(-adjbw1, 0), y1);
864                     quad[1] = FloatPoint(x1 + max(adjbw1, 0), y2);
865                     quad[2] = FloatPoint(x2 - max(adjbw2, 0), y2);
866                     quad[3] = FloatPoint(x2 - max(-adjbw2, 0), y1);
867                     break;
868                 case BSBottom:
869                     quad[0] = FloatPoint(x1 + max(adjbw1, 0), y1);
870                     quad[1] = FloatPoint(x1 + max(-adjbw1, 0), y2);
871                     quad[2] = FloatPoint(x2 - max(-adjbw2, 0), y2);
872                     quad[3] = FloatPoint(x2 - max(adjbw2, 0), y1);
873                     break;
874                 case BSLeft:
875                     quad[0] = FloatPoint(x1, y1 + max(-adjbw1, 0));
876                     quad[1] = FloatPoint(x1, y2 - max(-adjbw2, 0));
877                     quad[2] = FloatPoint(x2, y2 - max(adjbw2, 0));
878                     quad[3] = FloatPoint(x2, y1 + max(adjbw1, 0));
879                     break;
880                 case BSRight:
881                     quad[0] = FloatPoint(x1, y1 + max(adjbw1, 0));
882                     quad[1] = FloatPoint(x1, y2 - max(adjbw2, 0));
883                     quad[2] = FloatPoint(x2, y2 - max(-adjbw2, 0));
884                     quad[3] = FloatPoint(x2, y1 + max(-adjbw1, 0));
885                     break;
886             }
887             graphicsContext->drawConvexPolygon(4, quad);
888             break;
889         }
890     }
891 }
892
893 void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, int y, float thickness, IntSize radius,
894                                      int angleStart, int angleSpan, BoxSide s, Color c, const Color& textColor,
895                                      EBorderStyle style, bool firstCorner)
896 {
897     if ((style == DOUBLE && thickness / 2 < 3) || ((style == RIDGE || style == GROOVE) && thickness / 2 < 2))
898         style = SOLID;
899
900     if (!c.isValid()) {
901         if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE)
902             c.setRGB(238, 238, 238);
903         else
904             c = textColor;
905     }
906
907     switch (style) {
908         case BNONE:
909         case BHIDDEN:
910             return;
911         case DOTTED:
912         case DASHED:
913             graphicsContext->setStrokeColor(c);
914             graphicsContext->setStrokeStyle(style == DOTTED ? DottedStroke : DashedStroke);
915             graphicsContext->setStrokeThickness(thickness);
916             graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
917             break;
918         case DOUBLE: {
919             float third = thickness / 3.0f;
920             float innerThird = (thickness + 1.0f) / 6.0f;
921             int shiftForInner = static_cast<int>(innerThird * 2.5f);
922
923             int outerY = y;
924             int outerHeight = radius.height() * 2;
925             int innerX = x + shiftForInner;
926             int innerY = y + shiftForInner;
927             int innerWidth = (radius.width() - shiftForInner) * 2;
928             int innerHeight = (radius.height() - shiftForInner) * 2;
929             if (innerThird > 1 && (s == BSTop || (firstCorner && (s == BSLeft || s == BSRight)))) {
930                 outerHeight += 2;
931                 innerHeight += 2;
932             }
933
934             graphicsContext->setStrokeStyle(SolidStroke);
935             graphicsContext->setStrokeColor(c);
936             graphicsContext->setStrokeThickness(third);
937             graphicsContext->strokeArc(IntRect(x, outerY, radius.width() * 2, outerHeight), angleStart, angleSpan);
938             graphicsContext->setStrokeThickness(innerThird > 2 ? innerThird - 1 : innerThird);
939             graphicsContext->strokeArc(IntRect(innerX, innerY, innerWidth, innerHeight), angleStart, angleSpan);
940             break;
941         }
942         case GROOVE:
943         case RIDGE: {
944             Color c2;
945             if ((style == RIDGE && (s == BSTop || s == BSLeft)) ||
946                     (style == GROOVE && (s == BSBottom || s == BSRight)))
947                 c2 = c.dark();
948             else {
949                 c2 = c;
950                 c = c.dark();
951             }
952
953             graphicsContext->setStrokeStyle(SolidStroke);
954             graphicsContext->setStrokeColor(c);
955             graphicsContext->setStrokeThickness(thickness);
956             graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
957
958             float halfThickness = (thickness + 1.0f) / 4.0f;
959             int shiftForInner = static_cast<int>(halfThickness * 1.5f);
960             graphicsContext->setStrokeColor(c2);
961             graphicsContext->setStrokeThickness(halfThickness > 2 ? halfThickness - 1 : halfThickness);
962             graphicsContext->strokeArc(IntRect(x + shiftForInner, y + shiftForInner, (radius.width() - shiftForInner) * 2,
963                                        (radius.height() - shiftForInner) * 2), angleStart, angleSpan);
964             break;
965         }
966         case INSET:
967             if (s == BSTop || s == BSLeft)
968                 c = c.dark();
969         case OUTSET:
970             if (style == OUTSET && (s == BSBottom || s == BSRight))
971                 c = c.dark();
972         case SOLID:
973             graphicsContext->setStrokeStyle(SolidStroke);
974             graphicsContext->setStrokeColor(c);
975             graphicsContext->setStrokeThickness(thickness);
976             graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
977             break;
978     }
979 }
980
981 void RenderObject::addPDFURLRect(GraphicsContext* context, const IntRect& rect)
982 {
983     if (rect.isEmpty())
984         return;
985     Node* n = node();
986     if (!n || !n->isLink() || !n->isElementNode())
987         return;
988     const AtomicString& href = static_cast<Element*>(n)->getAttribute(hrefAttr);
989     if (href.isNull())
990         return;
991     context->setURLForRect(n->document()->completeURL(href), rect);
992 }
993
994 void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style)
995 {
996     if (!hasOutline())
997         return;
998
999     int ow = style->outlineWidth();
1000     EBorderStyle os = style->outlineStyle();
1001
1002     Color oc = style->outlineColor();
1003     if (!oc.isValid())
1004         oc = style->color();
1005
1006     int offset = style->outlineOffset();
1007
1008     if (style->outlineStyleIsAuto() || hasOutlineAnnotation()) {
1009         if (!theme()->supportsFocusRing(style)) {
1010             // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
1011             graphicsContext->initFocusRing(ow, offset);
1012             addFocusRingRects(graphicsContext, tx, ty);
1013             if (style->outlineStyleIsAuto())
1014                 graphicsContext->drawFocusRing(oc);
1015             else
1016                 addPDFURLRect(graphicsContext, graphicsContext->focusRingBoundingRect());
1017             graphicsContext->clearFocusRing();
1018         }
1019     }
1020
1021     if (style->outlineStyleIsAuto() || style->outlineStyle() == BNONE)
1022         return;
1023
1024     tx -= offset;
1025     ty -= offset;
1026     w += 2 * offset;
1027     h += 2 * offset;
1028
1029     if (h < 0 || w < 0)
1030         return;
1031
1032     drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx, ty + h + ow,
1033                BSLeft, Color(oc), style->color(), os, ow, ow);
1034
1035     drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx + w + ow, ty,
1036                BSTop, Color(oc), style->color(), os, ow, ow);
1037
1038     drawLineForBoxSide(graphicsContext, tx + w, ty - ow, tx + w + ow, ty + h + ow,
1039                BSRight, Color(oc), style->color(), os, ow, ow);
1040
1041     drawLineForBoxSide(graphicsContext, tx - ow, ty + h, tx + w + ow, ty + h + ow,
1042                BSBottom, Color(oc), style->color(), os, ow, ow);
1043 }
1044
1045 IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms)
1046 {
1047     if (useTransforms) {
1048         Vector<FloatQuad> quads;
1049         absoluteQuads(quads);
1050
1051         size_t n = quads.size();
1052         if (!n)
1053             return IntRect();
1054     
1055         IntRect result = quads[0].enclosingBoundingBox();
1056         for (size_t i = 1; i < n; ++i)
1057             result.unite(quads[i].enclosingBoundingBox());
1058         return result;
1059     }
1060
1061     FloatPoint absPos = localToAbsolute();
1062     Vector<IntRect> rects;
1063     absoluteRects(rects, absPos.x(), absPos.y());
1064
1065     size_t n = rects.size();
1066     if (!n)
1067         return IntRect();
1068
1069     IntRect result = rects[0];
1070     for (size_t i = 1; i < n; ++i)
1071         result.unite(rects[i]);
1072     return result;
1073 }
1074
1075 void RenderObject::addAbsoluteRectForLayer(IntRect& result)
1076 {
1077     if (hasLayer())
1078         result.unite(absoluteBoundingBoxRect());
1079     for (RenderObject* current = firstChild(); current; current = current->nextSibling())
1080         current->addAbsoluteRectForLayer(result);
1081 }
1082
1083 IntRect RenderObject::paintingRootRect(IntRect& topLevelRect)
1084 {
1085     IntRect result = absoluteBoundingBoxRect();
1086     topLevelRect = result;
1087     for (RenderObject* current = firstChild(); current; current = current->nextSibling())
1088         current->addAbsoluteRectForLayer(result);
1089     return result;
1090 }
1091
1092 void RenderObject::paint(PaintInfo& /*paintInfo*/, int /*tx*/, int /*ty*/)
1093 {
1094 }
1095
1096 RenderBoxModelObject* RenderObject::containerForRepaint() const
1097 {
1098 #if USE(ACCELERATED_COMPOSITING)
1099     if (RenderView* v = view()) {
1100         if (v->usesCompositing()) {
1101             RenderLayer* compLayer = enclosingLayer()->enclosingCompositingLayer();
1102             return compLayer ? compLayer->renderer() : 0;
1103         }
1104     }
1105 #endif
1106     // Do root-relative repaint.
1107     return 0;
1108 }
1109
1110 void RenderObject::repaintUsingContainer(RenderBoxModelObject* repaintContainer, const IntRect& r, bool immediate)
1111 {
1112     if (!repaintContainer || repaintContainer->isRenderView()) {
1113         RenderView* v = repaintContainer ? toRenderView(repaintContainer) : view();
1114         v->repaintViewRectangle(r, immediate);
1115     } else {
1116 #if USE(ACCELERATED_COMPOSITING)
1117         RenderView* v = view();
1118         if (v->usesCompositing()) {
1119             ASSERT(repaintContainer->hasLayer() && repaintContainer->layer()->isComposited());
1120             repaintContainer->layer()->setBackingNeedsRepaintInRect(r);
1121         }
1122 #else
1123         ASSERT_NOT_REACHED();
1124 #endif
1125     }
1126 }
1127
1128 void RenderObject::repaint(bool immediate)
1129 {
1130     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1131     RenderView* view;
1132     if (!isRooted(&view))
1133         return;
1134
1135     if (view->printing())
1136         return; // Don't repaint if we're printing.
1137
1138     RenderBoxModelObject* repaintContainer = containerForRepaint();
1139     repaintUsingContainer(repaintContainer ? repaintContainer : view, clippedOverflowRectForRepaint(repaintContainer), immediate);
1140 }
1141
1142 void RenderObject::repaintRectangle(const IntRect& r, bool immediate)
1143 {
1144     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1145     RenderView* view;
1146     if (!isRooted(&view))
1147         return;
1148
1149     if (view->printing())
1150         return; // Don't repaint if we're printing.
1151
1152     IntRect dirtyRect(r);
1153
1154     // FIXME: layoutDelta needs to be applied in parts before/after transforms and
1155     // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
1156     dirtyRect.move(view->layoutDelta());
1157
1158     RenderBoxModelObject* repaintContainer = containerForRepaint();
1159     computeRectForRepaint(repaintContainer, dirtyRect);
1160     repaintUsingContainer(repaintContainer ? repaintContainer : view, dirtyRect, immediate);
1161 }
1162
1163 bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox)
1164 {
1165     RenderView* v = view();
1166     if (v->printing())
1167         return false; // Don't repaint if we're printing.
1168
1169     IntRect newBounds = clippedOverflowRectForRepaint(repaintContainer);
1170     IntRect newOutlineBox;
1171
1172     bool fullRepaint = selfNeedsLayout();
1173     // Presumably a background or a border exists if border-fit:lines was specified.
1174     if (!fullRepaint && style()->borderFit() == BorderFitLines)
1175         fullRepaint = true;
1176     if (!fullRepaint) {
1177         newOutlineBox = outlineBoundsForRepaint(repaintContainer);
1178         if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
1179             fullRepaint = true;
1180     }
1181
1182     if (!repaintContainer)
1183         repaintContainer = v;
1184
1185     if (fullRepaint) {
1186         repaintUsingContainer(repaintContainer, oldBounds);
1187         if (newBounds != oldBounds)
1188             repaintUsingContainer(repaintContainer, newBounds);
1189         return true;
1190     }
1191
1192     if (newBounds == oldBounds && newOutlineBox == oldOutlineBox)
1193         return false;
1194
1195     int deltaLeft = newBounds.x() - oldBounds.x();
1196     if (deltaLeft > 0)
1197         repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
1198     else if (deltaLeft < 0)
1199         repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
1200
1201     int deltaRight = newBounds.right() - oldBounds.right();
1202     if (deltaRight > 0)
1203         repaintUsingContainer(repaintContainer, IntRect(oldBounds.right(), newBounds.y(), deltaRight, newBounds.height()));
1204     else if (deltaRight < 0)
1205         repaintUsingContainer(repaintContainer, IntRect(newBounds.right(), oldBounds.y(), -deltaRight, oldBounds.height()));
1206
1207     int deltaTop = newBounds.y() - oldBounds.y();
1208     if (deltaTop > 0)
1209         repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
1210     else if (deltaTop < 0)
1211         repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
1212
1213     int deltaBottom = newBounds.bottom() - oldBounds.bottom();
1214     if (deltaBottom > 0)
1215         repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), oldBounds.bottom(), newBounds.width(), deltaBottom));
1216     else if (deltaBottom < 0)
1217         repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), newBounds.bottom(), oldBounds.width(), -deltaBottom));
1218
1219     if (newOutlineBox == oldOutlineBox)
1220         return false;
1221
1222     // We didn't move, but we did change size.  Invalidate the delta, which will consist of possibly
1223     // two rectangles (but typically only one).
1224     RenderStyle* outlineStyle = outlineStyleForRepaint();
1225     int ow = outlineStyle->outlineSize();
1226     int width = abs(newOutlineBox.width() - oldOutlineBox.width());
1227     if (width) {
1228         int shadowLeft;
1229         int shadowRight;
1230         style()->getBoxShadowHorizontalExtent(shadowLeft, shadowRight);
1231
1232         int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0;
1233         int borderWidth = max(-outlineStyle->outlineOffset(), max(borderRight, max(style()->borderTopRightRadius().width(), style()->borderBottomRightRadius().width()))) + max(ow, shadowRight);
1234         IntRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - borderWidth,
1235             newOutlineBox.y(),
1236             width + borderWidth,
1237             max(newOutlineBox.height(), oldOutlineBox.height()));
1238         int right = min(newBounds.right(), oldBounds.right());
1239         if (rightRect.x() < right) {
1240             rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
1241             repaintUsingContainer(repaintContainer, rightRect);
1242         }
1243     }
1244     int height = abs(newOutlineBox.height() - oldOutlineBox.height());
1245     if (height) {
1246         int shadowTop;
1247         int shadowBottom;
1248         style()->getBoxShadowVerticalExtent(shadowTop, shadowBottom);
1249
1250         int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0;
1251         int borderHeight = max(-outlineStyle->outlineOffset(), max(borderBottom, max(style()->borderBottomLeftRadius().height(), style()->borderBottomRightRadius().height()))) + max(ow, shadowBottom);
1252         IntRect bottomRect(newOutlineBox.x(),
1253             min(newOutlineBox.bottom(), oldOutlineBox.bottom()) - borderHeight,
1254             max(newOutlineBox.width(), oldOutlineBox.width()),
1255             height + borderHeight);
1256         int bottom = min(newBounds.bottom(), oldBounds.bottom());
1257         if (bottomRect.y() < bottom) {
1258             bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
1259             repaintUsingContainer(repaintContainer, bottomRect);
1260         }
1261     }
1262     return false;
1263 }
1264
1265 void RenderObject::repaintDuringLayoutIfMoved(const IntRect&)
1266 {
1267 }
1268
1269 void RenderObject::repaintOverhangingFloats(bool)
1270 {
1271 }
1272
1273 bool RenderObject::checkForRepaintDuringLayout() const
1274 {
1275     // FIXME: <https://bugs.webkit.org/show_bug.cgi?id=20885> It is probably safe to also require
1276     // m_everHadLayout. Currently, only RenderBlock::layoutBlock() adds this condition. See also
1277     // <https://bugs.webkit.org/show_bug.cgi?id=15129>.
1278     return !document()->view()->needsFullRepaint() && !hasLayer();
1279 }
1280
1281 IntRect RenderObject::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
1282 {
1283     IntRect r(clippedOverflowRectForRepaint(repaintContainer));
1284     r.inflate(outlineWidth);
1285     return r;
1286 }
1287
1288 IntRect RenderObject::clippedOverflowRectForRepaint(RenderBoxModelObject*)
1289 {
1290     ASSERT_NOT_REACHED();
1291     return IntRect();
1292 }
1293
1294 void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
1295 {
1296     if (repaintContainer == this)
1297         return;
1298
1299     if (RenderObject* o = parent()) {
1300         if (o->isBlockFlow()) {
1301             RenderBlock* cb = toRenderBlock(o);
1302             if (cb->hasColumns())
1303                 cb->adjustRectForColumns(rect);
1304         }
1305
1306         if (o->hasOverflowClip()) {
1307             // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the
1308             // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint
1309             // anyway if its size does change.
1310             RenderBox* boxParent = toRenderBox(o);
1311
1312             IntRect boxRect(0, 0, boxParent->layer()->width(), boxParent->layer()->height());
1313             int x = rect.x();
1314             int y = rect.y();
1315             boxParent->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
1316             IntRect repaintRect(x, y, rect.width(), rect.height());
1317             rect = intersection(repaintRect, boxRect);
1318             if (rect.isEmpty())
1319                 return;
1320         }
1321
1322         o->computeRectForRepaint(repaintContainer, rect, fixed);
1323     }
1324 }
1325
1326 void RenderObject::dirtyLinesFromChangedChild(RenderObject*)
1327 {
1328 }
1329
1330 #ifndef NDEBUG
1331
1332 void RenderObject::showTreeForThis() const
1333 {
1334     if (node())
1335         node()->showTreeForThis();
1336 }
1337
1338 #endif // NDEBUG
1339
1340 Color RenderObject::selectionBackgroundColor() const
1341 {
1342     Color color;
1343     if (style()->userSelect() != SELECT_NONE) {
1344          RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION);
1345         if (pseudoStyle && pseudoStyle->backgroundColor().isValid())
1346             color = pseudoStyle->backgroundColor().blendWithWhite();
1347         else
1348             color = document()->frame()->selection()->isFocusedAndActive() ?
1349                     theme()->activeSelectionBackgroundColor() :
1350                     theme()->inactiveSelectionBackgroundColor();
1351     }
1352
1353     return color;
1354 }
1355
1356 Color RenderObject::selectionForegroundColor() const
1357 {
1358     Color color;
1359     if (style()->userSelect() == SELECT_NONE)
1360         return color;
1361
1362     if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION)) {
1363         color = pseudoStyle->textFillColor();
1364         if (!color.isValid())
1365             color = pseudoStyle->color();
1366     } else
1367         color = document()->frame()->selection()->isFocusedAndActive() ?
1368                 theme()->activeSelectionForegroundColor() :
1369                 theme()->inactiveSelectionForegroundColor();
1370
1371     return color;
1372 }
1373
1374 #if ENABLE(DRAG_SUPPORT)
1375 Node* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const
1376 {
1377     if (!dhtmlOK && !uaOK)
1378         return 0;
1379
1380     for (const RenderObject* curr = this; curr; curr = curr->parent()) {
1381         Node* elt = curr->node();
1382         if (elt && elt->nodeType() == Node::TEXT_NODE) {
1383             // Since there's no way for the author to address the -webkit-user-drag style for a text node,
1384             // we use our own judgement.
1385             if (uaOK && view()->frameView()->frame()->eventHandler()->shouldDragAutoNode(curr->node(), IntPoint(x, y))) {
1386                 dhtmlWillDrag = false;
1387                 return curr->node();
1388             }
1389             if (elt->canStartSelection())
1390                 // In this case we have a click in the unselected portion of text.  If this text is
1391                 // selectable, we want to start the selection process instead of looking for a parent
1392                 // to try to drag.
1393                 return 0;
1394         } else {
1395             EUserDrag dragMode = curr->style()->userDrag();
1396             if (dhtmlOK && dragMode == DRAG_ELEMENT) {
1397                 dhtmlWillDrag = true;
1398                 return curr->node();
1399             }
1400             if (uaOK && dragMode == DRAG_AUTO
1401                     && view()->frameView()->frame()->eventHandler()->shouldDragAutoNode(curr->node(), IntPoint(x, y))) {
1402                 dhtmlWillDrag = false;
1403                 return curr->node();
1404             }
1405         }
1406     }
1407     return 0;
1408 }
1409 #endif // ENABLE(DRAG_SUPPORT)
1410
1411 void RenderObject::selectionStartEnd(int& spos, int& epos) const
1412 {
1413     view()->selectionStartEnd(spos, epos);
1414 }
1415
1416 void RenderObject::handleDynamicFloatPositionChange()
1417 {
1418     // We have gone from not affecting the inline status of the parent flow to suddenly
1419     // having an impact.  See if there is a mismatch between the parent flow's
1420     // childrenInline() state and our state.
1421     setInline(style()->isDisplayInlineType());
1422     if (isInline() != parent()->childrenInline()) {
1423         if (!isInline())
1424             toRenderBoxModelObject(parent())->childBecameNonInline(this);
1425         else {
1426             // An anonymous block must be made to wrap this inline.
1427             RenderBlock* block = toRenderBlock(parent())->createAnonymousBlock();
1428             RenderObjectChildList* childlist = parent()->virtualChildren();
1429             childlist->insertChildNode(parent(), block, this);
1430             block->children()->appendChildNode(block, childlist->removeChildNode(parent(), this));
1431         }
1432     }
1433 }
1434
1435 void RenderObject::setAnimatableStyle(PassRefPtr<RenderStyle> style)
1436 {
1437     if (!isText() && style)
1438         setStyle(animation()->updateAnimations(this, style.get()));
1439     else
1440         setStyle(style);
1441 }
1442
1443 StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
1444 {
1445 #if USE(ACCELERATED_COMPOSITING)
1446     // If transform changed, and we are not composited, need to do a layout.
1447     if (contextSensitiveProperties & ContextSensitivePropertyTransform) {
1448         // Text nodes share style with their parents but transforms don't apply to them,
1449         // hence the !isText() check.
1450         // FIXME: when transforms are taken into account for overflow, we will need to do a layout.
1451         if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited()))
1452             diff = StyleDifferenceLayout;
1453         else if (diff < StyleDifferenceRecompositeLayer)
1454             diff = StyleDifferenceRecompositeLayer;
1455     }
1456
1457     // If opacity changed, and we are not composited, need to repaint (also
1458     // ignoring text nodes)
1459     if (contextSensitiveProperties & ContextSensitivePropertyOpacity) {
1460         if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited()))
1461             diff = StyleDifferenceRepaintLayer;
1462         else if (diff < StyleDifferenceRecompositeLayer)
1463             diff = StyleDifferenceRecompositeLayer;
1464     }
1465 #else
1466     UNUSED_PARAM(contextSensitiveProperties);
1467 #endif
1468
1469     // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
1470     if (diff == StyleDifferenceRepaintLayer && !hasLayer())
1471         diff = StyleDifferenceRepaint;
1472
1473     return diff;
1474 }
1475
1476 void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
1477 {
1478     if (m_style == style)
1479         return;
1480
1481     StyleDifference diff = StyleDifferenceEqual;
1482     unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
1483     if (m_style)
1484         diff = m_style->diff(style.get(), contextSensitiveProperties);
1485
1486     diff = adjustStyleDifference(diff, contextSensitiveProperties);
1487
1488     styleWillChange(diff, style.get());
1489     
1490     RefPtr<RenderStyle> oldStyle = m_style.release();
1491     m_style = style;
1492
1493     updateFillImages(oldStyle ? oldStyle->backgroundLayers() : 0, m_style ? m_style->backgroundLayers() : 0);
1494     updateFillImages(oldStyle ? oldStyle->maskLayers() : 0, m_style ? m_style->maskLayers() : 0);
1495
1496     updateImage(oldStyle ? oldStyle->borderImage().image() : 0, m_style ? m_style->borderImage().image() : 0);
1497     updateImage(oldStyle ? oldStyle->maskBoxImage().image() : 0, m_style ? m_style->maskBoxImage().image() : 0);
1498
1499     // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen
1500     // during styleDidChange (it's used by clippedOverflowRectForRepaint()).
1501     if (m_style->outlineWidth() > 0 && m_style->outlineSize() > maximalOutlineSize(PaintPhaseOutline))
1502         toRenderView(document()->renderer())->setMaximalOutlineSize(m_style->outlineSize());
1503
1504     styleDidChange(diff, oldStyle.get());
1505
1506     if (!m_parent || isText())
1507         return;
1508
1509     // Now that the layer (if any) has been updated, we need to adjust the diff again,
1510     // check whether we should layout now, and decide if we need to repaint.
1511     StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
1512     
1513     if (diff <= StyleDifferenceLayoutPositionedMovementOnly) {
1514         if (updatedDiff == StyleDifferenceLayout)
1515             setNeedsLayoutAndPrefWidthsRecalc();
1516         else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly)
1517             setNeedsPositionedMovementLayout();
1518     }
1519     
1520     if (updatedDiff == StyleDifferenceRepaintLayer || updatedDiff == StyleDifferenceRepaint) {
1521         // Do a repaint with the new style now, e.g., for example if we go from
1522         // not having an outline to having an outline.
1523         repaint();
1524     }
1525 }
1526
1527 void RenderObject::setStyleInternal(PassRefPtr<RenderStyle> style)
1528 {
1529     m_style = style;
1530 }
1531
1532 void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
1533 {
1534     if (m_style) {
1535         // If our z-index changes value or our visibility changes,
1536         // we need to dirty our stacking context's z-order list.
1537         if (newStyle) {
1538             bool visibilityChanged = m_style->visibility() != newStyle->visibility() 
1539                 || m_style->zIndex() != newStyle->zIndex() 
1540                 || m_style->hasAutoZIndex() != newStyle->hasAutoZIndex();
1541 #if ENABLE(DASHBOARD_SUPPORT)
1542             if (visibilityChanged)
1543                 document()->setDashboardRegionsDirty(true);
1544 #endif
1545             if (visibilityChanged && AXObjectCache::accessibilityEnabled())
1546                 document()->axObjectCache()->childrenChanged(this);
1547
1548             // Keep layer hierarchy visibility bits up to date if visibility changes.
1549             if (m_style->visibility() != newStyle->visibility()) {
1550                 if (RenderLayer* l = enclosingLayer()) {
1551                     if (newStyle->visibility() == VISIBLE)
1552                         l->setHasVisibleContent(true);
1553                     else if (l->hasVisibleContent() && (this == l->renderer() || l->renderer()->style()->visibility() != VISIBLE)) {
1554                         l->dirtyVisibleContentStatus();
1555                         if (diff > StyleDifferenceRepaintLayer)
1556                             repaint();
1557                     }
1558                 }
1559             }
1560         }
1561
1562         if (m_parent && (diff == StyleDifferenceRepaint || newStyle->outlineSize() < m_style->outlineSize()))
1563             repaint();
1564         if (isFloating() && (m_style->floating() != newStyle->floating()))
1565             // For changes in float styles, we need to conceivably remove ourselves
1566             // from the floating objects list.
1567             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
1568         else if (isPositioned() && (m_style->position() != newStyle->position()))
1569             // For changes in positioning styles, we need to conceivably remove ourselves
1570             // from the positioned objects list.
1571             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
1572
1573         s_affectsParentBlock = isFloatingOrPositioned() &&
1574             (!newStyle->isFloating() && newStyle->position() != AbsolutePosition && newStyle->position() != FixedPosition)
1575             && parent() && (parent()->isBlockFlow() || parent()->isRenderInline());
1576
1577         // reset style flags
1578         if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositionedMovementOnly) {
1579             m_floating = false;
1580             m_positioned = false;
1581             m_relPositioned = false;
1582         }
1583         m_paintBackground = false;
1584         m_hasOverflowClip = false;
1585         m_hasTransform = false;
1586         m_hasReflection = false;
1587     } else
1588         s_affectsParentBlock = false;
1589
1590     if (view()->frameView()) {
1591         // FIXME: A better solution would be to only invalidate the fixed regions when scrolling.  It's overkill to
1592         // prevent the entire view from blitting on a scroll.
1593         bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition || newStyle->hasFixedBackgroundImage());
1594         bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition || m_style->hasFixedBackgroundImage());
1595         if (oldStyleSlowScroll != newStyleSlowScroll) {
1596             if (oldStyleSlowScroll)
1597                 view()->frameView()->removeSlowRepaintObject();
1598             if (newStyleSlowScroll)
1599                 view()->frameView()->addSlowRepaintObject();
1600         }
1601     }
1602 }
1603
1604 void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle*)
1605 {
1606     if (s_affectsParentBlock)
1607         handleDynamicFloatPositionChange();
1608
1609     if (!m_parent)
1610         return;
1611     
1612     if (diff == StyleDifferenceLayout)
1613         setNeedsLayoutAndPrefWidthsRecalc();
1614     else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
1615         setNeedsPositionedMovementLayout();
1616
1617     // Don't check for repaint here; we need to wait until the layer has been
1618     // updated by subclasses before we know if we have to repaint (in setStyle()).
1619 }
1620
1621 void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers)
1622 {
1623     // Optimize the common case
1624     if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && (oldLayers->image() == newLayers->image()))
1625         return;
1626     
1627     // Go through the new layers and addClients first, to avoid removing all clients of an image.
1628     for (const FillLayer* currNew = newLayers; currNew; currNew = currNew->next()) {
1629         if (currNew->image())
1630             currNew->image()->addClient(this);
1631     }
1632
1633     for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) {
1634         if (currOld->image())
1635             currOld->image()->removeClient(this);
1636     }
1637 }
1638
1639 void RenderObject::updateImage(StyleImage* oldImage, StyleImage* newImage)
1640 {
1641     if (oldImage != newImage) {
1642         if (oldImage)
1643             oldImage->removeClient(this);
1644         if (newImage)
1645             newImage->addClient(this);
1646     }
1647 }
1648
1649 IntRect RenderObject::viewRect() const
1650 {
1651     return view()->viewRect();
1652 }
1653
1654 FloatPoint RenderObject::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
1655 {
1656     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1657     mapLocalToContainer(0, fixed, useTransforms, transformState);
1658     transformState.flatten();
1659     
1660     return transformState.lastPlanarPoint();
1661 }
1662
1663 FloatPoint RenderObject::absoluteToLocal(FloatPoint containerPoint, bool fixed, bool useTransforms) const
1664 {
1665     TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
1666     mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
1667     transformState.flatten();
1668     
1669     return transformState.lastPlanarPoint();
1670 }
1671
1672 void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
1673 {
1674     if (repaintContainer == this)
1675         return;
1676
1677     RenderObject* o = parent();
1678     if (!o)
1679         return;
1680
1681     if (o->hasOverflowClip())
1682         transformState.move(-toRenderBox(o)->layer()->scrolledContentOffset());
1683
1684     o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
1685 }
1686
1687 void RenderObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
1688 {
1689     RenderObject* o = parent();
1690     if (o) {
1691         o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
1692         if (o->hasOverflowClip())
1693             transformState.move(toRenderBox(o)->layer()->scrolledContentOffset());
1694     }
1695 }
1696
1697 bool RenderObject::shouldUseTransformFromContainer(const RenderObject* containerObject) const
1698 {
1699 #if ENABLE(3D_RENDERING)
1700     // hasTransform() indicates whether the object has transform, transform-style or perspective. We just care about transform,
1701     // so check the layer's transform directly.
1702     return (hasLayer() && toRenderBoxModelObject(this)->layer()->transform()) || (containerObject && containerObject->style()->hasPerspective());
1703 #else
1704     UNUSED_PARAM(containerObject);
1705     return hasTransform();
1706 #endif
1707 }
1708
1709 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const IntSize& offsetInContainer, TransformationMatrix& transform) const
1710 {
1711     transform.makeIdentity();
1712     transform.translate(offsetInContainer.width(), offsetInContainer.height());
1713     RenderLayer* layer;
1714     if (hasLayer() && (layer = toRenderBoxModelObject(this)->layer()) && layer->transform())
1715         transform.multLeft(layer->currentTransform());
1716     
1717 #if ENABLE(3D_RENDERING)
1718     if (containerObject && containerObject->hasLayer() && containerObject->style()->hasPerspective()) {
1719         // Perpsective on the container affects us, so we have to factor it in here.
1720         ASSERT(containerObject->hasLayer());
1721         FloatPoint perspectiveOrigin = toRenderBox(containerObject)->layer()->perspectiveOrigin();
1722
1723         TransformationMatrix perspectiveMatrix;
1724         perspectiveMatrix.applyPerspective(containerObject->style()->perspective());
1725         
1726         transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
1727         transform.multiply(perspectiveMatrix);
1728         transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
1729     }
1730 #else
1731     UNUSED_PARAM(containerObject);
1732 #endif
1733 }
1734
1735 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool fixed) const
1736 {
1737     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint(), &localQuad);
1738     mapLocalToContainer(repaintContainer, fixed, true, transformState);
1739     transformState.flatten();
1740     
1741     return transformState.lastPlanarQuad();
1742 }
1743
1744 IntSize RenderObject::offsetFromContainer(RenderObject* o) const
1745 {
1746     ASSERT(o == container());
1747
1748     IntSize offset;
1749     if (o->hasOverflowClip())
1750         offset -= toRenderBox(o)->layer()->scrolledContentOffset();
1751
1752     return offset;
1753 }
1754
1755 IntSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
1756 {
1757     IntSize offset;
1758     const RenderObject* currContainer = this;
1759     do {
1760         RenderObject* nextContainer = currContainer->container();
1761         ASSERT(nextContainer);  // This means we reached the top without finding container.
1762         if (!nextContainer)
1763             break;
1764         ASSERT(!currContainer->hasTransform());
1765         offset += currContainer->offsetFromContainer(nextContainer);
1766         currContainer = nextContainer;
1767     } while (currContainer != container);
1768
1769     return offset;
1770 }
1771
1772 IntRect RenderObject::localCaretRect(InlineBox*, int, int* extraWidthToEndOfLine)
1773 {
1774     if (extraWidthToEndOfLine)
1775         *extraWidthToEndOfLine = 0;
1776
1777     return IntRect();
1778 }
1779
1780 RenderView* RenderObject::view() const
1781 {
1782     return toRenderView(document()->renderer());
1783 }
1784
1785 bool RenderObject::isRooted(RenderView** view)
1786 {
1787     RenderObject* o = this;
1788     while (o->parent())
1789         o = o->parent();
1790
1791     if (!o->isRenderView())
1792         return false;
1793
1794     if (view)
1795         *view = toRenderView(o);
1796
1797     return true;
1798 }
1799
1800 bool RenderObject::hasOutlineAnnotation() const
1801 {
1802     return node() && node()->isLink() && document()->printing();
1803 }
1804
1805 RenderObject* RenderObject::container(RenderBoxModelObject* repaintContainer, bool* repaintContainerSkipped) const
1806 {
1807     if (repaintContainerSkipped)
1808         *repaintContainerSkipped = false;
1809
1810     // This method is extremely similar to containingBlock(), but with a few notable
1811     // exceptions.
1812     // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when
1813     // the object is not part of the primary document subtree yet.
1814     // (2) For normal flow elements, it just returns the parent.
1815     // (3) For absolute positioned elements, it will return a relative positioned inline.
1816     // containingBlock() simply skips relpositioned inlines and lets an enclosing block handle
1817     // the layout of the positioned object.  This does mean that calcAbsoluteHorizontal and
1818     // calcAbsoluteVertical have to use container().
1819     RenderObject* o = parent();
1820
1821     if (isText())
1822         return o;
1823
1824     EPosition pos = m_style->position();
1825     if (pos == FixedPosition) {
1826         // container() can be called on an object that is not in the
1827         // tree yet.  We don't call view() since it will assert if it
1828         // can't get back to the canvas.  Instead we just walk as high up
1829         // as we can.  If we're in the tree, we'll get the root.  If we
1830         // aren't we'll get the root of our little subtree (most likely
1831         // we'll just return 0).
1832         // FIXME: The definition of view() has changed to not crawl up the render tree.  It might
1833         // be safe now to use it.
1834         while (o && o->parent() && !(o->hasTransform() && o->isRenderBlock())) {
1835             if (repaintContainerSkipped && o == repaintContainer)
1836                 *repaintContainerSkipped = true;
1837             o = o->parent();
1838         }
1839     } else if (pos == AbsolutePosition) {
1840         // Same goes here.  We technically just want our containing block, but
1841         // we may not have one if we're part of an uninstalled subtree.  We'll
1842         // climb as high as we can though.
1843         while (o && o->style()->position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
1844             if (repaintContainerSkipped && o == repaintContainer)
1845                 *repaintContainerSkipped = true;
1846             o = o->parent();
1847         }
1848     }
1849
1850     return o;
1851 }
1852
1853 bool RenderObject::isSelectionBorder() const
1854 {
1855     SelectionState st = selectionState();
1856     return st == SelectionStart || st == SelectionEnd || st == SelectionBoth;
1857 }
1858
1859 void RenderObject::destroy()
1860 {
1861     // Destroy any leftover anonymous children.
1862     RenderObjectChildList* children = virtualChildren();
1863     if (children)
1864         children->destroyLeftoverChildren();
1865
1866     // If this renderer is being autoscrolled, stop the autoscroll timer
1867     
1868     // FIXME: RenderObject::destroy should not get called with a renderar whose document
1869     // has a null frame, so we assert this. However, we don't want release builds to crash which is why we
1870     // check that the frame is not null.
1871     ASSERT(document()->frame());
1872     if (document()->frame() && document()->frame()->eventHandler()->autoscrollRenderer() == this)
1873         document()->frame()->eventHandler()->stopAutoscrollTimer(true);
1874
1875     if (m_hasCounterNodeMap)
1876         RenderCounter::destroyCounterNodes(this);
1877
1878     if (AXObjectCache::accessibilityEnabled()) {
1879         document()->axObjectCache()->childrenChanged(this->parent());
1880         document()->axObjectCache()->remove(this);
1881     }
1882     animation()->cancelAnimations(this);
1883
1884     // By default no ref-counting. RenderWidget::destroy() doesn't call
1885     // this function because it needs to do ref-counting. If anything
1886     // in this function changes, be sure to fix RenderWidget::destroy() as well.
1887
1888     remove();
1889
1890     // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
1891     // be moved into RenderBoxModelObject::destroy.
1892     if (hasLayer()) {
1893         setHasLayer(false);
1894         toRenderBoxModelObject(this)->destroyLayer();
1895     }
1896     arenaDelete(renderArena(), this);
1897 }
1898
1899 void RenderObject::arenaDelete(RenderArena* arena, void* base)
1900 {
1901     if (m_style) {
1902         for (const FillLayer* bgLayer = m_style->backgroundLayers(); bgLayer; bgLayer = bgLayer->next()) {
1903             if (StyleImage* backgroundImage = bgLayer->image())
1904                 backgroundImage->removeClient(this);
1905         }
1906
1907         for (const FillLayer* maskLayer = m_style->maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
1908             if (StyleImage* maskImage = maskLayer->image())
1909                 maskImage->removeClient(this);
1910         }
1911
1912         if (StyleImage* borderImage = m_style->borderImage().image())
1913             borderImage->removeClient(this);
1914
1915         if (StyleImage* maskBoxImage = m_style->maskBoxImage().image())
1916             maskBoxImage->removeClient(this);
1917     }
1918
1919 #ifndef NDEBUG
1920     void* savedBase = baseOfRenderObjectBeingDeleted;
1921     baseOfRenderObjectBeingDeleted = base;
1922 #endif
1923     delete this;
1924 #ifndef NDEBUG
1925     baseOfRenderObjectBeingDeleted = savedBase;
1926 #endif
1927
1928     // Recover the size left there for us by operator delete and free the memory.
1929     arena->free(*(size_t*)base, base);
1930 }
1931
1932 VisiblePosition RenderObject::positionForCoordinates(int x, int y)
1933 {
1934     return positionForPoint(IntPoint(x, y));
1935 }
1936
1937 VisiblePosition RenderObject::positionForPoint(const IntPoint&)
1938 {
1939     return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
1940 }
1941
1942 void RenderObject::updateDragState(bool dragOn)
1943 {
1944     bool valueChanged = (dragOn != m_isDragging);
1945     m_isDragging = dragOn;
1946     if (valueChanged && style()->affectedByDragRules())
1947         node()->setNeedsStyleRecalc();
1948     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
1949         curr->updateDragState(dragOn);
1950 }
1951
1952 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const IntPoint& point, int tx, int ty, HitTestFilter hitTestFilter)
1953 {
1954     bool inside = false;
1955     if (hitTestFilter != HitTestSelf) {
1956         // First test the foreground layer (lines and inlines).
1957         inside = nodeAtPoint(request, result, point.x(), point.y(), tx, ty, HitTestForeground);
1958
1959         // Test floats next.
1960         if (!inside)
1961             inside = nodeAtPoint(request, result, point.x(), point.y(), tx, ty, HitTestFloat);
1962
1963         // Finally test to see if the mouse is in the background (within a child block's background).
1964         if (!inside)
1965             inside = nodeAtPoint(request, result, point.x(), point.y(), tx, ty, HitTestChildBlockBackgrounds);
1966     }
1967
1968     // See if the mouse is inside us but not any of our descendants
1969     if (hitTestFilter != HitTestDescendants && !inside)
1970         inside = nodeAtPoint(request, result, point.x(), point.y(), tx, ty, HitTestBlockBackground);
1971
1972     return inside;
1973 }
1974
1975 void RenderObject::updateHitTestResult(HitTestResult& result, const IntPoint& point)
1976 {
1977     if (result.innerNode())
1978         return;
1979
1980     Node* n = node();
1981     if (n) {
1982         result.setInnerNode(n);
1983         if (!result.innerNonSharedNode())
1984             result.setInnerNonSharedNode(n);
1985         result.setLocalPoint(point);
1986     }
1987 }
1988
1989 bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int /*x*/, int /*y*/, int /*tx*/, int /*ty*/, HitTestAction)
1990 {
1991     return false;
1992 }
1993
1994 int RenderObject::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
1995 {
1996     return style(firstLine)->computedLineHeight();
1997 }
1998
1999 int RenderObject::baselinePosition(bool firstLine, bool isRootLineBox) const
2000 {
2001     const Font& f = style(firstLine)->font();
2002     return f.ascent() + (lineHeight(firstLine, isRootLineBox) - f.height()) / 2;
2003 }
2004
2005 void RenderObject::scheduleRelayout()
2006 {
2007     if (isRenderView()) {
2008         FrameView* view = toRenderView(this)->frameView();
2009         if (view)
2010             view->scheduleRelayout();
2011     } else if (parent()) {
2012         FrameView* v = view() ? view()->frameView() : 0;
2013         if (v)
2014             v->scheduleRelayoutOfSubtree(this);
2015     }
2016 }
2017
2018 void RenderObject::layout()
2019 {
2020     ASSERT(needsLayout());
2021     RenderObject* child = firstChild();
2022     while (child) {
2023         child->layoutIfNeeded();
2024         ASSERT(!child->needsLayout());
2025         child = child->nextSibling();
2026     }
2027     setNeedsLayout(false);
2028 }
2029
2030 PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const
2031 {
2032     if (!document()->usesFirstLineRules())
2033         return 0;
2034
2035     ASSERT(!isText());
2036
2037     RefPtr<RenderStyle> result;
2038
2039     if (isBlockFlow()) {
2040         if (RenderBlock* firstLineBlock = this->firstLineBlock())
2041             result = firstLineBlock->getUncachedPseudoStyle(FIRST_LINE, style, firstLineBlock == this ? style : 0);
2042     } else if (!isAnonymous() && isRenderInline()) {
2043         RenderStyle* parentStyle = parent()->firstLineStyle();
2044         if (parentStyle != parent()->style())
2045             result = getUncachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle, style);
2046     }
2047
2048     return result.release();
2049 }
2050
2051 RenderStyle* RenderObject::firstLineStyleSlowCase() const
2052 {
2053     ASSERT(document()->usesFirstLineRules());
2054
2055     RenderStyle* style = m_style.get();
2056     const RenderObject* renderer = isText() ? parent() : this;
2057     if (renderer->isBlockFlow()) {
2058         if (RenderBlock* firstLineBlock = renderer->firstLineBlock())
2059             style = firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style);
2060     } else if (!renderer->isAnonymous() && renderer->isRenderInline()) {
2061         RenderStyle* parentStyle = renderer->parent()->firstLineStyle();
2062         if (parentStyle != renderer->parent()->style()) {
2063             // A first-line style is in effect. Cache a first-line style for ourselves.
2064             style->setHasPseudoStyle(FIRST_LINE_INHERITED);
2065             style = renderer->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle);
2066         }
2067     }
2068
2069     return style;
2070 }
2071
2072 RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
2073 {
2074     if (pseudo < FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
2075         return 0;
2076
2077     RenderStyle* cachedStyle = style()->getCachedPseudoStyle(pseudo);
2078     if (cachedStyle)
2079         return cachedStyle;
2080     
2081     RefPtr<RenderStyle> result = getUncachedPseudoStyle(pseudo, parentStyle);
2082     if (result)
2083         return style()->addCachedPseudoStyle(result.release());
2084     return 0;
2085 }
2086
2087 PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle, RenderStyle* ownStyle) const
2088 {
2089     if (pseudo < FIRST_INTERNAL_PSEUDOID && !ownStyle && !style()->hasPseudoStyle(pseudo))
2090         return 0;
2091     
2092     if (!parentStyle) {
2093         ASSERT(!ownStyle);
2094         parentStyle = style();
2095     }
2096
2097     Node* n = node();
2098     while (n && !n->isElementNode())
2099         n = n->parentNode();
2100     if (!n)
2101         return 0;
2102
2103     RefPtr<RenderStyle> result;
2104     if (pseudo == FIRST_LINE_INHERITED) {
2105         result = document()->styleSelector()->styleForElement(static_cast<Element*>(n), parentStyle, false);
2106         result->setStyleType(FIRST_LINE_INHERITED);
2107     } else
2108         result = document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<Element*>(n), parentStyle);
2109     return result.release();
2110 }
2111
2112 static Color decorationColor(RenderStyle* style)
2113 {
2114     Color result;
2115     if (style->textStrokeWidth() > 0) {
2116         // Prefer stroke color if possible but not if it's fully transparent.
2117         result = style->textStrokeColor();
2118         if (!result.isValid())
2119             result = style->color();
2120         if (result.alpha())
2121             return result;
2122     }
2123     
2124     result = style->textFillColor();
2125     if (!result.isValid())
2126         result = style->color();
2127     return result;
2128 }
2129
2130 void RenderObject::getTextDecorationColors(int decorations, Color& underline, Color& overline,
2131                                            Color& linethrough, bool quirksMode)
2132 {
2133     RenderObject* curr = this;
2134     do {
2135         int currDecs = curr->style()->textDecoration();
2136         if (currDecs) {
2137             if (currDecs & UNDERLINE) {
2138                 decorations &= ~UNDERLINE;
2139                 underline = decorationColor(curr->style());
2140             }
2141             if (currDecs & OVERLINE) {
2142                 decorations &= ~OVERLINE;
2143                 overline = decorationColor(curr->style());
2144             }
2145             if (currDecs & LINE_THROUGH) {
2146                 decorations &= ~LINE_THROUGH;
2147                 linethrough = decorationColor(curr->style());
2148             }
2149         }
2150         curr = curr->parent();
2151         if (curr && curr->isRenderBlock() && toRenderBlock(curr)->inlineContinuation())
2152             curr = toRenderBlock(curr)->inlineContinuation();
2153     } while (curr && decorations && (!quirksMode || !curr->node() ||
2154                                      (!curr->node()->hasTagName(aTag) && !curr->node()->hasTagName(fontTag))));
2155
2156     // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
2157     if (decorations && curr) {
2158         if (decorations & UNDERLINE)
2159             underline = decorationColor(curr->style());
2160         if (decorations & OVERLINE)
2161             overline = decorationColor(curr->style());
2162         if (decorations & LINE_THROUGH)
2163             linethrough = decorationColor(curr->style());
2164     }
2165 }
2166
2167 #if ENABLE(DASHBOARD_SUPPORT)
2168 void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions)
2169 {
2170     // Convert the style regions to absolute coordinates.
2171     if (style()->visibility() != VISIBLE || !isBox())
2172         return;
2173     
2174     RenderBox* box = toRenderBox(this);
2175
2176     const Vector<StyleDashboardRegion>& styleRegions = style()->dashboardRegions();
2177     unsigned i, count = styleRegions.size();
2178     for (i = 0; i < count; i++) {
2179         StyleDashboardRegion styleRegion = styleRegions[i];
2180
2181         int w = box->width();
2182         int h = box->height();
2183
2184         DashboardRegionValue region;
2185         region.label = styleRegion.label;
2186         region.bounds = IntRect(styleRegion.offset.left().value(),
2187                                 styleRegion.offset.top().value(),
2188                                 w - styleRegion.offset.left().value() - styleRegion.offset.right().value(),
2189                                 h - styleRegion.offset.top().value() - styleRegion.offset.bottom().value());
2190         region.type = styleRegion.type;
2191
2192         region.clip = region.bounds;
2193         computeAbsoluteRepaintRect(region.clip);
2194         if (region.clip.height() < 0) {
2195             region.clip.setHeight(0);
2196             region.clip.setWidth(0);
2197         }
2198
2199         FloatPoint absPos = localToAbsolute();
2200         region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
2201         region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
2202
2203         if (document()->frame()) {
2204             float pageScaleFactor = document()->frame()->page()->chrome()->scaleFactor();
2205             if (pageScaleFactor != 1.0f) {
2206                 region.bounds.scale(pageScaleFactor);
2207                 region.clip.scale(pageScaleFactor);
2208             }
2209         }
2210
2211         regions.append(region);
2212     }
2213 }
2214
2215 void RenderObject::collectDashboardRegions(Vector<DashboardRegionValue>& regions)
2216 {
2217     // RenderTexts don't have their own style, they just use their parent's style,
2218     // so we don't want to include them.
2219     if (isText())
2220         return;
2221
2222     addDashboardRegions(regions);
2223     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
2224         curr->collectDashboardRegions(regions);
2225 }
2226 #endif
2227
2228 bool RenderObject::willRenderImage(CachedImage*)
2229 {
2230     // Without visibility we won't render (and therefore don't care about animation).
2231     if (style()->visibility() != VISIBLE)
2232         return false;
2233
2234     // 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)
2235     // then we don't want to render either.
2236     return !document()->inPageCache() && !document()->view()->isOffscreen();
2237 }
2238
2239 int RenderObject::maximalOutlineSize(PaintPhase p) const
2240 {
2241     if (p != PaintPhaseOutline && p != PaintPhaseSelfOutline && p != PaintPhaseChildOutlines)
2242         return 0;
2243     return toRenderView(document()->renderer())->maximalOutlineSize();
2244 }
2245
2246 int RenderObject::caretMinOffset() const
2247 {
2248     return 0;
2249 }
2250
2251 int RenderObject::caretMaxOffset() const
2252 {
2253     if (isReplaced())
2254         return node() ? max(1U, node()->childNodeCount()) : 1;
2255     if (isHR())
2256         return 1;
2257     return 0;
2258 }
2259
2260 unsigned RenderObject::caretMaxRenderedOffset() const
2261 {
2262     return 0;
2263 }
2264
2265 int RenderObject::previousOffset(int current) const
2266 {
2267     return current - 1;
2268 }
2269
2270 int RenderObject::previousOffsetForBackwardDeletion(int current) const
2271 {
2272     return current - 1;
2273 }
2274
2275 int RenderObject::nextOffset(int current) const
2276 {
2277     return current + 1;
2278 }
2279
2280 void RenderObject::adjustRectForOutlineAndShadow(IntRect& rect) const
2281 {
2282     int outlineSize = outlineStyleForRepaint()->outlineSize();
2283     if (ShadowData* boxShadow = style()->boxShadow()) {
2284         int shadowLeft = 0;
2285         int shadowRight = 0;
2286         int shadowTop = 0;
2287         int shadowBottom = 0;
2288
2289         do {
2290             if (boxShadow->style == Normal) {
2291                 shadowLeft = min(boxShadow->x - boxShadow->blur - boxShadow->spread - outlineSize, shadowLeft);
2292                 shadowRight = max(boxShadow->x + boxShadow->blur + boxShadow->spread + outlineSize, shadowRight);
2293                 shadowTop = min(boxShadow->y - boxShadow->blur - boxShadow->spread - outlineSize, shadowTop);
2294                 shadowBottom = max(boxShadow->y + boxShadow->blur + boxShadow->spread + outlineSize, shadowBottom);
2295             }
2296
2297             boxShadow = boxShadow->next;
2298         } while (boxShadow);
2299
2300         rect.move(shadowLeft, shadowTop);
2301         rect.setWidth(rect.width() - shadowLeft + shadowRight);
2302         rect.setHeight(rect.height() - shadowTop + shadowBottom);
2303     } else
2304         rect.inflate(outlineSize);
2305 }
2306
2307 AnimationController* RenderObject::animation() const
2308 {
2309     return document()->frame()->animation();
2310 }
2311
2312 void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
2313 {
2314     imageChanged(static_cast<WrappedImagePtr>(image), rect);
2315 }
2316
2317 RenderBoxModelObject* RenderObject::offsetParent() const
2318 {
2319     // If any of the following holds true return null and stop this algorithm:
2320     // A is the root element.
2321     // A is the HTML body element.
2322     // The computed value of the position property for element A is fixed.
2323     if (isRoot() || isBody() || (isPositioned() && style()->position() == FixedPosition))
2324         return 0;
2325
2326     // If A is an area HTML element which has a map HTML element somewhere in the ancestor
2327     // chain return the nearest ancestor map HTML element and stop this algorithm.
2328     // FIXME: Implement!
2329     
2330     // Return the nearest ancestor element of A for which at least one of the following is
2331     // true and stop this algorithm if such an ancestor is found:
2332     //     * The computed value of the position property is not static.
2333     //     * It is the HTML body element.
2334     //     * The computed value of the position property of A is static and the ancestor
2335     //       is one of the following HTML elements: td, th, or table.
2336     //     * Our own extension: if there is a difference in the effective zoom
2337     bool skipTables = isPositioned() || isRelPositioned();
2338     float currZoom = style()->effectiveZoom();
2339     RenderObject* curr = parent();
2340     while (curr && (!curr->node() ||
2341                     (!curr->isPositioned() && !curr->isRelPositioned() && !curr->isBody()))) {
2342         Node* element = curr->node();
2343         if (!skipTables && element) {
2344             bool isTableElement = element->hasTagName(tableTag) ||
2345                                   element->hasTagName(tdTag) ||
2346                                   element->hasTagName(thTag);
2347
2348 #if ENABLE(WML)
2349             if (!isTableElement && element->isWMLElement())
2350                 isTableElement = element->hasTagName(WMLNames::tableTag) ||
2351                                  element->hasTagName(WMLNames::tdTag);
2352 #endif
2353
2354             if (isTableElement)
2355                 break;
2356         }
2357
2358         float newZoom = curr->style()->effectiveZoom();
2359         if (currZoom != newZoom)
2360             break;
2361         currZoom = newZoom;
2362         curr = curr->parent();
2363     }
2364     return curr && curr->isBoxModelObject() ? toRenderBoxModelObject(curr) : 0;
2365 }
2366
2367 VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity)
2368 {
2369     // If this is a non-anonymous renderer, then it's simple.
2370     if (Node* node = this->node())
2371         return VisiblePosition(node, offset, affinity);
2372
2373     // We don't want to cross the boundary between editable and non-editable
2374     // regions of the document, but that is either impossible or at least
2375     // extremely unlikely in any normal case because we stop as soon as we
2376     // find a single non-anonymous renderer.
2377
2378     // Find a nearby non-anonymous renderer.
2379     RenderObject* child = this;
2380     while (RenderObject* parent = child->parent()) {
2381         // Find non-anonymous content after.
2382         RenderObject* renderer = child;
2383         while ((renderer = renderer->nextInPreOrder(parent))) {
2384             if (Node* node = renderer->node())
2385                 return VisiblePosition(node, 0, DOWNSTREAM);
2386         }
2387
2388         // Find non-anonymous content before.
2389         renderer = child;
2390         while ((renderer = renderer->previousInPreOrder())) {
2391             if (renderer == parent)
2392                 break;
2393             if (Node* node = renderer->node())
2394                 return VisiblePosition(lastDeepEditingPositionForNode(node), DOWNSTREAM);
2395         }
2396
2397         // Use the parent itself unless it too is anonymous.
2398         if (Node* node = parent->node())
2399             return VisiblePosition(node, 0, DOWNSTREAM);
2400
2401         // Repeat at the next level up.
2402         child = parent;
2403     }
2404
2405     // Everything was anonymous. Give up.
2406     return VisiblePosition();
2407 }
2408
2409 VisiblePosition RenderObject::createVisiblePosition(const Position& position)
2410 {
2411     if (position.isNotNull())
2412         return VisiblePosition(position);
2413
2414     ASSERT(!node());
2415     return createVisiblePosition(0, DOWNSTREAM);
2416 }
2417
2418 #if ENABLE(SVG)
2419
2420 FloatRect RenderObject::objectBoundingBox() const
2421 {
2422     ASSERT_NOT_REACHED();
2423     return FloatRect();
2424 }
2425
2426 // Returns the smallest rectangle enclosing all of the painted content
2427 // respecting clipping, masking, filters, opacity, stroke-width and markers
2428 FloatRect RenderObject::repaintRectInLocalCoordinates() const
2429 {
2430     ASSERT_NOT_REACHED();
2431     return FloatRect();
2432 }
2433
2434 TransformationMatrix RenderObject::localTransform() const
2435 {
2436     return TransformationMatrix();
2437 }
2438
2439 TransformationMatrix RenderObject::localToParentTransform() const
2440 {
2441     // FIXME: This double virtual call indirection is temporary until I can land the
2442     // rest of the of the localToParentTransform() support for SVG.
2443     return localTransform();
2444 }
2445
2446 TransformationMatrix RenderObject::absoluteTransform() const
2447 {
2448     // FIXME: This should use localToParentTransform(), but much of the SVG code
2449     // depends on RenderBox::absoluteTransform() being the sum of the localTransform()s of all parent renderers.
2450     if (parent())
2451         return localTransform() * parent()->absoluteTransform();
2452     return localTransform();
2453 }
2454
2455 bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
2456 {
2457     ASSERT_NOT_REACHED();
2458     return false;
2459 }
2460
2461 #endif // ENABLE(SVG)
2462
2463 } // namespace WebCore
2464
2465 #ifndef NDEBUG
2466
2467 void showTree(const WebCore::RenderObject* ro)
2468 {
2469     if (ro)
2470         ro->showTreeForThis();
2471 }
2472
2473 #endif