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