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