d0f8a8b569b19df5ed2eccf4ac70ce35df6713d6
[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 offset = 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(offset);
1147
1148     if (inner.isEmpty())
1149         return;
1150
1151     LayoutRect outer = inner;
1152     outer.inflate(outlineWidth);
1153
1154     bool useTransparencyLayer = outlineColor.hasAlpha();
1155     if (useTransparencyLayer) {
1156         if (outlineStyle == SOLID) {
1157             Path path;
1158             path.addRect(outer);
1159             path.addRect(inner);
1160             graphicsContext->setFillRule(RULE_EVENODD);
1161             graphicsContext->setFillColor(outlineColor, styleToUse->colorSpace());
1162             graphicsContext->fillPath(path);
1163             return;
1164         }
1165         graphicsContext->beginTransparencyLayer(static_cast<float>(outlineColor.alpha()) / 255);
1166         outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue());
1167     }
1168
1169     LayoutUnit leftOuter = outer.x();
1170     LayoutUnit leftInner = inner.x();
1171     LayoutUnit rightOuter = outer.maxX();
1172     LayoutUnit rightInner = inner.maxX();
1173     LayoutUnit topOuter = outer.y();
1174     LayoutUnit topInner = inner.y();
1175     LayoutUnit bottomOuter = outer.maxY();
1176     LayoutUnit bottomInner = inner.maxY();
1177     
1178     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, leftInner, bottomOuter, BSLeft, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1179     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, rightOuter, topInner, BSTop, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1180     drawLineForBoxSide(graphicsContext, rightInner, topOuter, rightOuter, bottomOuter, BSRight, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1181     drawLineForBoxSide(graphicsContext, leftOuter, bottomInner, rightOuter, bottomOuter, BSBottom, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1182
1183     if (useTransparencyLayer)
1184         graphicsContext->endTransparencyLayer();
1185 }
1186
1187 LayoutRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
1188 {
1189     if (useTransforms) {
1190         Vector<FloatQuad> quads;
1191         absoluteQuads(quads);
1192
1193         size_t n = quads.size();
1194         if (!n)
1195             return IntRect();
1196     
1197         LayoutRect result = quads[0].enclosingBoundingBox();
1198         for (size_t i = 1; i < n; ++i)
1199             result.unite(quads[i].enclosingBoundingBox());
1200         return result;
1201     }
1202
1203     FloatPoint absPos = localToAbsolute();
1204     Vector<LayoutRect> rects;
1205     absoluteRects(rects, flooredLayoutPoint(absPos));
1206
1207     size_t n = rects.size();
1208     if (!n)
1209         return LayoutRect();
1210
1211     LayoutRect result = rects[0];
1212     for (size_t i = 1; i < n; ++i)
1213         result.unite(rects[i]);
1214     return result;
1215 }
1216
1217 void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
1218 {
1219     Vector<LayoutRect> rects;
1220     // FIXME: addFocusRingRects() needs to be passed this transform-unaware
1221     // localToAbsolute() offset here because RenderInline::addFocusRingRects()
1222     // implicitly assumes that. This doesn't work correctly with transformed
1223     // descendants.
1224     FloatPoint absolutePoint = localToAbsolute();
1225     addFocusRingRects(rects, flooredLayoutPoint(absolutePoint));
1226     size_t count = rects.size(); 
1227     for (size_t i = 0; i < count; ++i) {
1228         LayoutRect rect = rects[i];
1229         rect.move(-absolutePoint.x(), -absolutePoint.y());
1230         quads.append(localToAbsoluteQuad(FloatQuad(rect)));
1231     }
1232 }
1233
1234 void RenderObject::addAbsoluteRectForLayer(LayoutRect& result)
1235 {
1236     if (hasLayer())
1237         result.unite(absoluteBoundingBoxRectIgnoringTransforms());
1238     for (RenderObject* current = firstChild(); current; current = current->nextSibling())
1239         current->addAbsoluteRectForLayer(result);
1240 }
1241
1242 LayoutRect RenderObject::paintingRootRect(LayoutRect& topLevelRect)
1243 {
1244     LayoutRect result = absoluteBoundingBoxRectIgnoringTransforms();
1245     topLevelRect = result;
1246     for (RenderObject* current = firstChild(); current; current = current->nextSibling())
1247         current->addAbsoluteRectForLayer(result);
1248     return result;
1249 }
1250
1251 void RenderObject::paint(PaintInfo&, const LayoutPoint&)
1252 {
1253 }
1254
1255 RenderBoxModelObject* RenderObject::containerForRepaint() const
1256 {
1257     RenderView* v = view();
1258     if (!v)
1259         return 0;
1260     
1261     RenderBoxModelObject* repaintContainer = 0;
1262
1263 #if USE(ACCELERATED_COMPOSITING)
1264     if (v->usesCompositing()) {
1265         RenderLayer* compLayer = enclosingLayer()->enclosingCompositingLayer();
1266         if (compLayer)
1267             repaintContainer = compLayer->renderer();
1268     }
1269 #endif
1270
1271     // If we have a flow thread, then we need to do individual repaints within the RenderRegions instead.
1272     // Return the flow thread as a repaint container in order to create a chokepoint that allows us to change
1273     // repainting to do individual region repaints.
1274     // FIXME: Composited layers inside a flow thread will bypass this mechanism and will malfunction. It's not
1275     // clear how to address this problem for composited descendants of a RenderFlowThread.
1276     if (!repaintContainer && inRenderFlowThread())
1277         repaintContainer = enclosingRenderFlowThread();
1278     return repaintContainer;
1279 }
1280
1281 void RenderObject::repaintUsingContainer(RenderBoxModelObject* repaintContainer, const LayoutRect& r, bool immediate)
1282 {
1283     if (!repaintContainer) {
1284         view()->repaintViewRectangle(r, immediate);
1285         return;
1286     }
1287
1288     if (repaintContainer->isRenderFlowThread()) {
1289         toRenderFlowThread(repaintContainer)->repaintRectangleInRegions(r, immediate);
1290         return;
1291     }
1292
1293 #if USE(ACCELERATED_COMPOSITING)
1294     RenderView* v = view();
1295     if (repaintContainer->isRenderView()) {
1296         ASSERT(repaintContainer == v);
1297         bool viewHasCompositedLayer = v->hasLayer() && v->layer()->isComposited();
1298         if (!viewHasCompositedLayer || v->layer()->backing()->paintingGoesToWindow()) {
1299             LayoutRect repaintRectangle = r;
1300             if (viewHasCompositedLayer &&  v->layer()->transform())
1301                 repaintRectangle = v->layer()->transform()->mapRect(r);
1302             v->repaintViewRectangle(repaintRectangle, immediate);
1303             return;
1304         }
1305     }
1306     
1307     if (v->usesCompositing()) {
1308         ASSERT(repaintContainer->hasLayer() && repaintContainer->layer()->isComposited());
1309         repaintContainer->layer()->setBackingNeedsRepaintInRect(r);
1310     }
1311 #else
1312     if (repaintContainer->isRenderView())
1313         toRenderView(repaintContainer)->repaintViewRectangle(r, immediate);
1314 #endif
1315 }
1316
1317 void RenderObject::repaint(bool immediate)
1318 {
1319     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1320     RenderView* view;
1321     if (!isRooted(&view))
1322         return;
1323
1324     if (view->printing())
1325         return; // Don't repaint if we're printing.
1326
1327     RenderBoxModelObject* repaintContainer = containerForRepaint();
1328     repaintUsingContainer(repaintContainer ? repaintContainer : view, clippedOverflowRectForRepaint(repaintContainer), immediate);
1329 }
1330
1331 void RenderObject::repaintRectangle(const LayoutRect& r, bool immediate)
1332 {
1333     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1334     RenderView* view;
1335     if (!isRooted(&view))
1336         return;
1337
1338     if (view->printing())
1339         return; // Don't repaint if we're printing.
1340
1341     LayoutRect dirtyRect(r);
1342
1343     // FIXME: layoutDelta needs to be applied in parts before/after transforms and
1344     // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
1345     dirtyRect.move(view->layoutDelta());
1346
1347     RenderBoxModelObject* repaintContainer = containerForRepaint();
1348     computeRectForRepaint(repaintContainer, dirtyRect);
1349     repaintUsingContainer(repaintContainer ? repaintContainer : view, dirtyRect, immediate);
1350 }
1351
1352 bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr, const LayoutRect* newOutlineBoxRectPtr)
1353 {
1354     RenderView* v = view();
1355     if (v->printing())
1356         return false; // Don't repaint if we're printing.
1357
1358     // This ASSERT fails due to animations.  See https://bugs.webkit.org/show_bug.cgi?id=37048
1359     // ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForRepaint(repaintContainer));
1360     LayoutRect newBounds = newBoundsPtr ? *newBoundsPtr : clippedOverflowRectForRepaint(repaintContainer);
1361     LayoutRect newOutlineBox;
1362
1363     bool fullRepaint = selfNeedsLayout();
1364     // Presumably a background or a border exists if border-fit:lines was specified.
1365     if (!fullRepaint && style()->borderFit() == BorderFitLines)
1366         fullRepaint = true;
1367     if (!fullRepaint) {
1368         // This ASSERT fails due to animations.  See https://bugs.webkit.org/show_bug.cgi?id=37048
1369         // ASSERT(!newOutlineBoxRectPtr || *newOutlineBoxRectPtr == outlineBoundsForRepaint(repaintContainer));
1370         newOutlineBox = newOutlineBoxRectPtr ? *newOutlineBoxRectPtr : outlineBoundsForRepaint(repaintContainer);
1371         if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
1372             fullRepaint = true;
1373     }
1374
1375     if (!repaintContainer)
1376         repaintContainer = v;
1377
1378     if (fullRepaint) {
1379         repaintUsingContainer(repaintContainer, oldBounds);
1380         if (newBounds != oldBounds)
1381             repaintUsingContainer(repaintContainer, newBounds);
1382         return true;
1383     }
1384
1385     if (newBounds == oldBounds && newOutlineBox == oldOutlineBox)
1386         return false;
1387
1388     LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
1389     if (deltaLeft > 0)
1390         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
1391     else if (deltaLeft < 0)
1392         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
1393
1394     LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
1395     if (deltaRight > 0)
1396         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
1397     else if (deltaRight < 0)
1398         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
1399
1400     LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
1401     if (deltaTop > 0)
1402         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
1403     else if (deltaTop < 0)
1404         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
1405
1406     LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
1407     if (deltaBottom > 0)
1408         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
1409     else if (deltaBottom < 0)
1410         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
1411
1412     if (newOutlineBox == oldOutlineBox)
1413         return false;
1414
1415     // We didn't move, but we did change size.  Invalidate the delta, which will consist of possibly
1416     // two rectangles (but typically only one).
1417     RenderStyle* outlineStyle = outlineStyleForRepaint();
1418     LayoutUnit ow = outlineStyle->outlineSize();
1419     LayoutUnit width = abs(newOutlineBox.width() - oldOutlineBox.width());
1420     if (width) {
1421         LayoutUnit shadowLeft;
1422         LayoutUnit shadowRight;
1423         style()->getBoxShadowHorizontalExtent(shadowLeft, shadowRight);
1424
1425         LayoutUnit borderRight = isBox() ? toRenderBox(this)->borderRight() : LayoutUnit(0);
1426         LayoutUnit boxWidth = isBox() ? toRenderBox(this)->width() : LayoutUnit(0);
1427         LayoutUnit borderWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), max(borderRight, max<LayoutUnit>(style()->borderTopRightRadius().width().calcValue(boxWidth), style()->borderBottomRightRadius().width().calcValue(boxWidth)))) + max(ow, shadowRight);
1428         LayoutRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - borderWidth,
1429             newOutlineBox.y(),
1430             width + borderWidth,
1431             max(newOutlineBox.height(), oldOutlineBox.height()));
1432         LayoutUnit right = min(newBounds.maxX(), oldBounds.maxX());
1433         if (rightRect.x() < right) {
1434             rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
1435             repaintUsingContainer(repaintContainer, rightRect);
1436         }
1437     }
1438     LayoutUnit height = abs(newOutlineBox.height() - oldOutlineBox.height());
1439     if (height) {
1440         LayoutUnit shadowTop;
1441         LayoutUnit shadowBottom;
1442         style()->getBoxShadowVerticalExtent(shadowTop, shadowBottom);
1443
1444         LayoutUnit borderBottom = isBox() ? toRenderBox(this)->borderBottom() : LayoutUnit(0);
1445         LayoutUnit boxHeight = isBox() ? toRenderBox(this)->height() : LayoutUnit(0);
1446         LayoutUnit borderHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), max(borderBottom, max<LayoutUnit>(style()->borderBottomLeftRadius().height().calcValue(boxHeight), style()->borderBottomRightRadius().height().calcValue(boxHeight)))) + max(ow, shadowBottom);
1447         LayoutRect bottomRect(newOutlineBox.x(),
1448             min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - borderHeight,
1449             max(newOutlineBox.width(), oldOutlineBox.width()),
1450             height + borderHeight);
1451         LayoutUnit bottom = min(newBounds.maxY(), oldBounds.maxY());
1452         if (bottomRect.y() < bottom) {
1453             bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
1454             repaintUsingContainer(repaintContainer, bottomRect);
1455         }
1456     }
1457     return false;
1458 }
1459
1460 void RenderObject::repaintDuringLayoutIfMoved(const LayoutRect&)
1461 {
1462 }
1463
1464 void RenderObject::repaintOverhangingFloats(bool)
1465 {
1466 }
1467
1468 bool RenderObject::checkForRepaintDuringLayout() const
1469 {
1470     // FIXME: <https://bugs.webkit.org/show_bug.cgi?id=20885> It is probably safe to also require
1471     // m_everHadLayout. Currently, only RenderBlock::layoutBlock() adds this condition. See also
1472     // <https://bugs.webkit.org/show_bug.cgi?id=15129>.
1473     return !document()->view()->needsFullRepaint() && !hasLayer();
1474 }
1475
1476 LayoutRect RenderObject::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, LayoutUnit outlineWidth) const
1477 {
1478     LayoutRect r(clippedOverflowRectForRepaint(repaintContainer));
1479     r.inflate(outlineWidth);
1480     return r;
1481 }
1482
1483 LayoutRect RenderObject::clippedOverflowRectForRepaint(RenderBoxModelObject*) const
1484 {
1485     ASSERT_NOT_REACHED();
1486     return LayoutRect();
1487 }
1488
1489 void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
1490 {
1491     if (repaintContainer == this)
1492         return;
1493
1494     if (RenderObject* o = parent()) {
1495         if (o->isBlockFlow()) {
1496             RenderBlock* cb = toRenderBlock(o);
1497             if (cb->hasColumns())
1498                 cb->adjustRectForColumns(rect);
1499         }
1500
1501         if (o->hasOverflowClip()) {
1502             // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the
1503             // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint
1504             // anyway if its size does change.
1505             RenderBox* boxParent = toRenderBox(o);
1506
1507             LayoutRect repaintRect(rect);
1508             repaintRect.move(-boxParent->layer()->scrolledContentOffset()); // For overflow:auto/scroll/hidden.
1509
1510             LayoutRect boxRect(LayoutPoint(), boxParent->layer()->size());
1511             rect = intersection(repaintRect, boxRect);
1512             if (rect.isEmpty())
1513                 return;
1514         }
1515
1516         o->computeRectForRepaint(repaintContainer, rect, fixed);
1517     }
1518 }
1519
1520 void RenderObject::computeFloatRectForRepaint(RenderBoxModelObject*, FloatRect&, bool) const
1521 {
1522     ASSERT_NOT_REACHED();
1523 }
1524
1525 void RenderObject::dirtyLinesFromChangedChild(RenderObject*)
1526 {
1527 }
1528
1529 #ifndef NDEBUG
1530
1531 void RenderObject::showTreeForThis() const
1532 {
1533     if (node())
1534         node()->showTreeForThis();
1535 }
1536
1537 void RenderObject::showRenderTreeForThis() const
1538 {
1539     showRenderTree(this, 0);
1540 }
1541
1542 void RenderObject::showLineTreeForThis() const
1543 {
1544     if (containingBlock())
1545         containingBlock()->showLineTreeAndMark(0, 0, 0, 0, this);
1546 }
1547
1548 void RenderObject::showRenderObject() const
1549 {
1550     showRenderObject(0);
1551 }
1552
1553 void RenderObject::showRenderObject(int printedCharacters) const
1554 {
1555     // As this function is intended to be used when debugging, the
1556     // this pointer may be 0.
1557     if (!this) {
1558         fputs("(null)\n", stderr);
1559         return;
1560     }
1561
1562     printedCharacters += fprintf(stderr, "%s %p", renderName(), this);
1563
1564     if (node()) {
1565         if (printedCharacters)
1566             for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
1567                 fputc(' ', stderr);
1568         fputc('\t', stderr);
1569         node()->showNode();
1570     } else
1571         fputc('\n', stderr);
1572 }
1573
1574 void RenderObject::showRenderTreeAndMark(const RenderObject* markedObject1, const char* markedLabel1, const RenderObject* markedObject2, const char* markedLabel2, int depth) const
1575 {
1576     int printedCharacters = 0;
1577     if (markedObject1 == this && markedLabel1)
1578         printedCharacters += fprintf(stderr, "%s", markedLabel1);
1579     if (markedObject2 == this && markedLabel2)
1580         printedCharacters += fprintf(stderr, "%s", markedLabel2);
1581     for (; printedCharacters < depth * 2; printedCharacters++)
1582         fputc(' ', stderr);
1583
1584     showRenderObject(printedCharacters);
1585     if (!this)
1586         return;
1587
1588     for (const RenderObject* child = firstChild(); child; child = child->nextSibling())
1589         child->showRenderTreeAndMark(markedObject1, markedLabel1, markedObject2, markedLabel2, depth + 1);
1590 }
1591
1592 #endif // NDEBUG
1593
1594 Color RenderObject::selectionBackgroundColor() const
1595 {
1596     Color color;
1597     if (style()->userSelect() != SELECT_NONE) {
1598         RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION);
1599         if (pseudoStyle && pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
1600             color = pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).blendWithWhite();
1601         else
1602             color = frame()->selection()->isFocusedAndActive() ?
1603                     theme()->activeSelectionBackgroundColor() :
1604                     theme()->inactiveSelectionBackgroundColor();
1605     }
1606
1607     return color;
1608 }
1609
1610 Color RenderObject::selectionColor(int colorProperty) const
1611 {
1612     Color color;
1613     // If the element is unselectable, or we are only painting the selection,
1614     // don't override the foreground color with the selection foreground color.
1615     if (style()->userSelect() == SELECT_NONE
1616         || (frame()->view()->paintBehavior() & PaintBehaviorSelectionOnly))
1617         return color;
1618
1619     if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION)) {
1620         color = pseudoStyle->visitedDependentColor(colorProperty);
1621         if (!color.isValid())
1622             color = pseudoStyle->visitedDependentColor(CSSPropertyColor);
1623     } else
1624         color = frame()->selection()->isFocusedAndActive() ?
1625                 theme()->activeSelectionForegroundColor() :
1626                 theme()->inactiveSelectionForegroundColor();
1627
1628     return color;
1629 }
1630
1631 Color RenderObject::selectionForegroundColor() const
1632 {
1633     return selectionColor(CSSPropertyWebkitTextFillColor);
1634 }
1635
1636 Color RenderObject::selectionEmphasisMarkColor() const
1637 {
1638     return selectionColor(CSSPropertyWebkitTextEmphasisColor);
1639 }
1640
1641 void RenderObject::selectionStartEnd(int& spos, int& epos) const
1642 {
1643     view()->selectionStartEnd(spos, epos);
1644 }
1645
1646 void RenderObject::handleDynamicFloatPositionChange()
1647 {
1648     // We have gone from not affecting the inline status of the parent flow to suddenly
1649     // having an impact.  See if there is a mismatch between the parent flow's
1650     // childrenInline() state and our state.
1651     setInline(style()->isDisplayInlineType());
1652     if (isInline() != parent()->childrenInline()) {
1653         if (!isInline())
1654             toRenderBoxModelObject(parent())->childBecameNonInline(this);
1655         else {
1656             // An anonymous block must be made to wrap this inline.
1657             RenderBlock* block = toRenderBlock(parent())->createAnonymousBlock();
1658             RenderObjectChildList* childlist = parent()->virtualChildren();
1659             childlist->insertChildNode(parent(), block, this);
1660             block->children()->appendChildNode(block, childlist->removeChildNode(parent(), this));
1661         }
1662     }
1663 }
1664
1665 void RenderObject::setAnimatableStyle(PassRefPtr<RenderStyle> style)
1666 {
1667     if (!isText() && style)
1668         setStyle(animation()->updateAnimations(this, style.get()));
1669     else
1670         setStyle(style);
1671 }
1672
1673 StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
1674 {
1675 #if USE(ACCELERATED_COMPOSITING)
1676     // If transform changed, and we are not composited, need to do a layout.
1677     if (contextSensitiveProperties & ContextSensitivePropertyTransform) {
1678         // Text nodes share style with their parents but transforms don't apply to them,
1679         // hence the !isText() check.
1680         // FIXME: when transforms are taken into account for overflow, we will need to do a layout.
1681         if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited())) {
1682             // We need to set at least SimplifiedLayout, but if PositionedMovementOnly is already set
1683             // then we actually need SimplifiedLayoutAndPositionedMovement.
1684             if (!hasLayer())
1685                 diff = StyleDifferenceLayout; // FIXME: Do this for now since SimplifiedLayout cannot handle updating floating objects lists.
1686             else if (diff < StyleDifferenceLayoutPositionedMovementOnly)
1687                 diff = StyleDifferenceSimplifiedLayout;
1688             else if (diff < StyleDifferenceSimplifiedLayout)
1689                 diff = StyleDifferenceSimplifiedLayoutAndPositionedMovement;
1690         } else if (diff < StyleDifferenceRecompositeLayer)
1691             diff = StyleDifferenceRecompositeLayer;
1692     }
1693
1694     // If opacity changed, and we are not composited, need to repaint (also
1695     // ignoring text nodes)
1696     if (contextSensitiveProperties & ContextSensitivePropertyOpacity) {
1697         if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited()))
1698             diff = StyleDifferenceRepaintLayer;
1699         else if (diff < StyleDifferenceRecompositeLayer)
1700             diff = StyleDifferenceRecompositeLayer;
1701     }
1702     
1703     // The answer to requiresLayer() for plugins and iframes can change outside of the style system,
1704     // since it depends on whether we decide to composite these elements. When the layer status of
1705     // one of these elements changes, we need to force a layout.
1706     if (diff == StyleDifferenceEqual && style() && isBoxModelObject()) {
1707         if (hasLayer() != toRenderBoxModelObject(this)->requiresLayer())
1708             diff = StyleDifferenceLayout;
1709     }
1710 #else
1711     UNUSED_PARAM(contextSensitiveProperties);
1712 #endif
1713
1714     // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
1715     if (diff == StyleDifferenceRepaintLayer && !hasLayer())
1716         diff = StyleDifferenceRepaint;
1717
1718     return diff;
1719 }
1720
1721 RenderStyle* RenderObject::styleInRegion() const
1722 {
1723     ASSERT(inRenderFlowThread());
1724
1725     if (!canHaveRegionStyle()
1726         || !((view() && view()->currentRenderRegion() && view()->currentRenderRegion()->hasCustomRegionStyle())))
1727         return m_style.get();
1728
1729     RenderStyle* regionStyle = view()->currentRenderRegion()->renderObjectRegionStyle(this);
1730     if (!regionStyle)
1731         view()->currentRenderRegion()->computeStyleInRegion(this);
1732     return view()->currentRenderRegion()->renderObjectRegionStyle(this);
1733 }
1734
1735 void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
1736 {
1737     if (m_style == style) {
1738 #if USE(ACCELERATED_COMPOSITING)
1739         // We need to run through adjustStyleDifference() for iframes and plugins, so
1740         // style sharing is disabled for them. That should ensure that we never hit this code path.
1741         ASSERT(!isRenderIFrame() && !isEmbeddedObject() &&!isApplet());
1742 #endif
1743         return;
1744     }
1745
1746     StyleDifference diff = StyleDifferenceEqual;
1747     unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
1748     if (m_style)
1749         diff = m_style->diff(style.get(), contextSensitiveProperties);
1750
1751     diff = adjustStyleDifference(diff, contextSensitiveProperties);
1752
1753     styleWillChange(diff, style.get());
1754     
1755     RefPtr<RenderStyle> oldStyle = m_style.release();
1756     m_style = style;
1757
1758     updateFillImages(oldStyle ? oldStyle->backgroundLayers() : 0, m_style ? m_style->backgroundLayers() : 0);
1759     updateFillImages(oldStyle ? oldStyle->maskLayers() : 0, m_style ? m_style->maskLayers() : 0);
1760
1761     updateImage(oldStyle ? oldStyle->borderImage().image() : 0, m_style ? m_style->borderImage().image() : 0);
1762     updateImage(oldStyle ? oldStyle->maskBoxImage().image() : 0, m_style ? m_style->maskBoxImage().image() : 0);
1763
1764     // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen
1765     // during styleDidChange (it's used by clippedOverflowRectForRepaint()).
1766     if (m_style->outlineWidth() > 0 && m_style->outlineSize() > maximalOutlineSize(PaintPhaseOutline))
1767         toRenderView(document()->renderer())->setMaximalOutlineSize(m_style->outlineSize());
1768
1769     styleDidChange(diff, oldStyle.get());
1770
1771     if (!m_parent || isText())
1772         return;
1773
1774     // Now that the layer (if any) has been updated, we need to adjust the diff again,
1775     // check whether we should layout now, and decide if we need to repaint.
1776     StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
1777     
1778     if (diff <= StyleDifferenceLayoutPositionedMovementOnly) {
1779         if (updatedDiff == StyleDifferenceLayout)
1780             setNeedsLayoutAndPrefWidthsRecalc();
1781         else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly)
1782             setNeedsPositionedMovementLayout();
1783         else if (updatedDiff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
1784             setNeedsPositionedMovementLayout();
1785             setNeedsSimplifiedNormalFlowLayout();
1786         } else if (updatedDiff == StyleDifferenceSimplifiedLayout)
1787             setNeedsSimplifiedNormalFlowLayout();
1788     }
1789     
1790     if (updatedDiff == StyleDifferenceRepaintLayer || updatedDiff == StyleDifferenceRepaint) {
1791         // Do a repaint with the new style now, e.g., for example if we go from
1792         // not having an outline to having an outline.
1793         repaint();
1794     }
1795 }
1796
1797 void RenderObject::setStyleInternal(PassRefPtr<RenderStyle> style)
1798 {
1799     m_style = style;
1800 }
1801
1802 void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
1803 {
1804     if (m_style) {
1805         // If our z-index changes value or our visibility changes,
1806         // we need to dirty our stacking context's z-order list.
1807         if (newStyle) {
1808             bool visibilityChanged = m_style->visibility() != newStyle->visibility() 
1809                 || m_style->zIndex() != newStyle->zIndex() 
1810                 || m_style->hasAutoZIndex() != newStyle->hasAutoZIndex();
1811 #if ENABLE(DASHBOARD_SUPPORT)
1812             if (visibilityChanged)
1813                 document()->setDashboardRegionsDirty(true);
1814 #endif
1815             if (visibilityChanged && AXObjectCache::accessibilityEnabled())
1816                 document()->axObjectCache()->childrenChanged(this);
1817
1818             // Keep layer hierarchy visibility bits up to date if visibility changes.
1819             if (m_style->visibility() != newStyle->visibility()) {
1820                 if (RenderLayer* l = enclosingLayer()) {
1821                     if (newStyle->visibility() == VISIBLE)
1822                         l->setHasVisibleContent(true);
1823                     else if (l->hasVisibleContent() && (this == l->renderer() || l->renderer()->style()->visibility() != VISIBLE)) {
1824                         l->dirtyVisibleContentStatus();
1825                         if (diff > StyleDifferenceRepaintLayer)
1826                             repaint();
1827                     }
1828                 }
1829             }
1830         }
1831
1832         if (m_parent && (diff == StyleDifferenceRepaint || newStyle->outlineSize() < m_style->outlineSize()))
1833             repaint();
1834         if (isFloating() && (m_style->floating() != newStyle->floating()))
1835             // For changes in float styles, we need to conceivably remove ourselves
1836             // from the floating objects list.
1837             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
1838         else if (isPositioned() && (m_style->position() != newStyle->position()))
1839             // For changes in positioning styles, we need to conceivably remove ourselves
1840             // from the positioned objects list.
1841             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
1842
1843         s_affectsParentBlock = isFloatingOrPositioned() &&
1844             (!newStyle->isFloating() && newStyle->position() != AbsolutePosition && newStyle->position() != FixedPosition)
1845             && parent() && (parent()->isBlockFlow() || parent()->isRenderInline());
1846
1847         // reset style flags
1848         if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositionedMovementOnly) {
1849             m_floating = false;
1850             m_positioned = false;
1851             m_relPositioned = false;
1852         }
1853         m_horizontalWritingMode = true;
1854         m_paintBackground = false;
1855         m_hasOverflowClip = false;
1856         m_hasTransform = false;
1857         m_hasReflection = false;
1858     } else
1859         s_affectsParentBlock = false;
1860
1861     if (view()->frameView()) {
1862         bool shouldBlitOnFixedBackgroundImage = false;
1863 #if ENABLE(FAST_MOBILE_SCROLLING)
1864         // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
1865         // when scrolling a page with a fixed background image. As an optimization, assuming there are
1866         // no fixed positoned elements on the page, we can acclerate scrolling (via blitting) if we
1867         // ignore the CSS property "background-attachment: fixed".
1868         shouldBlitOnFixedBackgroundImage = true;
1869 #endif
1870
1871         bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
1872         bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
1873         if (oldStyleSlowScroll != newStyleSlowScroll) {
1874             if (oldStyleSlowScroll)
1875                 view()->frameView()->removeSlowRepaintObject();
1876             if (newStyleSlowScroll)
1877                 view()->frameView()->addSlowRepaintObject();
1878         }
1879     }
1880 }
1881
1882 static bool areNonIdenticalCursorListsEqual(const RenderStyle* a, const RenderStyle* b)
1883 {
1884     ASSERT(a->cursors() != b->cursors());
1885     return a->cursors() && b->cursors() && *a->cursors() == *b->cursors();
1886 }
1887
1888 static inline bool areCursorsEqual(const RenderStyle* a, const RenderStyle* b)
1889 {
1890     return a->cursor() == b->cursor() && (a->cursors() == b->cursors() || areNonIdenticalCursorListsEqual(a, b));
1891 }
1892
1893 void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
1894 {
1895     if (s_affectsParentBlock)
1896         handleDynamicFloatPositionChange();
1897
1898     if (!m_parent)
1899         return;
1900     
1901     if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) {
1902         RenderCounter::rendererStyleChanged(this, oldStyle, m_style.get());
1903
1904         // If the object already needs layout, then setNeedsLayout won't do
1905         // any work. But if the containing block has changed, then we may need
1906         // to mark the new containing blocks for layout. The change that can
1907         // directly affect the containing block of this object is a change to
1908         // the position style.
1909         if (m_needsLayout && oldStyle->position() != m_style->position())
1910             markContainingBlocksForLayout();
1911
1912         if (diff == StyleDifferenceLayout)
1913             setNeedsLayoutAndPrefWidthsRecalc();
1914         else
1915             setNeedsSimplifiedNormalFlowLayout();
1916     } else if (diff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
1917         setNeedsPositionedMovementLayout();
1918         setNeedsSimplifiedNormalFlowLayout();
1919     } else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
1920         setNeedsPositionedMovementLayout();
1921
1922     // Don't check for repaint here; we need to wait until the layer has been
1923     // updated by subclasses before we know if we have to repaint (in setStyle()).
1924
1925     if (oldStyle && !areCursorsEqual(oldStyle, style())) {
1926         if (Frame* frame = this->frame())
1927             frame->eventHandler()->dispatchFakeMouseMoveEventSoon();
1928     }
1929 }
1930
1931 void RenderObject::propagateStyleToAnonymousChildren(bool blockChildrenOnly)
1932 {
1933     // FIXME: We could save this call when the change only affected non-inherited properties.
1934     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
1935         if (!child->isAnonymous() || child->style()->styleType() != NOPSEUDO)
1936             continue;
1937
1938         if (blockChildrenOnly && !child->isRenderBlock())
1939             continue;
1940
1941 #if ENABLE(FULLSCREEN_API)
1942         if (child->isRenderFullScreen() || child->isRenderFullScreenPlaceholder())
1943             continue;
1944 #endif
1945
1946         RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
1947         if (style()->specifiesColumns()) {
1948             if (child->style()->specifiesColumns())
1949                 newStyle->inheritColumnPropertiesFrom(style());
1950             if (child->style()->columnSpan())
1951                 newStyle->setColumnSpan(ColumnSpanAll);
1952         }
1953         newStyle->setDisplay(child->style()->display());
1954         child->setStyle(newStyle.release());
1955     }
1956 }
1957
1958 void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers)
1959 {
1960     // Optimize the common case
1961     if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && (oldLayers->image() == newLayers->image()))
1962         return;
1963     
1964     // Go through the new layers and addClients first, to avoid removing all clients of an image.
1965     for (const FillLayer* currNew = newLayers; currNew; currNew = currNew->next()) {
1966         if (currNew->image())
1967             currNew->image()->addClient(this);
1968     }
1969
1970     for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) {
1971         if (currOld->image())
1972             currOld->image()->removeClient(this);
1973     }
1974 }
1975
1976 void RenderObject::updateImage(StyleImage* oldImage, StyleImage* newImage)
1977 {
1978     if (oldImage != newImage) {
1979         if (oldImage)
1980             oldImage->removeClient(this);
1981         if (newImage)
1982             newImage->addClient(this);
1983     }
1984 }
1985
1986 LayoutRect RenderObject::viewRect() const
1987 {
1988     return view()->viewRect();
1989 }
1990
1991 FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, bool fixed, bool useTransforms) const
1992 {
1993     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1994     mapLocalToContainer(0, fixed, useTransforms, transformState);
1995     transformState.flatten();
1996     
1997     return transformState.lastPlanarPoint();
1998 }
1999
2000 FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, bool fixed, bool useTransforms) const
2001 {
2002     TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
2003     mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
2004     transformState.flatten();
2005     
2006     return transformState.lastPlanarPoint();
2007 }
2008
2009 void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState, bool* wasFixed) const
2010 {
2011     if (repaintContainer == this)
2012         return;
2013
2014     RenderObject* o = parent();
2015     if (!o)
2016         return;
2017
2018     LayoutPoint centerPoint = roundedLayoutPoint(transformState.mappedPoint());
2019     if (o->isBox() && o->style()->isFlippedBlocksWritingMode())
2020         transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(roundedLayoutPoint(transformState.mappedPoint())) - centerPoint);
2021
2022     LayoutSize columnOffset;
2023     o->adjustForColumns(columnOffset, roundedLayoutPoint(transformState.mappedPoint()));
2024     if (!columnOffset.isZero())
2025         transformState.move(columnOffset);
2026
2027     if (o->hasOverflowClip())
2028         transformState.move(-toRenderBox(o)->layer()->scrolledContentOffset());
2029
2030     o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState, wasFixed);
2031 }
2032
2033 void RenderObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
2034 {
2035     RenderObject* o = parent();
2036     if (o) {
2037         o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
2038         if (o->hasOverflowClip())
2039             transformState.move(toRenderBox(o)->layer()->scrolledContentOffset());
2040     }
2041 }
2042
2043 bool RenderObject::shouldUseTransformFromContainer(const RenderObject* containerObject) const
2044 {
2045 #if ENABLE(3D_RENDERING)
2046     // hasTransform() indicates whether the object has transform, transform-style or perspective. We just care about transform,
2047     // so check the layer's transform directly.
2048     return (hasLayer() && toRenderBoxModelObject(this)->layer()->transform()) || (containerObject && containerObject->style()->hasPerspective());
2049 #else
2050     UNUSED_PARAM(containerObject);
2051     return hasTransform();
2052 #endif
2053 }
2054
2055 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
2056 {
2057     transform.makeIdentity();
2058     transform.translate(offsetInContainer.width(), offsetInContainer.height());
2059     RenderLayer* layer;
2060     if (hasLayer() && (layer = toRenderBoxModelObject(this)->layer()) && layer->transform())
2061         transform.multiply(layer->currentTransform());
2062     
2063 #if ENABLE(3D_RENDERING)
2064     if (containerObject && containerObject->hasLayer() && containerObject->style()->hasPerspective()) {
2065         // Perpsective on the container affects us, so we have to factor it in here.
2066         ASSERT(containerObject->hasLayer());
2067         FloatPoint perspectiveOrigin = toRenderBoxModelObject(containerObject)->layer()->perspectiveOrigin();
2068
2069         TransformationMatrix perspectiveMatrix;
2070         perspectiveMatrix.applyPerspective(containerObject->style()->perspective());
2071         
2072         transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
2073         transform = perspectiveMatrix * transform;
2074         transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
2075     }
2076 #else
2077     UNUSED_PARAM(containerObject);
2078 #endif
2079 }
2080
2081 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool fixed, bool* wasFixed) const
2082 {
2083     // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
2084     // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
2085     TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
2086     mapLocalToContainer(repaintContainer, fixed, true, transformState, wasFixed);
2087     transformState.flatten();
2088     
2089     return transformState.lastPlanarQuad();
2090 }
2091
2092 LayoutSize RenderObject::offsetFromContainer(RenderObject* o, const LayoutPoint& point) const
2093 {
2094     ASSERT(o == container());
2095
2096     LayoutSize offset;
2097
2098     o->adjustForColumns(offset, point);
2099
2100     if (o->hasOverflowClip())
2101         offset -= toRenderBox(o)->layer()->scrolledContentOffset();
2102
2103     return offset;
2104 }
2105
2106 LayoutSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
2107 {
2108     LayoutSize offset;
2109     LayoutPoint referencePoint;
2110     const RenderObject* currContainer = this;
2111     do {
2112         RenderObject* nextContainer = currContainer->container();
2113         ASSERT(nextContainer);  // This means we reached the top without finding container.
2114         if (!nextContainer)
2115             break;
2116         ASSERT(!currContainer->hasTransform());
2117         LayoutSize currentOffset = currContainer->offsetFromContainer(nextContainer, referencePoint);
2118         offset += currentOffset;
2119         referencePoint.move(currentOffset);
2120         currContainer = nextContainer;
2121     } while (currContainer != container);
2122
2123     return offset;
2124 }
2125
2126 LayoutRect RenderObject::localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine)
2127 {
2128     if (extraWidthToEndOfLine)
2129         *extraWidthToEndOfLine = 0;
2130
2131     return LayoutRect();
2132 }
2133
2134 bool RenderObject::isRooted(RenderView** view)
2135 {
2136     RenderObject* o = this;
2137     while (o->parent())
2138         o = o->parent();
2139
2140     if (!o->isRenderView())
2141         return false;
2142
2143     if (view)
2144         *view = toRenderView(o);
2145
2146     return true;
2147 }
2148
2149 bool RenderObject::hasOutlineAnnotation() const
2150 {
2151     return node() && node()->isLink() && document()->printing();
2152 }
2153
2154 RenderObject* RenderObject::container(RenderBoxModelObject* repaintContainer, bool* repaintContainerSkipped) const
2155 {
2156     if (repaintContainerSkipped)
2157         *repaintContainerSkipped = false;
2158
2159     // This method is extremely similar to containingBlock(), but with a few notable
2160     // exceptions.
2161     // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when
2162     // the object is not part of the primary document subtree yet.
2163     // (2) For normal flow elements, it just returns the parent.
2164     // (3) For absolute positioned elements, it will return a relative positioned inline.
2165     // containingBlock() simply skips relpositioned inlines and lets an enclosing block handle
2166     // the layout of the positioned object.  This does mean that computePositionedLogicalWidth and
2167     // computePositionedLogicalHeight have to use container().
2168     RenderObject* o = parent();
2169
2170     if (isText())
2171         return o;
2172
2173     EPosition pos = m_style->position();
2174     if (pos == FixedPosition) {
2175         // container() can be called on an object that is not in the
2176         // tree yet.  We don't call view() since it will assert if it
2177         // can't get back to the canvas.  Instead we just walk as high up
2178         // as we can.  If we're in the tree, we'll get the root.  If we
2179         // aren't we'll get the root of our little subtree (most likely
2180         // we'll just return 0).
2181         // FIXME: The definition of view() has changed to not crawl up the render tree.  It might
2182         // be safe now to use it.
2183         while (o && o->parent() && !(o->hasTransform() && o->isRenderBlock())) {
2184             if (repaintContainerSkipped && o == repaintContainer)
2185                 *repaintContainerSkipped = true;
2186             o = o->parent();
2187         }
2188     } else if (pos == AbsolutePosition) {
2189         // Same goes here.  We technically just want our containing block, but
2190         // we may not have one if we're part of an uninstalled subtree.  We'll
2191         // climb as high as we can though.
2192         while (o && o->style()->position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
2193             if (repaintContainerSkipped && o == repaintContainer)
2194                 *repaintContainerSkipped = true;
2195 #if ENABLE(SVG)
2196             if (o->isSVGForeignObject()) // foreignObject is the containing block for contents inside it
2197                 break;
2198 #endif
2199             o = o->parent();
2200         }
2201     }
2202
2203     return o;
2204 }
2205
2206 bool RenderObject::isSelectionBorder() const
2207 {
2208     SelectionState st = selectionState();
2209     return st == SelectionStart || st == SelectionEnd || st == SelectionBoth;
2210 }
2211
2212 void RenderObject::willBeDestroyed()
2213 {
2214     // Destroy any leftover anonymous children.
2215     RenderObjectChildList* children = virtualChildren();
2216     if (children)
2217         children->destroyLeftoverChildren();
2218
2219     // If this renderer is being autoscrolled, stop the autoscroll timer
2220     
2221     // FIXME: RenderObject::destroy should not get called with a renderer whose document
2222     // has a null frame, so we assert this. However, we don't want release builds to crash which is why we
2223     // check that the frame is not null.
2224     ASSERT(frame());
2225     if (frame() && frame()->eventHandler()->autoscrollRenderer() == this)
2226         frame()->eventHandler()->stopAutoscrollTimer(true);
2227
2228     if (AXObjectCache::accessibilityEnabled()) {
2229         document()->axObjectCache()->childrenChanged(this->parent());
2230         document()->axObjectCache()->remove(this);
2231     }
2232     animation()->cancelAnimations(this);
2233
2234     remove();
2235
2236     // If this renderer had a parent, remove should have destroyed any counters
2237     // attached to this renderer and marked the affected other counters for
2238     // reevaluation. This apparently redundant check is here for the case when
2239     // this renderer had no parent at the time remove() was called.
2240
2241     if (m_hasCounterNodeMap)
2242         RenderCounter::destroyCounterNodes(this);
2243
2244     // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
2245     // be moved into RenderBoxModelObject::destroy.
2246     if (hasLayer()) {
2247         setHasLayer(false);
2248         toRenderBoxModelObject(this)->destroyLayer();
2249     }
2250 }
2251
2252 void RenderObject::destroy()
2253 {
2254     willBeDestroyed();
2255     arenaDelete(renderArena(), this);
2256 }
2257
2258 void RenderObject::arenaDelete(RenderArena* arena, void* base)
2259 {
2260     if (m_style) {
2261         for (const FillLayer* bgLayer = m_style->backgroundLayers(); bgLayer; bgLayer = bgLayer->next()) {
2262             if (StyleImage* backgroundImage = bgLayer->image())
2263                 backgroundImage->removeClient(this);
2264         }
2265
2266         for (const FillLayer* maskLayer = m_style->maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
2267             if (StyleImage* maskImage = maskLayer->image())
2268                 maskImage->removeClient(this);
2269         }
2270
2271         if (StyleImage* borderImage = m_style->borderImage().image())
2272             borderImage->removeClient(this);
2273
2274         if (StyleImage* maskBoxImage = m_style->maskBoxImage().image())
2275             maskBoxImage->removeClient(this);
2276     }
2277
2278 #ifndef NDEBUG
2279     void* savedBase = baseOfRenderObjectBeingDeleted;
2280     baseOfRenderObjectBeingDeleted = base;
2281 #endif
2282     delete this;
2283 #ifndef NDEBUG
2284     baseOfRenderObjectBeingDeleted = savedBase;
2285 #endif
2286
2287     // Recover the size left there for us by operator delete and free the memory.
2288     arena->free(*(size_t*)base, base);
2289 }
2290
2291 VisiblePosition RenderObject::positionForPoint(const LayoutPoint&)
2292 {
2293     return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
2294 }
2295
2296 void RenderObject::updateDragState(bool dragOn)
2297 {
2298     bool valueChanged = (dragOn != m_isDragging);
2299     m_isDragging = dragOn;
2300     if (valueChanged && style()->affectedByDragRules() && node())
2301         node()->setNeedsStyleRecalc();
2302     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
2303         curr->updateDragState(dragOn);
2304 }
2305
2306 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
2307 {
2308     bool inside = false;
2309     if (hitTestFilter != HitTestSelf) {
2310         // First test the foreground layer (lines and inlines).
2311         inside = nodeAtPoint(request, result, pointInContainer, accumulatedOffset, HitTestForeground);
2312
2313         // Test floats next.
2314         if (!inside)
2315             inside = nodeAtPoint(request, result, pointInContainer, accumulatedOffset, HitTestFloat);
2316
2317         // Finally test to see if the mouse is in the background (within a child block's background).
2318         if (!inside)
2319             inside = nodeAtPoint(request, result, pointInContainer, accumulatedOffset, HitTestChildBlockBackgrounds);
2320     }
2321
2322     // See if the mouse is inside us but not any of our descendants
2323     if (hitTestFilter != HitTestDescendants && !inside)
2324         inside = nodeAtPoint(request, result, pointInContainer, accumulatedOffset, HitTestBlockBackground);
2325
2326     return inside;
2327 }
2328
2329 void RenderObject::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
2330 {
2331     if (result.innerNode())
2332         return;
2333
2334     Node* n = node();
2335     if (n) {
2336         result.setInnerNode(n);
2337         if (!result.innerNonSharedNode())
2338             result.setInnerNonSharedNode(n);
2339         result.setLocalPoint(point);
2340     }
2341 }
2342
2343 bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& /*pointInContainer*/, const LayoutPoint& /*accumulatedOffset*/, HitTestAction)
2344 {
2345     return false;
2346 }
2347
2348 void RenderObject::scheduleRelayout()
2349 {
2350     if (isRenderView()) {
2351         FrameView* view = toRenderView(this)->frameView();
2352         if (view)
2353             view->scheduleRelayout();
2354     } else {
2355         if (isRooted()) {
2356             if (RenderView* renderView = view()) {
2357                 if (FrameView* frameView = renderView->frameView())
2358                     frameView->scheduleRelayoutOfSubtree(this);
2359             }
2360         }
2361     }
2362 }
2363
2364 void RenderObject::layout()
2365 {
2366     ASSERT(needsLayout());
2367     RenderObject* child = firstChild();
2368     while (child) {
2369         child->layoutIfNeeded();
2370         ASSERT(!child->needsLayout());
2371         child = child->nextSibling();
2372     }
2373     setNeedsLayout(false);
2374 }
2375
2376 PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const
2377 {
2378     if (!document()->usesFirstLineRules())
2379         return 0;
2380
2381     ASSERT(!isText());
2382
2383     RefPtr<RenderStyle> result;
2384
2385     if (isBlockFlow()) {
2386         if (RenderBlock* firstLineBlock = this->firstLineBlock())
2387             result = firstLineBlock->getUncachedPseudoStyle(FIRST_LINE, style, firstLineBlock == this ? style : 0);
2388     } else if (!isAnonymous() && isRenderInline()) {
2389         RenderStyle* parentStyle = parent()->firstLineStyle();
2390         if (parentStyle != parent()->style())
2391             result = getUncachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle, style);
2392     }
2393
2394     return result.release();
2395 }
2396
2397 RenderStyle* RenderObject::firstLineStyleSlowCase() const
2398 {
2399     ASSERT(document()->usesFirstLineRules());
2400
2401     RenderStyle* style = m_style.get();
2402     const RenderObject* renderer = isText() ? parent() : this;
2403     if (renderer->isBlockFlow()) {
2404         if (RenderBlock* firstLineBlock = renderer->firstLineBlock())
2405             style = firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style);
2406     } else if (!renderer->isAnonymous() && renderer->isRenderInline()) {
2407         RenderStyle* parentStyle = renderer->parent()->firstLineStyle();
2408         if (parentStyle != renderer->parent()->style()) {
2409             // A first-line style is in effect. Cache a first-line style for ourselves.
2410             renderer->style()->setHasPseudoStyle(FIRST_LINE_INHERITED);
2411             style = renderer->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle);
2412         }
2413     }
2414
2415     return style;
2416 }
2417
2418 RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
2419 {
2420     if (pseudo < FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
2421         return 0;
2422
2423     RenderStyle* cachedStyle = style()->getCachedPseudoStyle(pseudo);
2424     if (cachedStyle)
2425         return cachedStyle;
2426     
2427     RefPtr<RenderStyle> result = getUncachedPseudoStyle(pseudo, parentStyle);
2428     if (result)
2429         return style()->addCachedPseudoStyle(result.release());
2430     return 0;
2431 }
2432
2433 PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle, RenderStyle* ownStyle) const
2434 {
2435     if (pseudo < FIRST_INTERNAL_PSEUDOID && !ownStyle && !style()->hasPseudoStyle(pseudo))
2436         return 0;
2437     
2438     if (!parentStyle) {
2439         ASSERT(!ownStyle);
2440         parentStyle = style();
2441     }
2442
2443     Node* n = node();
2444     while (n && !n->isElementNode())
2445         n = n->parentNode();
2446     if (!n)
2447         return 0;
2448
2449     RefPtr<RenderStyle> result;
2450     if (pseudo == FIRST_LINE_INHERITED) {
2451         result = document()->styleSelector()->styleForElement(static_cast<Element*>(n), parentStyle, false);
2452         result->setStyleType(FIRST_LINE_INHERITED);
2453     } else
2454         result = document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<Element*>(n), parentStyle);
2455     return result.release();
2456 }
2457
2458 static Color decorationColor(RenderObject* renderer)
2459 {
2460     Color result;
2461     if (renderer->style()->textStrokeWidth() > 0) {
2462         // Prefer stroke color if possible but not if it's fully transparent.
2463         result = renderer->style()->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
2464         if (result.alpha())
2465             return result;
2466     }
2467     
2468     result = renderer->style()->visitedDependentColor(CSSPropertyWebkitTextFillColor);
2469     return result;
2470 }
2471
2472 void RenderObject::getTextDecorationColors(int decorations, Color& underline, Color& overline,
2473                                            Color& linethrough, bool quirksMode)
2474 {
2475     RenderObject* curr = this;
2476     do {
2477         int currDecs = curr->style()->textDecoration();
2478         if (currDecs) {
2479             if (currDecs & UNDERLINE) {
2480                 decorations &= ~UNDERLINE;
2481                 underline = decorationColor(curr);
2482             }
2483             if (currDecs & OVERLINE) {
2484                 decorations &= ~OVERLINE;
2485                 overline = decorationColor(curr);
2486             }
2487             if (currDecs & LINE_THROUGH) {
2488                 decorations &= ~LINE_THROUGH;
2489                 linethrough = decorationColor(curr);
2490             }
2491         }
2492         curr = curr->parent();
2493         if (curr && curr->isAnonymousBlock() && toRenderBlock(curr)->continuation())
2494             curr = toRenderBlock(curr)->continuation();
2495     } while (curr && decorations && (!quirksMode || !curr->node() ||
2496                                      (!curr->node()->hasTagName(aTag) && !curr->node()->hasTagName(fontTag))));
2497
2498     // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
2499     if (decorations && curr) {
2500         if (decorations & UNDERLINE)
2501             underline = decorationColor(curr);
2502         if (decorations & OVERLINE)
2503             overline = decorationColor(curr);
2504         if (decorations & LINE_THROUGH)
2505             linethrough = decorationColor(curr);
2506     }
2507 }
2508
2509 #if ENABLE(DASHBOARD_SUPPORT)
2510 void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions)
2511 {
2512     // Convert the style regions to absolute coordinates.
2513     if (style()->visibility() != VISIBLE || !isBox())
2514         return;
2515     
2516     RenderBox* box = toRenderBox(this);
2517
2518     const Vector<StyleDashboardRegion>& styleRegions = style()->dashboardRegions();
2519     unsigned i, count = styleRegions.size();
2520     for (i = 0; i < count; i++) {
2521         StyleDashboardRegion styleRegion = styleRegions[i];
2522
2523         LayoutUnit w = box->width();
2524         LayoutUnit h = box->height();
2525
2526         DashboardRegionValue region;
2527         region.label = styleRegion.label;
2528         region.bounds = LayoutRect(styleRegion.offset.left().value(),
2529                                    styleRegion.offset.top().value(),
2530                                    w - styleRegion.offset.left().value() - styleRegion.offset.right().value(),
2531                                    h - styleRegion.offset.top().value() - styleRegion.offset.bottom().value());
2532         region.type = styleRegion.type;
2533
2534         region.clip = region.bounds;
2535         computeAbsoluteRepaintRect(region.clip);
2536         if (region.clip.height() < 0) {
2537             region.clip.setHeight(0);
2538             region.clip.setWidth(0);
2539         }
2540
2541         FloatPoint absPos = localToAbsolute();
2542         region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
2543         region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
2544
2545         if (frame()) {
2546             float deviceScaleFactor = frame()->page()->deviceScaleFactor();
2547             if (deviceScaleFactor != 1.0f) {
2548                 region.bounds.scale(deviceScaleFactor);
2549                 region.clip.scale(deviceScaleFactor);
2550             }
2551         }
2552
2553         regions.append(region);
2554     }
2555 }
2556
2557 void RenderObject::collectDashboardRegions(Vector<DashboardRegionValue>& regions)
2558 {
2559     // RenderTexts don't have their own style, they just use their parent's style,
2560     // so we don't want to include them.
2561     if (isText())
2562         return;
2563
2564     addDashboardRegions(regions);
2565     for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
2566         curr->collectDashboardRegions(regions);
2567 }
2568 #endif
2569
2570 bool RenderObject::willRenderImage(CachedImage*)
2571 {
2572     // Without visibility we won't render (and therefore don't care about animation).
2573     if (style()->visibility() != VISIBLE)
2574         return false;
2575
2576     // 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)
2577     // then we don't want to render either.
2578     return !document()->inPageCache() && !document()->view()->isOffscreen();
2579 }
2580
2581 LayoutUnit RenderObject::maximalOutlineSize(PaintPhase p) const
2582 {
2583     if (p != PaintPhaseOutline && p != PaintPhaseSelfOutline && p != PaintPhaseChildOutlines)
2584         return 0;
2585     return toRenderView(document()->renderer())->maximalOutlineSize();
2586 }
2587
2588 int RenderObject::caretMinOffset() const
2589 {
2590     return 0;
2591 }
2592
2593 int RenderObject::caretMaxOffset() const
2594 {
2595     if (isReplaced())
2596         return node() ? max(1U, node()->childNodeCount()) : 1;
2597     if (isHR())
2598         return 1;
2599     return 0;
2600 }
2601
2602 int RenderObject::previousOffset(int current) const
2603 {
2604     return current - 1;
2605 }
2606
2607 int RenderObject::previousOffsetForBackwardDeletion(int current) const
2608 {
2609     return current - 1;
2610 }
2611
2612 int RenderObject::nextOffset(int current) const
2613 {
2614     return current + 1;
2615 }
2616
2617 void RenderObject::adjustRectForOutlineAndShadow(LayoutRect& rect) const
2618 {
2619     LayoutUnit outlineSize = outlineStyleForRepaint()->outlineSize();
2620     if (const ShadowData* boxShadow = style()->boxShadow()) {
2621         boxShadow->adjustRectForShadow(rect, outlineSize);
2622         return;
2623     }
2624
2625     rect.inflate(outlineSize);
2626 }
2627
2628 AnimationController* RenderObject::animation() const
2629 {
2630     return frame()->animation();
2631 }
2632
2633 void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
2634 {
2635     imageChanged(static_cast<WrappedImagePtr>(image), rect);
2636 }
2637
2638 RenderBoxModelObject* RenderObject::offsetParent() const
2639 {
2640     // If any of the following holds true return null and stop this algorithm:
2641     // A is the root element.
2642     // A is the HTML body element.
2643     // The computed value of the position property for element A is fixed.
2644     if (isRoot() || isBody() || (isPositioned() && style()->position() == FixedPosition))
2645         return 0;
2646
2647     // If A is an area HTML element which has a map HTML element somewhere in the ancestor
2648     // chain return the nearest ancestor map HTML element and stop this algorithm.
2649     // FIXME: Implement!
2650     
2651     // Return the nearest ancestor element of A for which at least one of the following is
2652     // true and stop this algorithm if such an ancestor is found:
2653     //     * The computed value of the position property is not static.
2654     //     * It is the HTML body element.
2655     //     * The computed value of the position property of A is static and the ancestor
2656     //       is one of the following HTML elements: td, th, or table.
2657     //     * Our own extension: if there is a difference in the effective zoom
2658
2659     bool skipTables = isPositioned() || isRelPositioned();
2660     float currZoom = style()->effectiveZoom();
2661     RenderObject* curr = parent();
2662     while (curr && (!curr->node() || (!curr->isPositioned() && !curr->isRelPositioned() && !curr->isBody()))) {
2663         Node* element = curr->node();
2664         if (!skipTables && element && (element->hasTagName(tableTag) || element->hasTagName(tdTag) || element->hasTagName(thTag)))
2665             break;
2666
2667         float newZoom = curr->style()->effectiveZoom();
2668         if (currZoom != newZoom)
2669             break;
2670         currZoom = newZoom;
2671         curr = curr->parent();
2672     }
2673     return curr && curr->isBoxModelObject() ? toRenderBoxModelObject(curr) : 0;
2674 }
2675
2676 VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity)
2677 {
2678     // If this is a non-anonymous renderer in an editable area, then it's simple.
2679     if (Node* node = this->node()) {
2680         if (!node->rendererIsEditable()) {
2681             // If it can be found, we prefer a visually equivalent position that is editable. 
2682             Position position = createLegacyEditingPosition(node, offset);
2683             Position candidate = position.downstream(CanCrossEditingBoundary);
2684             if (candidate.deprecatedNode()->rendererIsEditable())
2685                 return VisiblePosition(candidate, affinity);
2686             candidate = position.upstream(CanCrossEditingBoundary);
2687             if (candidate.deprecatedNode()->rendererIsEditable())
2688                 return VisiblePosition(candidate, affinity);
2689         }
2690         // FIXME: Eliminate legacy editing positions
2691         return VisiblePosition(createLegacyEditingPosition(node, offset), affinity);
2692     }
2693
2694     // We don't want to cross the boundary between editable and non-editable
2695     // regions of the document, but that is either impossible or at least
2696     // extremely unlikely in any normal case because we stop as soon as we
2697     // find a single non-anonymous renderer.
2698
2699     // Find a nearby non-anonymous renderer.
2700     RenderObject* child = this;
2701     while (RenderObject* parent = child->parent()) {
2702         // Find non-anonymous content after.
2703         RenderObject* renderer = child;
2704         while ((renderer = renderer->nextInPreOrder(parent))) {
2705             if (Node* node = renderer->node())
2706                 return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
2707         }
2708
2709         // Find non-anonymous content before.
2710         renderer = child;
2711         while ((renderer = renderer->previousInPreOrder())) {
2712             if (renderer == parent)
2713                 break;
2714             if (Node* node = renderer->node())
2715                 return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
2716         }
2717
2718         // Use the parent itself unless it too is anonymous.
2719         if (Node* node = parent->node())
2720             return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
2721
2722         // Repeat at the next level up.
2723         child = parent;
2724     }
2725
2726     // Everything was anonymous. Give up.
2727     return VisiblePosition();
2728 }
2729
2730 VisiblePosition RenderObject::createVisiblePosition(const Position& position)
2731 {
2732     if (position.isNotNull())
2733         return VisiblePosition(position);
2734
2735     ASSERT(!node());
2736     return createVisiblePosition(0, DOWNSTREAM);
2737 }
2738
2739 CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
2740 {
2741     return SetCursorBasedOnStyle;
2742 }
2743
2744 #if ENABLE(SVG)
2745
2746 RenderSVGResourceContainer* RenderObject::toRenderSVGResourceContainer()
2747 {
2748     ASSERT_NOT_REACHED();
2749     return 0;
2750 }
2751
2752 void RenderObject::setNeedsBoundariesUpdate()
2753 {
2754     if (RenderObject* renderer = parent())
2755         renderer->setNeedsBoundariesUpdate();
2756 }
2757
2758 FloatRect RenderObject::objectBoundingBox() const
2759 {
2760     ASSERT_NOT_REACHED();
2761     return FloatRect();
2762 }
2763
2764 FloatRect RenderObject::strokeBoundingBox() const
2765 {
2766     ASSERT_NOT_REACHED();
2767     return FloatRect();
2768 }
2769
2770 // Returns the smallest rectangle enclosing all of the painted content
2771 // respecting clipping, masking, filters, opacity, stroke-width and markers
2772 FloatRect RenderObject::repaintRectInLocalCoordinates() const
2773 {
2774     ASSERT_NOT_REACHED();
2775     return FloatRect();
2776 }
2777
2778 AffineTransform RenderObject::localTransform() const
2779 {
2780     static const AffineTransform identity;
2781     return identity;
2782 }
2783
2784 const AffineTransform& RenderObject::localToParentTransform() const
2785 {
2786     static const AffineTransform identity;
2787     return identity;
2788 }
2789
2790 bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
2791 {
2792     ASSERT_NOT_REACHED();
2793     return false;
2794 }
2795
2796 #endif // ENABLE(SVG)
2797
2798 } // namespace WebCore
2799
2800 #ifndef NDEBUG
2801
2802 void showTree(const WebCore::RenderObject* object)
2803 {
2804     if (object)
2805         object->showTreeForThis();
2806 }
2807
2808 void showLineTree(const WebCore::RenderObject* object)
2809 {
2810     if (object)
2811         object->showLineTreeForThis();
2812 }
2813
2814 void showRenderTree(const WebCore::RenderObject* object1)
2815 {
2816     showRenderTree(object1, 0);
2817 }
2818
2819 void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2)
2820 {
2821     if (object1) {
2822         const WebCore::RenderObject* root = object1;
2823         while (root->parent())
2824             root = root->parent();
2825         root->showRenderTreeAndMark(object1, "*", object2, "-", 0);
2826     }
2827 }
2828
2829 #endif