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