Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2000 Dirk Mueller (mueller (at) kde.org)
      5  *           (C) 2004 Allan Sandfeld Jensen (kde (at) carewolf.com)
      6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
      7  * Copyright (C) 2009 Google Inc. All rights reserved.
      8  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
      9  *
     10  * This library is free software; you can redistribute it and/or
     11  * modify it under the terms of the GNU Library General Public
     12  * License as published by the Free Software Foundation; either
     13  * version 2 of the License, or (at your option) any later version.
     14  *
     15  * This library is distributed in the hope that it will be useful,
     16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     18  * Library General Public License for more details.
     19  *
     20  * You should have received a copy of the GNU Library General Public License
     21  * along with this library; see the file COPYING.LIB.  If not, write to
     22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     23  * Boston, MA 02110-1301, USA.
     24  *
     25  */
     26 
     27 #include "config.h"
     28 #include "core/rendering/RenderObject.h"
     29 
     30 #include "core/HTMLNames.h"
     31 #include "core/accessibility/AXObjectCache.h"
     32 #include "core/animation/ActiveAnimations.h"
     33 #include "core/css/resolver/StyleResolver.h"
     34 #include "core/dom/ElementTraversal.h"
     35 #include "core/dom/shadow/ShadowRoot.h"
     36 #include "core/editing/EditingBoundary.h"
     37 #include "core/editing/FrameSelection.h"
     38 #include "core/editing/htmlediting.h"
     39 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
     40 #include "core/fetch/ResourceLoader.h"
     41 #include "core/frame/FrameView.h"
     42 #include "core/frame/LocalFrame.h"
     43 #include "core/html/HTMLAnchorElement.h"
     44 #include "core/html/HTMLElement.h"
     45 #include "core/html/HTMLHtmlElement.h"
     46 #include "core/html/HTMLTableCellElement.h"
     47 #include "core/html/HTMLTableElement.h"
     48 #include "core/page/AutoscrollController.h"
     49 #include "core/page/EventHandler.h"
     50 #include "core/page/Page.h"
     51 #include "core/frame/Settings.h"
     52 #include "core/frame/UseCounter.h"
     53 #include "core/rendering/FlowThreadController.h"
     54 #include "core/rendering/HitTestResult.h"
     55 #include "core/rendering/RenderCounter.h"
     56 #include "core/rendering/RenderDeprecatedFlexibleBox.h"
     57 #include "core/rendering/RenderFlexibleBox.h"
     58 #include "core/rendering/RenderFlowThread.h"
     59 #include "core/rendering/RenderGeometryMap.h"
     60 #include "core/rendering/RenderGrid.h"
     61 #include "core/rendering/RenderImage.h"
     62 #include "core/rendering/RenderImageResourceStyleImage.h"
     63 #include "core/rendering/RenderInline.h"
     64 #include "core/rendering/RenderLayer.h"
     65 #include "core/rendering/RenderListItem.h"
     66 #include "core/rendering/RenderMarquee.h"
     67 #include "core/rendering/RenderScrollbarPart.h"
     68 #include "core/rendering/RenderTableCaption.h"
     69 #include "core/rendering/RenderTableCell.h"
     70 #include "core/rendering/RenderTableCol.h"
     71 #include "core/rendering/RenderTableRow.h"
     72 #include "core/rendering/RenderTheme.h"
     73 #include "core/rendering/RenderView.h"
     74 #include "core/rendering/compositing/CompositedLayerMapping.h"
     75 #include "core/rendering/compositing/RenderLayerCompositor.h"
     76 #include "core/rendering/style/ContentData.h"
     77 #include "core/rendering/style/ShadowList.h"
     78 #include "platform/JSONValues.h"
     79 #include "platform/Partitions.h"
     80 #include "platform/RuntimeEnabledFeatures.h"
     81 #include "platform/TraceEvent.h"
     82 #include "platform/TracedValue.h"
     83 #include "platform/geometry/TransformState.h"
     84 #include "platform/graphics/GraphicsContext.h"
     85 #include "wtf/RefCountedLeakCounter.h"
     86 #include "wtf/text/StringBuilder.h"
     87 #include "wtf/text/WTFString.h"
     88 #include <algorithm>
     89 #ifndef NDEBUG
     90 #include <stdio.h>
     91 #endif
     92 
     93 using namespace std;
     94 
     95 namespace WebCore {
     96 
     97 namespace {
     98 
     99 static bool gModifyRenderTreeStructureAnyState = false;
    100 
    101 } // namespace
    102 
    103 using namespace HTMLNames;
    104 
    105 #ifndef NDEBUG
    106 
    107 RenderObject::SetLayoutNeededForbiddenScope::SetLayoutNeededForbiddenScope(RenderObject& renderObject)
    108     : m_renderObject(renderObject)
    109     , m_preexistingForbidden(m_renderObject.isSetNeedsLayoutForbidden())
    110 {
    111     m_renderObject.setNeedsLayoutIsForbidden(true);
    112 }
    113 
    114 RenderObject::SetLayoutNeededForbiddenScope::~SetLayoutNeededForbiddenScope()
    115 {
    116     m_renderObject.setNeedsLayoutIsForbidden(m_preexistingForbidden);
    117 }
    118 #endif
    119 
    120 struct SameSizeAsRenderObject {
    121     virtual ~SameSizeAsRenderObject() { } // Allocate vtable pointer.
    122     void* pointers[5];
    123 #ifndef NDEBUG
    124     unsigned m_debugBitfields : 2;
    125 #endif
    126     unsigned m_bitfields;
    127     unsigned m_bitfields2;
    128     LayoutRect rect; // Stores the previous paint invalidation rect.
    129     LayoutPoint position; // Stores the previous position from the paint invalidation container.
    130 };
    131 
    132 COMPILE_ASSERT(sizeof(RenderObject) == sizeof(SameSizeAsRenderObject), RenderObject_should_stay_small);
    133 
    134 bool RenderObject::s_affectsParentBlock = false;
    135 
    136 void* RenderObject::operator new(size_t sz)
    137 {
    138     ASSERT(isMainThread());
    139     return partitionAlloc(Partitions::getRenderingPartition(), sz);
    140 }
    141 
    142 void RenderObject::operator delete(void* ptr)
    143 {
    144     ASSERT(isMainThread());
    145     partitionFree(ptr);
    146 }
    147 
    148 RenderObject* RenderObject::createObject(Element* element, RenderStyle* style)
    149 {
    150     ASSERT(isAllowedToModifyRenderTreeStructure(element->document()));
    151 
    152     // Minimal support for content properties replacing an entire element.
    153     // Works only if we have exactly one piece of content and it's a URL.
    154     // Otherwise acts as if we didn't support this feature.
    155     const ContentData* contentData = style->contentData();
    156     if (contentData && !contentData->next() && contentData->isImage() && !element->isPseudoElement()) {
    157         RenderImage* image = new RenderImage(element);
    158         // RenderImageResourceStyleImage requires a style being present on the image but we don't want to
    159         // trigger a style change now as the node is not fully attached. Moving this code to style change
    160         // doesn't make sense as it should be run once at renderer creation.
    161         image->setStyleInternal(style);
    162         if (const StyleImage* styleImage = static_cast<const ImageContentData*>(contentData)->image()) {
    163             image->setImageResource(RenderImageResourceStyleImage::create(const_cast<StyleImage*>(styleImage)));
    164             image->setIsGeneratedContent();
    165         } else
    166             image->setImageResource(RenderImageResource::create());
    167         image->setStyleInternal(nullptr);
    168         return image;
    169     }
    170 
    171     switch (style->display()) {
    172     case NONE:
    173         return 0;
    174     case INLINE:
    175         return new RenderInline(element);
    176     case BLOCK:
    177     case INLINE_BLOCK:
    178         return new RenderBlockFlow(element);
    179     case LIST_ITEM:
    180         return new RenderListItem(element);
    181     case TABLE:
    182     case INLINE_TABLE:
    183         return new RenderTable(element);
    184     case TABLE_ROW_GROUP:
    185     case TABLE_HEADER_GROUP:
    186     case TABLE_FOOTER_GROUP:
    187         return new RenderTableSection(element);
    188     case TABLE_ROW:
    189         return new RenderTableRow(element);
    190     case TABLE_COLUMN_GROUP:
    191     case TABLE_COLUMN:
    192         return new RenderTableCol(element);
    193     case TABLE_CELL:
    194         return new RenderTableCell(element);
    195     case TABLE_CAPTION:
    196         return new RenderTableCaption(element);
    197     case BOX:
    198     case INLINE_BOX:
    199         return new RenderDeprecatedFlexibleBox(element);
    200     case FLEX:
    201     case INLINE_FLEX:
    202         return new RenderFlexibleBox(element);
    203     case GRID:
    204     case INLINE_GRID:
    205         return new RenderGrid(element);
    206     }
    207 
    208     return 0;
    209 }
    210 
    211 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, renderObjectCounter, ("RenderObject"));
    212 
    213 RenderObject::RenderObject(Node* node)
    214     : ImageResourceClient()
    215     , m_style(nullptr)
    216     , m_node(node)
    217     , m_parent(0)
    218     , m_previous(0)
    219     , m_next(0)
    220 #ifndef NDEBUG
    221     , m_hasAXObject(false)
    222     , m_setNeedsLayoutForbidden(false)
    223 #endif
    224     , m_bitfields(node)
    225 {
    226 #ifndef NDEBUG
    227     renderObjectCounter.increment();
    228 #endif
    229 }
    230 
    231 RenderObject::~RenderObject()
    232 {
    233     ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->removeRenderObject(this);
    234 #ifndef NDEBUG
    235     ASSERT(!m_hasAXObject);
    236     renderObjectCounter.decrement();
    237 #endif
    238 }
    239 
    240 String RenderObject::debugName() const
    241 {
    242     StringBuilder name;
    243     name.append(renderName());
    244 
    245     if (Node* node = this->node()) {
    246         name.append(' ');
    247         name.append(node->debugName());
    248     }
    249 
    250     return name.toString();
    251 }
    252 
    253 bool RenderObject::isDescendantOf(const RenderObject* obj) const
    254 {
    255     for (const RenderObject* r = this; r; r = r->m_parent) {
    256         if (r == obj)
    257             return true;
    258     }
    259     return false;
    260 }
    261 
    262 bool RenderObject::isHR() const
    263 {
    264     return isHTMLHRElement(node());
    265 }
    266 
    267 bool RenderObject::isLegend() const
    268 {
    269     return isHTMLLegendElement(node());
    270 }
    271 
    272 void RenderObject::setFlowThreadStateIncludingDescendants(FlowThreadState state)
    273 {
    274     for (RenderObject *object = this; object; object = object->nextInPreOrder(this)) {
    275         // If object is a fragmentation context it already updated the descendants flag accordingly.
    276         if (object->isRenderFlowThread())
    277             continue;
    278         ASSERT(state != object->flowThreadState());
    279         object->setFlowThreadState(state);
    280     }
    281 }
    282 
    283 bool RenderObject::requiresAnonymousTableWrappers(const RenderObject* newChild) const
    284 {
    285     // Check should agree with:
    286     // CSS 2.1 Tables: 17.2.1 Anonymous table objects
    287     // http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes
    288     if (newChild->isRenderTableCol()) {
    289         const RenderTableCol* newTableColumn = toRenderTableCol(newChild);
    290         bool isColumnInColumnGroup = newTableColumn->isTableColumn() && isRenderTableCol();
    291         return !isTable() && !isColumnInColumnGroup;
    292     } else if (newChild->isTableCaption())
    293         return !isTable();
    294     else if (newChild->isTableSection())
    295         return !isTable();
    296     else if (newChild->isTableRow())
    297         return !isTableSection();
    298     else if (newChild->isTableCell())
    299         return !isTableRow();
    300     return false;
    301 }
    302 
    303 void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
    304 {
    305     ASSERT(isAllowedToModifyRenderTreeStructure(document()));
    306 
    307     RenderObjectChildList* children = virtualChildren();
    308     ASSERT(children);
    309     if (!children)
    310         return;
    311 
    312     if (requiresAnonymousTableWrappers(newChild)) {
    313         // Generate an anonymous table or reuse existing one from previous child
    314         // Per: 17.2.1 Anonymous table objects 3. Generate missing parents
    315         // http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes
    316         RenderTable* table;
    317         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : children->lastChild();
    318         if (afterChild && afterChild->isAnonymous() && afterChild->isTable() && !afterChild->isBeforeContent())
    319             table = toRenderTable(afterChild);
    320         else {
    321             table = RenderTable::createAnonymousWithParentRenderer(this);
    322             addChild(table, beforeChild);
    323         }
    324         table->addChild(newChild);
    325     } else
    326         children->insertChildNode(this, newChild, beforeChild);
    327 
    328     if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE)
    329         toRenderText(newChild)->transformText();
    330 
    331     // SVG creates renderers for <g display="none">, as SVG requires children of hidden
    332     // <g>s to have renderers - at least that's how our implementation works. Consider:
    333     // <g display="none"><foreignObject><body style="position: relative">FOO...
    334     // - layerTypeRequired() would return true for the <body>, creating a new RenderLayer
    335     // - when the document is painted, both layers are painted. The <body> layer doesn't
    336     //   know that it's inside a "hidden SVG subtree", and thus paints, even if it shouldn't.
    337     // To avoid the problem alltogether, detect early if we're inside a hidden SVG subtree
    338     // and stop creating layers at all for these cases - they're not used anyways.
    339     if (newChild->hasLayer() && !layerCreationAllowedForSubtree())
    340         toRenderLayerModelObject(newChild)->layer()->removeOnlyThisLayer();
    341 }
    342 
    343 void RenderObject::removeChild(RenderObject* oldChild)
    344 {
    345     ASSERT(isAllowedToModifyRenderTreeStructure(document()));
    346 
    347     RenderObjectChildList* children = virtualChildren();
    348     ASSERT(children);
    349     if (!children)
    350         return;
    351 
    352     children->removeChildNode(this, oldChild);
    353 }
    354 
    355 RenderObject* RenderObject::nextInPreOrder() const
    356 {
    357     if (RenderObject* o = slowFirstChild())
    358         return o;
    359 
    360     return nextInPreOrderAfterChildren();
    361 }
    362 
    363 RenderObject* RenderObject::nextInPreOrderAfterChildren() const
    364 {
    365     RenderObject* o;
    366     if (!(o = nextSibling())) {
    367         o = parent();
    368         while (o && !o->nextSibling())
    369             o = o->parent();
    370         if (o)
    371             o = o->nextSibling();
    372     }
    373 
    374     return o;
    375 }
    376 
    377 RenderObject* RenderObject::nextInPreOrder(const RenderObject* stayWithin) const
    378 {
    379     if (RenderObject* o = slowFirstChild())
    380         return o;
    381 
    382     return nextInPreOrderAfterChildren(stayWithin);
    383 }
    384 
    385 RenderObject* RenderObject::nextInPreOrderAfterChildren(const RenderObject* stayWithin) const
    386 {
    387     if (this == stayWithin)
    388         return 0;
    389 
    390     const RenderObject* current = this;
    391     RenderObject* next;
    392     while (!(next = current->nextSibling())) {
    393         current = current->parent();
    394         if (!current || current == stayWithin)
    395             return 0;
    396     }
    397     return next;
    398 }
    399 
    400 RenderObject* RenderObject::previousInPreOrder() const
    401 {
    402     if (RenderObject* o = previousSibling()) {
    403         while (RenderObject* lastChild = o->slowLastChild())
    404             o = lastChild;
    405         return o;
    406     }
    407 
    408     return parent();
    409 }
    410 
    411 RenderObject* RenderObject::previousInPreOrder(const RenderObject* stayWithin) const
    412 {
    413     if (this == stayWithin)
    414         return 0;
    415 
    416     return previousInPreOrder();
    417 }
    418 
    419 RenderObject* RenderObject::childAt(unsigned index) const
    420 {
    421     RenderObject* child = slowFirstChild();
    422     for (unsigned i = 0; child && i < index; i++)
    423         child = child->nextSibling();
    424     return child;
    425 }
    426 
    427 RenderObject* RenderObject::lastLeafChild() const
    428 {
    429     RenderObject* r = slowLastChild();
    430     while (r) {
    431         RenderObject* n = 0;
    432         n = r->slowLastChild();
    433         if (!n)
    434             break;
    435         r = n;
    436     }
    437     return r;
    438 }
    439 
    440 static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject*& newObject,
    441                       RenderLayer*& beforeChild)
    442 {
    443     if (obj->hasLayer()) {
    444         if (!beforeChild && newObject) {
    445             // We need to figure out the layer that follows newObject. We only do
    446             // this the first time we find a child layer, and then we update the
    447             // pointer values for newObject and beforeChild used by everyone else.
    448             beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject);
    449             newObject = 0;
    450         }
    451         parentLayer->addChild(toRenderLayerModelObject(obj)->layer(), beforeChild);
    452         return;
    453     }
    454 
    455     for (RenderObject* curr = obj->slowFirstChild(); curr; curr = curr->nextSibling())
    456         addLayers(curr, parentLayer, newObject, beforeChild);
    457 }
    458 
    459 void RenderObject::addLayers(RenderLayer* parentLayer)
    460 {
    461     if (!parentLayer)
    462         return;
    463 
    464     RenderObject* object = this;
    465     RenderLayer* beforeChild = 0;
    466     WebCore::addLayers(this, parentLayer, object, beforeChild);
    467 }
    468 
    469 void RenderObject::removeLayers(RenderLayer* parentLayer)
    470 {
    471     if (!parentLayer)
    472         return;
    473 
    474     if (hasLayer()) {
    475         parentLayer->removeChild(toRenderLayerModelObject(this)->layer());
    476         return;
    477     }
    478 
    479     for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling())
    480         curr->removeLayers(parentLayer);
    481 }
    482 
    483 void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
    484 {
    485     if (!newParent)
    486         return;
    487 
    488     if (hasLayer()) {
    489         RenderLayer* layer = toRenderLayerModelObject(this)->layer();
    490         ASSERT(oldParent == layer->parent());
    491         if (oldParent)
    492             oldParent->removeChild(layer);
    493         newParent->addChild(layer);
    494         return;
    495     }
    496 
    497     for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling())
    498         curr->moveLayers(oldParent, newParent);
    499 }
    500 
    501 RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint,
    502                                          bool checkParent)
    503 {
    504     // Error check the parent layer passed in. If it's null, we can't find anything.
    505     if (!parentLayer)
    506         return 0;
    507 
    508     // Step 1: If our layer is a child of the desired parent, then return our layer.
    509     RenderLayer* ourLayer = hasLayer() ? toRenderLayerModelObject(this)->layer() : 0;
    510     if (ourLayer && ourLayer->parent() == parentLayer)
    511         return ourLayer;
    512 
    513     // Step 2: If we don't have a layer, or our layer is the desired parent, then descend
    514     // into our siblings trying to find the next layer whose parent is the desired parent.
    515     if (!ourLayer || ourLayer == parentLayer) {
    516         for (RenderObject* curr = startPoint ? startPoint->nextSibling() : slowFirstChild();
    517              curr; curr = curr->nextSibling()) {
    518             RenderLayer* nextLayer = curr->findNextLayer(parentLayer, 0, false);
    519             if (nextLayer)
    520                 return nextLayer;
    521         }
    522     }
    523 
    524     // Step 3: If our layer is the desired parent layer, then we're finished. We didn't
    525     // find anything.
    526     if (parentLayer == ourLayer)
    527         return 0;
    528 
    529     // Step 4: If |checkParent| is set, climb up to our parent and check its siblings that
    530     // follow us to see if we can locate a layer.
    531     if (checkParent && parent())
    532         return parent()->findNextLayer(parentLayer, this, true);
    533 
    534     return 0;
    535 }
    536 
    537 RenderLayer* RenderObject::enclosingLayer() const
    538 {
    539     for (const RenderObject* current = this; current; current = current->parent()) {
    540         if (current->hasLayer())
    541             return toRenderLayerModelObject(current)->layer();
    542     }
    543     // FIXME: We should remove the one caller that triggers this case and make
    544     // this function return a reference.
    545     ASSERT(!m_parent && !isRenderView());
    546     return 0;
    547 }
    548 
    549 bool RenderObject::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
    550 {
    551     RenderBox* enclosingBox = this->enclosingBox();
    552     if (!enclosingBox)
    553         return false;
    554 
    555     enclosingBox->scrollRectToVisible(rect, alignX, alignY);
    556     return true;
    557 }
    558 
    559 RenderBox* RenderObject::enclosingBox() const
    560 {
    561     RenderObject* curr = const_cast<RenderObject*>(this);
    562     while (curr) {
    563         if (curr->isBox())
    564             return toRenderBox(curr);
    565         curr = curr->parent();
    566     }
    567 
    568     ASSERT_NOT_REACHED();
    569     return 0;
    570 }
    571 
    572 RenderBoxModelObject* RenderObject::enclosingBoxModelObject() const
    573 {
    574     RenderObject* curr = const_cast<RenderObject*>(this);
    575     while (curr) {
    576         if (curr->isBoxModelObject())
    577             return toRenderBoxModelObject(curr);
    578         curr = curr->parent();
    579     }
    580 
    581     ASSERT_NOT_REACHED();
    582     return 0;
    583 }
    584 
    585 RenderBox* RenderObject::enclosingScrollableBox() const
    586 {
    587     for (RenderObject* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
    588         if (!ancestor->isBox())
    589             continue;
    590 
    591         RenderBox* ancestorBox = toRenderBox(ancestor);
    592         if (ancestorBox->canBeScrolledAndHasScrollableArea())
    593             return ancestorBox;
    594     }
    595 
    596     return 0;
    597 }
    598 
    599 RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const
    600 {
    601     ASSERT(flowThreadState() != NotInsideFlowThread);
    602 
    603     // See if we have the thread cached because we're in the middle of layout.
    604     RenderFlowThread* flowThread = view()->flowThreadController()->currentRenderFlowThread();
    605     if (flowThread)
    606         return flowThread;
    607 
    608     // Not in the middle of layout so have to find the thread the slow way.
    609     RenderObject* curr = const_cast<RenderObject*>(this);
    610     while (curr) {
    611         if (curr->isRenderFlowThread())
    612             return toRenderFlowThread(curr);
    613         curr = curr->containingBlock();
    614     }
    615     return 0;
    616 }
    617 
    618 RenderBlock* RenderObject::firstLineBlock() const
    619 {
    620     return 0;
    621 }
    622 
    623 static inline bool objectIsRelayoutBoundary(const RenderObject* object)
    624 {
    625     // FIXME: In future it may be possible to broaden these conditions in order to improve performance.
    626     if (object->isTextControl())
    627         return true;
    628 
    629     if (object->isSVGRoot())
    630         return true;
    631 
    632     if (!object->hasOverflowClip())
    633         return false;
    634 
    635     if (object->style()->width().isIntrinsicOrAuto() || object->style()->height().isIntrinsicOrAuto() || object->style()->height().isPercent())
    636         return false;
    637 
    638     // Table parts can't be relayout roots since the table is responsible for layouting all the parts.
    639     if (object->isTablePart())
    640         return false;
    641 
    642     return true;
    643 }
    644 
    645 void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, RenderObject* newRoot, SubtreeLayoutScope* layouter)
    646 {
    647     ASSERT(!scheduleRelayout || !newRoot);
    648     ASSERT(!isSetNeedsLayoutForbidden());
    649     ASSERT(!layouter || this != layouter->root());
    650 
    651     RenderObject* object = container();
    652     RenderObject* last = this;
    653 
    654     bool simplifiedNormalFlowLayout = needsSimplifiedNormalFlowLayout() && !selfNeedsLayout() && !normalChildNeedsLayout();
    655 
    656     while (object) {
    657         if (object->selfNeedsLayout())
    658             return;
    659 
    660         // Don't mark the outermost object of an unrooted subtree. That object will be
    661         // marked when the subtree is added to the document.
    662         RenderObject* container = object->container();
    663         if (!container && !object->isRenderView())
    664             return;
    665         if (!last->isText() && last->style()->hasOutOfFlowPosition()) {
    666             bool willSkipRelativelyPositionedInlines = !object->isRenderBlock() || object->isAnonymousBlock();
    667             // Skip relatively positioned inlines and anonymous blocks to get to the enclosing RenderBlock.
    668             while (object && (!object->isRenderBlock() || object->isAnonymousBlock()))
    669                 object = object->container();
    670             if (!object || object->posChildNeedsLayout())
    671                 return;
    672             if (willSkipRelativelyPositionedInlines)
    673                 container = object->container();
    674             object->setPosChildNeedsLayout(true);
    675             simplifiedNormalFlowLayout = true;
    676             ASSERT(!object->isSetNeedsLayoutForbidden());
    677         } else if (simplifiedNormalFlowLayout) {
    678             if (object->needsSimplifiedNormalFlowLayout())
    679                 return;
    680             object->setNeedsSimplifiedNormalFlowLayout(true);
    681             ASSERT(!object->isSetNeedsLayoutForbidden());
    682         } else {
    683             if (object->normalChildNeedsLayout())
    684                 return;
    685             object->setNormalChildNeedsLayout(true);
    686             ASSERT(!object->isSetNeedsLayoutForbidden());
    687         }
    688 
    689         if (layouter) {
    690             layouter->addRendererToLayout(object);
    691             if (object == layouter->root())
    692                 return;
    693         }
    694 
    695         if (object == newRoot)
    696             return;
    697 
    698         last = object;
    699         if (scheduleRelayout && objectIsRelayoutBoundary(last))
    700             break;
    701         object = container;
    702     }
    703 
    704     if (scheduleRelayout)
    705         last->scheduleRelayout();
    706 }
    707 
    708 #ifndef NDEBUG
    709 void RenderObject::checkBlockPositionedObjectsNeedLayout()
    710 {
    711     ASSERT(!needsLayout());
    712 
    713     if (isRenderBlock())
    714         toRenderBlock(this)->checkPositionedObjectsNeedLayout();
    715 }
    716 #endif
    717 
    718 void RenderObject::setPreferredLogicalWidthsDirty(MarkingBehavior markParents)
    719 {
    720     m_bitfields.setPreferredLogicalWidthsDirty(true);
    721     if (markParents == MarkContainingBlockChain && (isText() || !style()->hasOutOfFlowPosition()))
    722         invalidateContainerPreferredLogicalWidths();
    723 }
    724 
    725 void RenderObject::clearPreferredLogicalWidthsDirty()
    726 {
    727     m_bitfields.setPreferredLogicalWidthsDirty(false);
    728 }
    729 
    730 void RenderObject::invalidateContainerPreferredLogicalWidths()
    731 {
    732     // In order to avoid pathological behavior when inlines are deeply nested, we do include them
    733     // in the chain that we mark dirty (even though they're kind of irrelevant).
    734     RenderObject* o = isTableCell() ? containingBlock() : container();
    735     while (o && !o->preferredLogicalWidthsDirty()) {
    736         // Don't invalidate the outermost object of an unrooted subtree. That object will be
    737         // invalidated when the subtree is added to the document.
    738         RenderObject* container = o->isTableCell() ? o->containingBlock() : o->container();
    739         if (!container && !o->isRenderView())
    740             break;
    741 
    742         o->m_bitfields.setPreferredLogicalWidthsDirty(true);
    743         if (o->style()->hasOutOfFlowPosition())
    744             // A positioned object has no effect on the min/max width of its containing block ever.
    745             // We can optimize this case and not go up any further.
    746             break;
    747         o = container;
    748     }
    749 }
    750 
    751 void RenderObject::setLayerNeedsFullPaintInvalidationForPositionedMovementLayout()
    752 {
    753     ASSERT(hasLayer());
    754     toRenderLayerModelObject(this)->layer()->repainter().setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout);
    755 }
    756 
    757 RenderBlock* RenderObject::containerForFixedPosition(const RenderLayerModelObject* paintInvalidationContainer, bool* paintInvalidationContainerSkipped) const
    758 {
    759     ASSERT(!paintInvalidationContainerSkipped || !*paintInvalidationContainerSkipped);
    760     ASSERT(!isText());
    761     ASSERT(style()->position() == FixedPosition);
    762 
    763     RenderObject* ancestor = parent();
    764     for (; ancestor && !ancestor->canContainFixedPositionObjects(); ancestor = ancestor->parent()) {
    765         if (paintInvalidationContainerSkipped && ancestor == paintInvalidationContainer)
    766             *paintInvalidationContainerSkipped = true;
    767     }
    768 
    769     ASSERT(!ancestor || !ancestor->isAnonymousBlock());
    770     return toRenderBlock(ancestor);
    771 }
    772 
    773 RenderBlock* RenderObject::containingBlock() const
    774 {
    775     RenderObject* o = parent();
    776     if (!o && isRenderScrollbarPart())
    777         o = toRenderScrollbarPart(this)->rendererOwningScrollbar();
    778     if (!isText() && m_style->position() == FixedPosition) {
    779         return containerForFixedPosition();
    780     } else if (!isText() && m_style->position() == AbsolutePosition) {
    781         while (o) {
    782             // For relpositioned inlines, we return the nearest non-anonymous enclosing block. We don't try
    783             // to return the inline itself.  This allows us to avoid having a positioned objects
    784             // list in all RenderInlines and lets us return a strongly-typed RenderBlock* result
    785             // from this method.  The container() method can actually be used to obtain the
    786             // inline directly.
    787             if (o->style()->position() != StaticPosition && (!o->isInline() || o->isReplaced()))
    788                 break;
    789 
    790             if (o->canContainFixedPositionObjects())
    791                 break;
    792 
    793             if (o->style()->hasInFlowPosition() && o->isInline() && !o->isReplaced()) {
    794                 o = o->containingBlock();
    795                 break;
    796             }
    797 
    798             o = o->parent();
    799         }
    800 
    801         if (o && !o->isRenderBlock())
    802             o = o->containingBlock();
    803 
    804         while (o && o->isAnonymousBlock())
    805             o = o->containingBlock();
    806     } else {
    807         while (o && ((o->isInline() && !o->isReplaced()) || !o->isRenderBlock()))
    808             o = o->parent();
    809     }
    810 
    811     if (!o || !o->isRenderBlock())
    812         return 0; // This can still happen in case of an orphaned tree
    813 
    814     return toRenderBlock(o);
    815 }
    816 
    817 RenderObject* RenderObject::clippingContainer() const
    818 {
    819     RenderObject* container = const_cast<RenderObject*>(this);
    820     while (container) {
    821         if (container->style()->position() == FixedPosition) {
    822             for (container = container->parent(); container && !container->canContainFixedPositionObjects(); container = container->parent()) {
    823                 // CSS clip applies to fixed position elements even for ancestors that are not what the
    824                 // fixed element is positioned with respect to.
    825                 if (container->hasClip())
    826                     return container;
    827             }
    828         } else {
    829             container = container->containingBlock();
    830         }
    831 
    832         if (!container)
    833             return 0;
    834         if (container->hasClipOrOverflowClip())
    835             return container;
    836     }
    837     return 0;
    838 }
    839 
    840 bool RenderObject::canRenderBorderImage() const
    841 {
    842     ASSERT(style()->hasBorder());
    843 
    844     StyleImage* borderImage = style()->borderImage().image();
    845     return borderImage && borderImage->canRender(*this, style()->effectiveZoom()) && borderImage->isLoaded();
    846 }
    847 
    848 bool RenderObject::mustInvalidateFillLayersPaintOnWidthChange(const FillLayer& layer) const
    849 {
    850     // Nobody will use multiple layers without wanting fancy positioning.
    851     if (layer.next())
    852         return true;
    853 
    854     // Make sure we have a valid image.
    855     StyleImage* img = layer.image();
    856     if (!img || !img->canRender(*this, style()->effectiveZoom()))
    857         return false;
    858 
    859     if (layer.repeatX() != RepeatFill && layer.repeatX() != NoRepeatFill)
    860         return true;
    861 
    862     if (layer.xPosition().isPercent() && !layer.xPosition().isZero())
    863         return true;
    864 
    865     if (layer.backgroundXOrigin() != LeftEdge)
    866         return true;
    867 
    868     EFillSizeType sizeType = layer.sizeType();
    869 
    870     if (sizeType == Contain || sizeType == Cover)
    871         return true;
    872 
    873     if (sizeType == SizeLength) {
    874         if (layer.sizeLength().width().isPercent() && !layer.sizeLength().width().isZero())
    875             return true;
    876         if (img->isGeneratedImage() && layer.sizeLength().width().isAuto())
    877             return true;
    878     } else if (img->usesImageContainerSize()) {
    879         return true;
    880     }
    881 
    882     return false;
    883 }
    884 
    885 bool RenderObject::mustInvalidateFillLayersPaintOnHeightChange(const FillLayer& layer) const
    886 {
    887     // Nobody will use multiple layers without wanting fancy positioning.
    888     if (layer.next())
    889         return true;
    890 
    891     // Make sure we have a valid image.
    892     StyleImage* img = layer.image();
    893     if (!img || !img->canRender(*this, style()->effectiveZoom()))
    894         return false;
    895 
    896     if (layer.repeatY() != RepeatFill && layer.repeatY() != NoRepeatFill)
    897         return true;
    898 
    899     if (layer.yPosition().isPercent() && !layer.yPosition().isZero())
    900         return true;
    901 
    902     if (layer.backgroundYOrigin() != TopEdge)
    903         return true;
    904 
    905     EFillSizeType sizeType = layer.sizeType();
    906 
    907     if (sizeType == Contain || sizeType == Cover)
    908         return true;
    909 
    910     if (sizeType == SizeLength) {
    911         if (layer.sizeLength().height().isPercent() && !layer.sizeLength().height().isZero())
    912             return true;
    913         if (img->isGeneratedImage() && layer.sizeLength().height().isAuto())
    914             return true;
    915     } else if (img->usesImageContainerSize()) {
    916         return true;
    917     }
    918 
    919     return false;
    920 }
    921 
    922 bool RenderObject::mustInvalidateBackgroundOrBorderPaintOnWidthChange() const
    923 {
    924     if (hasMask() && mustInvalidateFillLayersPaintOnWidthChange(*style()->maskLayers()))
    925         return true;
    926 
    927     // If we don't have a background/border/mask, then nothing to do.
    928     if (!hasBoxDecorations())
    929         return false;
    930 
    931     if (mustInvalidateFillLayersPaintOnWidthChange(*style()->backgroundLayers()))
    932         return true;
    933 
    934     // Our fill layers are ok. Let's check border.
    935     if (style()->hasBorder() && canRenderBorderImage())
    936         return true;
    937 
    938     return false;
    939 }
    940 
    941 bool RenderObject::mustInvalidateBackgroundOrBorderPaintOnHeightChange() const
    942 {
    943     if (hasMask() && mustInvalidateFillLayersPaintOnHeightChange(*style()->maskLayers()))
    944         return true;
    945 
    946     // If we don't have a background/border/mask, then nothing to do.
    947     if (!hasBoxDecorations())
    948         return false;
    949 
    950     if (mustInvalidateFillLayersPaintOnHeightChange(*style()->backgroundLayers()))
    951         return true;
    952 
    953     // Our fill layers are ok.  Let's check border.
    954     if (style()->hasBorder() && canRenderBorderImage())
    955         return true;
    956 
    957     return false;
    958 }
    959 
    960 void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
    961                                       BoxSide side, Color color, EBorderStyle style,
    962                                       int adjacentWidth1, int adjacentWidth2, bool antialias)
    963 {
    964     int thickness;
    965     int length;
    966     if (side == BSTop || side == BSBottom) {
    967         thickness = y2 - y1;
    968         length = x2 - x1;
    969     } else {
    970         thickness = x2 - x1;
    971         length = y2 - y1;
    972     }
    973 
    974     // FIXME: We really would like this check to be an ASSERT as we don't want to draw empty borders. However
    975     // nothing guarantees that the following recursive calls to drawLineForBoxSide will have non-null dimensions.
    976     if (!thickness || !length)
    977         return;
    978 
    979     if (style == DOUBLE && thickness < 3)
    980         style = SOLID;
    981 
    982     switch (style) {
    983     case BNONE:
    984     case BHIDDEN:
    985         return;
    986     case DOTTED:
    987     case DASHED:
    988         drawDashedOrDottedBoxSide(graphicsContext, x1, y1, x2, y2, side,
    989             color, thickness, style, antialias);
    990         break;
    991     case DOUBLE:
    992         drawDoubleBoxSide(graphicsContext, x1, y1, x2, y2, length, side, color,
    993             thickness, adjacentWidth1, adjacentWidth2, antialias);
    994         break;
    995     case RIDGE:
    996     case GROOVE:
    997         drawRidgeOrGrooveBoxSide(graphicsContext, x1, y1, x2, y2, side, color,
    998             style, adjacentWidth1, adjacentWidth2, antialias);
    999         break;
   1000     case INSET:
   1001         // FIXME: Maybe we should lighten the colors on one side like Firefox.
   1002         // https://bugs.webkit.org/show_bug.cgi?id=58608
   1003         if (side == BSTop || side == BSLeft)
   1004             color = color.dark();
   1005         // fall through
   1006     case OUTSET:
   1007         if (style == OUTSET && (side == BSBottom || side == BSRight))
   1008             color = color.dark();
   1009         // fall through
   1010     case SOLID:
   1011         drawSolidBoxSide(graphicsContext, x1, y1, x2, y2, side, color, adjacentWidth1, adjacentWidth2, antialias);
   1012         break;
   1013     }
   1014 }
   1015 
   1016 void RenderObject::drawDashedOrDottedBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
   1017     BoxSide side, Color color, int thickness, EBorderStyle style, bool antialias)
   1018 {
   1019     if (thickness <= 0)
   1020         return;
   1021 
   1022     bool wasAntialiased = graphicsContext->shouldAntialias();
   1023     StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
   1024     graphicsContext->setShouldAntialias(antialias);
   1025     graphicsContext->setStrokeColor(color);
   1026     graphicsContext->setStrokeThickness(thickness);
   1027     graphicsContext->setStrokeStyle(style == DASHED ? DashedStroke : DottedStroke);
   1028 
   1029     switch (side) {
   1030     case BSBottom:
   1031     case BSTop:
   1032         graphicsContext->drawLine(IntPoint(x1, (y1 + y2) / 2), IntPoint(x2, (y1 + y2) / 2));
   1033         break;
   1034     case BSRight:
   1035     case BSLeft:
   1036         graphicsContext->drawLine(IntPoint((x1 + x2) / 2, y1), IntPoint((x1 + x2) / 2, y2));
   1037         break;
   1038     }
   1039     graphicsContext->setShouldAntialias(wasAntialiased);
   1040     graphicsContext->setStrokeStyle(oldStrokeStyle);
   1041 }
   1042 
   1043 void RenderObject::drawDoubleBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
   1044     int length, BoxSide side, Color color, int thickness, int adjacentWidth1, int adjacentWidth2, bool antialias)
   1045 {
   1046     int thirdOfThickness = (thickness + 1) / 3;
   1047     ASSERT(thirdOfThickness);
   1048 
   1049     if (!adjacentWidth1 && !adjacentWidth2) {
   1050         StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
   1051         graphicsContext->setStrokeStyle(NoStroke);
   1052         graphicsContext->setFillColor(color);
   1053 
   1054         bool wasAntialiased = graphicsContext->shouldAntialias();
   1055         graphicsContext->setShouldAntialias(antialias);
   1056 
   1057         switch (side) {
   1058         case BSTop:
   1059         case BSBottom:
   1060             graphicsContext->drawRect(IntRect(x1, y1, length, thirdOfThickness));
   1061             graphicsContext->drawRect(IntRect(x1, y2 - thirdOfThickness, length, thirdOfThickness));
   1062             break;
   1063         case BSLeft:
   1064         case BSRight:
   1065             // FIXME: Why do we offset the border by 1 in this case but not the other one?
   1066             if (length > 1) {
   1067                 graphicsContext->drawRect(IntRect(x1, y1 + 1, thirdOfThickness, length - 1));
   1068                 graphicsContext->drawRect(IntRect(x2 - thirdOfThickness, y1 + 1, thirdOfThickness, length - 1));
   1069             }
   1070             break;
   1071         }
   1072 
   1073         graphicsContext->setShouldAntialias(wasAntialiased);
   1074         graphicsContext->setStrokeStyle(oldStrokeStyle);
   1075         return;
   1076     }
   1077 
   1078     int adjacent1BigThird = ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 3;
   1079     int adjacent2BigThird = ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 3;
   1080 
   1081     switch (side) {
   1082     case BSTop:
   1083         drawLineForBoxSide(graphicsContext, x1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
   1084             y1, x2 - max((-adjacentWidth2 * 2 + 1) / 3, 0), y1 + thirdOfThickness,
   1085             side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
   1086         drawLineForBoxSide(graphicsContext, x1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
   1087             y2 - thirdOfThickness, x2 - max((adjacentWidth2 * 2 + 1) / 3, 0), y2,
   1088             side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
   1089         break;
   1090     case BSLeft:
   1091         drawLineForBoxSide(graphicsContext, x1, y1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
   1092             x1 + thirdOfThickness, y2 - max((-adjacentWidth2 * 2 + 1) / 3, 0),
   1093             side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
   1094         drawLineForBoxSide(graphicsContext, x2 - thirdOfThickness, y1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
   1095             x2, y2 - max((adjacentWidth2 * 2 + 1) / 3, 0),
   1096             side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
   1097         break;
   1098     case BSBottom:
   1099         drawLineForBoxSide(graphicsContext, x1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
   1100             y1, x2 - max((adjacentWidth2 * 2 + 1) / 3, 0), y1 + thirdOfThickness,
   1101             side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
   1102         drawLineForBoxSide(graphicsContext, x1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
   1103             y2 - thirdOfThickness, x2 - max((-adjacentWidth2 * 2 + 1) / 3, 0), y2,
   1104             side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
   1105         break;
   1106     case BSRight:
   1107         drawLineForBoxSide(graphicsContext, x1, y1 + max((adjacentWidth1 * 2 + 1) / 3, 0),
   1108             x1 + thirdOfThickness, y2 - max((adjacentWidth2 * 2 + 1) / 3, 0),
   1109             side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
   1110         drawLineForBoxSide(graphicsContext, x2 - thirdOfThickness, y1 + max((-adjacentWidth1 * 2 + 1) / 3, 0),
   1111             x2, y2 - max((-adjacentWidth2 * 2 + 1) / 3, 0),
   1112             side, color, SOLID, adjacent1BigThird, adjacent2BigThird, antialias);
   1113         break;
   1114     default:
   1115         break;
   1116     }
   1117 }
   1118 
   1119 void RenderObject::drawRidgeOrGrooveBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
   1120     BoxSide side, Color color, EBorderStyle style, int adjacentWidth1, int adjacentWidth2, bool antialias)
   1121 {
   1122     EBorderStyle s1;
   1123     EBorderStyle s2;
   1124     if (style == GROOVE) {
   1125         s1 = INSET;
   1126         s2 = OUTSET;
   1127     } else {
   1128         s1 = OUTSET;
   1129         s2 = INSET;
   1130     }
   1131 
   1132     int adjacent1BigHalf = ((adjacentWidth1 > 0) ? adjacentWidth1 + 1 : adjacentWidth1 - 1) / 2;
   1133     int adjacent2BigHalf = ((adjacentWidth2 > 0) ? adjacentWidth2 + 1 : adjacentWidth2 - 1) / 2;
   1134 
   1135     switch (side) {
   1136     case BSTop:
   1137         drawLineForBoxSide(graphicsContext, x1 + max(-adjacentWidth1, 0) / 2, y1, x2 - max(-adjacentWidth2, 0) / 2, (y1 + y2 + 1) / 2,
   1138             side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
   1139         drawLineForBoxSide(graphicsContext, x1 + max(adjacentWidth1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(adjacentWidth2 + 1, 0) / 2, y2,
   1140             side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
   1141         break;
   1142     case BSLeft:
   1143         drawLineForBoxSide(graphicsContext, x1, y1 + max(-adjacentWidth1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(-adjacentWidth2, 0) / 2,
   1144             side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
   1145         drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(adjacentWidth1 + 1, 0) / 2, x2, y2 - max(adjacentWidth2 + 1, 0) / 2,
   1146             side, color, s2, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
   1147         break;
   1148     case BSBottom:
   1149         drawLineForBoxSide(graphicsContext, x1 + max(adjacentWidth1, 0) / 2, y1, x2 - max(adjacentWidth2, 0) / 2, (y1 + y2 + 1) / 2,
   1150             side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
   1151         drawLineForBoxSide(graphicsContext, x1 + max(-adjacentWidth1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(-adjacentWidth2 + 1, 0) / 2, y2,
   1152             side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
   1153         break;
   1154     case BSRight:
   1155         drawLineForBoxSide(graphicsContext, x1, y1 + max(adjacentWidth1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(adjacentWidth2, 0) / 2,
   1156             side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
   1157         drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(-adjacentWidth1 + 1, 0) / 2, x2, y2 - max(-adjacentWidth2 + 1, 0) / 2,
   1158             side, color, s1, adjacentWidth1 / 2, adjacentWidth2 / 2, antialias);
   1159         break;
   1160     }
   1161 }
   1162 
   1163 void RenderObject::drawSolidBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
   1164     BoxSide side, Color color, int adjacentWidth1, int adjacentWidth2, bool antialias)
   1165 {
   1166     StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
   1167     graphicsContext->setStrokeStyle(NoStroke);
   1168     graphicsContext->setFillColor(color);
   1169     ASSERT(x2 >= x1);
   1170     ASSERT(y2 >= y1);
   1171     if (!adjacentWidth1 && !adjacentWidth2) {
   1172         // Turn off antialiasing to match the behavior of drawConvexPolygon();
   1173         // this matters for rects in transformed contexts.
   1174         bool wasAntialiased = graphicsContext->shouldAntialias();
   1175         graphicsContext->setShouldAntialias(antialias);
   1176         graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, y2 - y1));
   1177         graphicsContext->setShouldAntialias(wasAntialiased);
   1178         graphicsContext->setStrokeStyle(oldStrokeStyle);
   1179         return;
   1180     }
   1181     FloatPoint quad[4];
   1182     switch (side) {
   1183     case BSTop:
   1184         quad[0] = FloatPoint(x1 + max(-adjacentWidth1, 0), y1);
   1185         quad[1] = FloatPoint(x1 + max(adjacentWidth1, 0), y2);
   1186         quad[2] = FloatPoint(x2 - max(adjacentWidth2, 0), y2);
   1187         quad[3] = FloatPoint(x2 - max(-adjacentWidth2, 0), y1);
   1188         break;
   1189     case BSBottom:
   1190         quad[0] = FloatPoint(x1 + max(adjacentWidth1, 0), y1);
   1191         quad[1] = FloatPoint(x1 + max(-adjacentWidth1, 0), y2);
   1192         quad[2] = FloatPoint(x2 - max(-adjacentWidth2, 0), y2);
   1193         quad[3] = FloatPoint(x2 - max(adjacentWidth2, 0), y1);
   1194         break;
   1195     case BSLeft:
   1196         quad[0] = FloatPoint(x1, y1 + max(-adjacentWidth1, 0));
   1197         quad[1] = FloatPoint(x1, y2 - max(-adjacentWidth2, 0));
   1198         quad[2] = FloatPoint(x2, y2 - max(adjacentWidth2, 0));
   1199         quad[3] = FloatPoint(x2, y1 + max(adjacentWidth1, 0));
   1200         break;
   1201     case BSRight:
   1202         quad[0] = FloatPoint(x1, y1 + max(adjacentWidth1, 0));
   1203         quad[1] = FloatPoint(x1, y2 - max(adjacentWidth2, 0));
   1204         quad[2] = FloatPoint(x2, y2 - max(-adjacentWidth2, 0));
   1205         quad[3] = FloatPoint(x2, y1 + max(-adjacentWidth1, 0));
   1206         break;
   1207     }
   1208 
   1209     graphicsContext->drawConvexPolygon(4, quad, antialias);
   1210     graphicsContext->setStrokeStyle(oldStrokeStyle);
   1211 }
   1212 
   1213 void RenderObject::paintFocusRing(PaintInfo& paintInfo, const LayoutPoint& paintOffset, RenderStyle* style)
   1214 {
   1215     Vector<IntRect> focusRingRects;
   1216     addFocusRingRects(focusRingRects, paintOffset, paintInfo.paintContainer());
   1217     if (style->outlineStyleIsAuto())
   1218         paintInfo.context->drawFocusRing(focusRingRects, style->outlineWidth(), style->outlineOffset(), resolveColor(style, CSSPropertyOutlineColor));
   1219     else
   1220         addPDFURLRect(paintInfo.context, unionRect(focusRingRects));
   1221 }
   1222 
   1223 void RenderObject::addPDFURLRect(GraphicsContext* context, const LayoutRect& rect)
   1224 {
   1225     if (rect.isEmpty())
   1226         return;
   1227     Node* n = node();
   1228     if (!n || !n->isLink() || !n->isElementNode())
   1229         return;
   1230     const AtomicString& href = toElement(n)->getAttribute(hrefAttr);
   1231     if (href.isNull())
   1232         return;
   1233     KURL url = n->document().completeURL(href);
   1234     if (!url.isValid())
   1235         return;
   1236     if (context->supportsURLFragments() && url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(url, n->document().baseURL())) {
   1237         String name = url.fragmentIdentifier();
   1238         if (document().findAnchor(name))
   1239             context->setURLFragmentForRect(name, pixelSnappedIntRect(rect));
   1240         return;
   1241     }
   1242     context->setURLForRect(url, pixelSnappedIntRect(rect));
   1243 }
   1244 
   1245 void RenderObject::paintOutline(PaintInfo& paintInfo, const LayoutRect& paintRect)
   1246 {
   1247     if (!hasOutline())
   1248         return;
   1249 
   1250     RenderStyle* styleToUse = style();
   1251     LayoutUnit outlineWidth = styleToUse->outlineWidth();
   1252 
   1253     int outlineOffset = styleToUse->outlineOffset();
   1254 
   1255     if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
   1256         if (RenderTheme::theme().shouldDrawDefaultFocusRing(this)) {
   1257             // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
   1258             paintFocusRing(paintInfo, paintRect.location(), styleToUse);
   1259         }
   1260     }
   1261 
   1262     if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE)
   1263         return;
   1264 
   1265     IntRect inner = pixelSnappedIntRect(paintRect);
   1266     inner.inflate(outlineOffset);
   1267 
   1268     IntRect outer = pixelSnappedIntRect(inner);
   1269     outer.inflate(outlineWidth);
   1270 
   1271     // FIXME: This prevents outlines from painting inside the object. See bug 12042
   1272     if (outer.isEmpty())
   1273         return;
   1274 
   1275     EBorderStyle outlineStyle = styleToUse->outlineStyle();
   1276     Color outlineColor = resolveColor(styleToUse, CSSPropertyOutlineColor);
   1277 
   1278     GraphicsContext* graphicsContext = paintInfo.context;
   1279     bool useTransparencyLayer = outlineColor.hasAlpha();
   1280     if (useTransparencyLayer) {
   1281         if (outlineStyle == SOLID) {
   1282             Path path;
   1283             path.addRect(outer);
   1284             path.addRect(inner);
   1285             graphicsContext->setFillRule(RULE_EVENODD);
   1286             graphicsContext->setFillColor(outlineColor);
   1287             graphicsContext->fillPath(path);
   1288             return;
   1289         }
   1290         graphicsContext->beginTransparencyLayer(static_cast<float>(outlineColor.alpha()) / 255);
   1291         outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue());
   1292     }
   1293 
   1294     int leftOuter = outer.x();
   1295     int leftInner = inner.x();
   1296     int rightOuter = outer.maxX();
   1297     int rightInner = inner.maxX();
   1298     int topOuter = outer.y();
   1299     int topInner = inner.y();
   1300     int bottomOuter = outer.maxY();
   1301     int bottomInner = inner.maxY();
   1302 
   1303     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, leftInner, bottomOuter, BSLeft, outlineColor, outlineStyle, outlineWidth, outlineWidth);
   1304     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, rightOuter, topInner, BSTop, outlineColor, outlineStyle, outlineWidth, outlineWidth);
   1305     drawLineForBoxSide(graphicsContext, rightInner, topOuter, rightOuter, bottomOuter, BSRight, outlineColor, outlineStyle, outlineWidth, outlineWidth);
   1306     drawLineForBoxSide(graphicsContext, leftOuter, bottomInner, rightOuter, bottomOuter, BSBottom, outlineColor, outlineStyle, outlineWidth, outlineWidth);
   1307 
   1308     if (useTransparencyLayer)
   1309         graphicsContext->endLayer();
   1310 }
   1311 
   1312 void RenderObject::addChildFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
   1313 {
   1314     for (RenderObject* current = slowFirstChild(); current; current = current->nextSibling()) {
   1315         if (current->isText() || current->isListMarker())
   1316             continue;
   1317 
   1318         if (current->isBox()) {
   1319             RenderBox* box = toRenderBox(current);
   1320             if (box->hasLayer()) {
   1321                 Vector<IntRect> layerFocusRingRects;
   1322                 box->addFocusRingRects(layerFocusRingRects, LayoutPoint(), box);
   1323                 for (size_t i = 0; i < layerFocusRingRects.size(); ++i) {
   1324                     FloatQuad quadInBox = box->localToContainerQuad(FloatRect(layerFocusRingRects[i]), paintContainer);
   1325                     rects.append(pixelSnappedIntRect(LayoutRect(quadInBox.boundingBox())));
   1326                 }
   1327             } else {
   1328                 FloatPoint pos(additionalOffset);
   1329                 pos.move(box->locationOffset()); // FIXME: Snap offsets? crbug.com/350474
   1330                 box->addFocusRingRects(rects, flooredIntPoint(pos), paintContainer);
   1331             }
   1332         } else {
   1333             current->addFocusRingRects(rects, additionalOffset, paintContainer);
   1334         }
   1335     }
   1336 }
   1337 
   1338 // FIXME: In repaint-after-layout, we should be able to change the logic to remove the need for this function. See crbug.com/368416.
   1339 LayoutPoint RenderObject::positionFromPaintInvalidationContainer(const RenderLayerModelObject* paintInvalidationContainer) const
   1340 {
   1341     // FIXME: This assert should be re-enabled when we move paint invalidation to after compositing update. crbug.com/360286
   1342     // ASSERT(containerForPaintInvalidation() == paintInvalidationContainer);
   1343 
   1344     LayoutPoint offset = isBox() ? toRenderBox(this)->location() : LayoutPoint();
   1345     if (paintInvalidationContainer == this)
   1346         return offset;
   1347 
   1348     return roundedIntPoint(localToContainerPoint(offset, paintInvalidationContainer));
   1349 }
   1350 
   1351 IntRect RenderObject::absoluteBoundingBoxRect() const
   1352 {
   1353     Vector<FloatQuad> quads;
   1354     absoluteQuads(quads);
   1355 
   1356     size_t n = quads.size();
   1357     if (!n)
   1358         return IntRect();
   1359 
   1360     IntRect result = quads[0].enclosingBoundingBox();
   1361     for (size_t i = 1; i < n; ++i)
   1362         result.unite(quads[i].enclosingBoundingBox());
   1363     return result;
   1364 }
   1365 
   1366 IntRect RenderObject::absoluteBoundingBoxRectIgnoringTransforms() const
   1367 {
   1368     FloatPoint absPos = localToAbsolute();
   1369     Vector<IntRect> rects;
   1370     absoluteRects(rects, flooredLayoutPoint(absPos));
   1371 
   1372     size_t n = rects.size();
   1373     if (!n)
   1374         return IntRect();
   1375 
   1376     LayoutRect result = rects[0];
   1377     for (size_t i = 1; i < n; ++i)
   1378         result.unite(rects[i]);
   1379     return pixelSnappedIntRect(result);
   1380 }
   1381 
   1382 void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
   1383 {
   1384     Vector<IntRect> rects;
   1385     const RenderLayerModelObject* container = containerForPaintInvalidation();
   1386     addFocusRingRects(rects, LayoutPoint(localToContainerPoint(FloatPoint(), container)), container);
   1387     size_t count = rects.size();
   1388     for (size_t i = 0; i < count; ++i)
   1389         quads.append(container->localToAbsoluteQuad(FloatQuad(rects[i])));
   1390 }
   1391 
   1392 FloatRect RenderObject::absoluteBoundingBoxRectForRange(const Range* range)
   1393 {
   1394     if (!range || !range->startContainer())
   1395         return FloatRect();
   1396 
   1397     range->ownerDocument().updateLayout();
   1398 
   1399     Vector<FloatQuad> quads;
   1400     range->textQuads(quads);
   1401 
   1402     FloatRect result;
   1403     for (size_t i = 0; i < quads.size(); ++i)
   1404         result.unite(quads[i].boundingBox());
   1405 
   1406     return result;
   1407 }
   1408 
   1409 void RenderObject::addAbsoluteRectForLayer(LayoutRect& result)
   1410 {
   1411     if (hasLayer())
   1412         result.unite(absoluteBoundingBoxRect());
   1413     for (RenderObject* current = slowFirstChild(); current; current = current->nextSibling())
   1414         current->addAbsoluteRectForLayer(result);
   1415 }
   1416 
   1417 LayoutRect RenderObject::paintingRootRect(LayoutRect& topLevelRect)
   1418 {
   1419     LayoutRect result = absoluteBoundingBoxRect();
   1420     topLevelRect = result;
   1421     for (RenderObject* current = slowFirstChild(); current; current = current->nextSibling())
   1422         current->addAbsoluteRectForLayer(result);
   1423     return result;
   1424 }
   1425 
   1426 void RenderObject::paint(PaintInfo&, const LayoutPoint&)
   1427 {
   1428 }
   1429 
   1430 const RenderLayerModelObject* RenderObject::containerForPaintInvalidation() const
   1431 {
   1432     if (!isRooted())
   1433         return 0;
   1434 
   1435     return adjustCompositedContainerForSpecialAncestors(enclosingCompositedContainer());
   1436 }
   1437 
   1438 const RenderLayerModelObject* RenderObject::enclosingCompositedContainer() const
   1439 {
   1440     RenderLayerModelObject* container = 0;
   1441     if (view()->usesCompositing()) {
   1442         // FIXME: CompositingState is not necessarily up to date for many callers of this function.
   1443         DisableCompositingQueryAsserts disabler;
   1444 
   1445         if (RenderLayer* compositingLayer = enclosingLayer()->enclosingCompositingLayerForRepaint())
   1446             container = compositingLayer->renderer();
   1447     }
   1448     return container;
   1449 }
   1450 
   1451 const RenderLayerModelObject* RenderObject::adjustCompositedContainerForSpecialAncestors(const RenderLayerModelObject* paintInvalidationContainer) const
   1452 {
   1453 
   1454     if (document().view()->hasSoftwareFilters()) {
   1455         if (RenderLayer* enclosingFilterLayer = enclosingLayer()->enclosingFilterLayer())
   1456             return enclosingFilterLayer->renderer();
   1457     }
   1458 
   1459     // If we have a flow thread, then we need to do individual paint invalidations within the RenderRegions instead.
   1460     // Return the flow thread as a paint invalidation container in order to create a chokepoint that allows us to change
   1461     // paint invalidation to do individual region paint invalidations.
   1462     if (RenderFlowThread* parentRenderFlowThread = flowThreadContainingBlock()) {
   1463         // If we have already found a paint invalidation container then we will invalidate paints in that container only if it is part of the same
   1464         // flow thread. Otherwise we will need to catch the paint invalidation call and send it to the flow thread.
   1465         if (!paintInvalidationContainer || paintInvalidationContainer->flowThreadContainingBlock() != parentRenderFlowThread)
   1466             paintInvalidationContainer = parentRenderFlowThread;
   1467     }
   1468     return paintInvalidationContainer ? paintInvalidationContainer : view();
   1469 }
   1470 
   1471 bool RenderObject::isPaintInvalidationContainer() const
   1472 {
   1473     return hasLayer() && toRenderLayerModelObject(this)->layer()->isRepaintContainer();
   1474 }
   1475 
   1476 template<typename T> PassRefPtr<JSONValue> jsonObjectForRect(const T& rect)
   1477 {
   1478     RefPtr<JSONObject> object = JSONObject::create();
   1479     object->setNumber("x", rect.x());
   1480     object->setNumber("y", rect.y());
   1481     object->setNumber("width", rect.width());
   1482     object->setNumber("height", rect.height());
   1483     return object.release();
   1484 }
   1485 
   1486 static PassRefPtr<JSONValue> jsonObjectForPaintInvalidationInfo(const IntRect& rect, const String& invalidationReason)
   1487 {
   1488     RefPtr<JSONObject> object = JSONObject::create();
   1489     object->setValue("rect", jsonObjectForRect(rect));
   1490     object->setString("invalidation_reason", invalidationReason);
   1491     return object.release();
   1492 }
   1493 
   1494 LayoutRect RenderObject::computePaintInvalidationRect(const RenderLayerModelObject* paintInvalidationContainer) const
   1495 {
   1496     return clippedOverflowRectForPaintInvalidation(paintInvalidationContainer);
   1497 }
   1498 
   1499 void RenderObject::invalidatePaintUsingContainer(const RenderLayerModelObject* paintInvalidationContainer, const IntRect& r, InvalidationReason invalidationReason) const
   1500 {
   1501     if (r.isEmpty())
   1502         return;
   1503 
   1504     // FIXME: This should be an assert, but editing/selection can trigger this case to invalidate
   1505     // the selection. crbug.com/368140.
   1506     if (!isRooted())
   1507         return;
   1508 
   1509     TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "RenderObject::invalidatePaintUsingContainer()",
   1510         "object", this->debugName().ascii(),
   1511         "info", TracedValue::fromJSONValue(jsonObjectForPaintInvalidationInfo(r, invalidationReasonToString(invalidationReason))));
   1512 
   1513     // For querying RenderLayer::compositingState()
   1514     DisableCompositingQueryAsserts disabler;
   1515 
   1516     if (paintInvalidationContainer->isRenderFlowThread()) {
   1517         toRenderFlowThread(paintInvalidationContainer)->repaintRectangleInRegions(r);
   1518         return;
   1519     }
   1520 
   1521     if (paintInvalidationContainer->hasFilter() && paintInvalidationContainer->layer()->requiresFullLayerImageForFilters()) {
   1522         paintInvalidationContainer->layer()->repainter().setFilterBackendNeedsRepaintingInRect(r);
   1523         return;
   1524     }
   1525 
   1526     RenderView* v = view();
   1527     if (paintInvalidationContainer->isRenderView()) {
   1528         ASSERT(paintInvalidationContainer == v);
   1529         v->repaintViewRectangle(r);
   1530         return;
   1531     }
   1532 
   1533     if (v->usesCompositing()) {
   1534         ASSERT(paintInvalidationContainer->hasLayer() && (paintInvalidationContainer->layer()->compositingState() == PaintsIntoOwnBacking || paintInvalidationContainer->layer()->compositingState() == PaintsIntoGroupedBacking));
   1535         paintInvalidationContainer->layer()->repainter().setBackingNeedsRepaintInRect(r);
   1536     }
   1537 }
   1538 
   1539 void RenderObject::paintInvalidationForWholeRenderer() const
   1540 {
   1541     if (!isRooted())
   1542         return;
   1543 
   1544     if (view()->document().printing())
   1545         return; // Don't invalidate paints if we're printing.
   1546 
   1547     // FIXME: really, we're in the paint invalidation phase here, and the following queries are legal.
   1548     // Until those states are fully fledged, I'll just disable the ASSERTS.
   1549     DisableCompositingQueryAsserts disabler;
   1550     const RenderLayerModelObject* paintInvalidationContainer = containerForPaintInvalidation();
   1551     LayoutRect paintInvalidationRect = boundsRectForPaintInvalidation(paintInvalidationContainer);
   1552     invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(paintInvalidationRect), InvalidationPaint);
   1553 }
   1554 
   1555 LayoutRect RenderObject::boundsRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
   1556 {
   1557     if (!paintInvalidationContainer)
   1558         return computePaintInvalidationRect(paintInvalidationContainer);
   1559     return RenderLayer::computeRepaintRect(this, paintInvalidationContainer->layer());
   1560 }
   1561 
   1562 void RenderObject::invalidatePaintRectangle(const LayoutRect& r) const
   1563 {
   1564     if (!isRooted())
   1565         return;
   1566 
   1567     if (view()->document().printing())
   1568         return; // Don't invalidate paints if we're printing.
   1569 
   1570     LayoutRect dirtyRect(r);
   1571 
   1572     if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
   1573         // FIXME: layoutDelta needs to be applied in parts before/after transforms and
   1574         // paint invalidation containers. https://bugs.webkit.org/show_bug.cgi?id=23308
   1575         dirtyRect.move(view()->layoutDelta());
   1576     }
   1577 
   1578     const RenderLayerModelObject* paintInvalidationContainer = containerForPaintInvalidation();
   1579     RenderLayer::mapRectToRepaintBacking(this, paintInvalidationContainer, dirtyRect);
   1580     invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(dirtyRect), InvalidationPaintRectangle);
   1581 }
   1582 
   1583 IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
   1584 {
   1585     return pixelSnappedIntRect(absoluteClippedOverflowRect());
   1586 }
   1587 
   1588 const char* RenderObject::invalidationReasonToString(InvalidationReason reason) const
   1589 {
   1590     switch (reason) {
   1591     case InvalidationIncremental:
   1592         return "incremental";
   1593     case InvalidationSelfLayout:
   1594         return "self layout";
   1595     case InvalidationBorderFitLines:
   1596         return "border fit lines";
   1597     case InvalidationBorderRadius:
   1598         return "border radius";
   1599     case InvalidationBoundsChangeWithBackground:
   1600         return "bounds change with background";
   1601     case InvalidationBoundsChange:
   1602         return "bounds change";
   1603     case InvalidationLocationChange:
   1604         return "location change";
   1605     case InvalidationScroll:
   1606         return "scroll";
   1607     case InvalidationSelection:
   1608         return "selection";
   1609     case InvalidationLayer:
   1610         return "layer";
   1611     case InvalidationPaint:
   1612         return "invalidate paint";
   1613     case InvalidationPaintRectangle:
   1614         return "invalidate paint rectangle";
   1615     }
   1616     ASSERT_NOT_REACHED();
   1617     return "";
   1618 }
   1619 
   1620 void RenderObject::invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer)
   1621 {
   1622     // If we didn't need paint invalidation then our children don't need as well.
   1623     // Skip walking down the tree as everything should be fine below us.
   1624     if (!shouldCheckForPaintInvalidationAfterLayout())
   1625         return;
   1626 
   1627     clearPaintInvalidationState();
   1628 
   1629     for (RenderObject* child = slowFirstChild(); child; child = child->nextSibling()) {
   1630         if (!child->isOutOfFlowPositioned())
   1631             child->invalidateTreeAfterLayout(paintInvalidationContainer);
   1632     }
   1633 }
   1634 
   1635 static PassRefPtr<JSONValue> jsonObjectForOldAndNewRects(const LayoutRect& oldRect, const LayoutRect& newRect)
   1636 {
   1637     RefPtr<JSONObject> object = JSONObject::create();
   1638 
   1639     object->setValue("old", jsonObjectForRect(oldRect));
   1640     object->setValue("new", jsonObjectForRect(newRect));
   1641     return object.release();
   1642 }
   1643 
   1644 bool RenderObject::invalidatePaintAfterLayoutIfNeeded(const RenderLayerModelObject* paintInvalidationContainer, bool wasSelfLayout,
   1645     const LayoutRect& oldBounds, const LayoutPoint& oldLocation, const LayoutRect* newBoundsPtr, const LayoutPoint* newLocationPtr)
   1646 {
   1647     RenderView* v = view();
   1648     if (v->document().printing())
   1649         return false; // Don't invalidate paints if we're printing.
   1650 
   1651     // This ASSERT fails due to animations.  See https://bugs.webkit.org/show_bug.cgi?id=37048
   1652     // ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForPaintInvalidation(paintInvalidationContainer));
   1653     LayoutRect newBounds = newBoundsPtr ? *newBoundsPtr : computePaintInvalidationRect();
   1654     LayoutPoint newLocation = newLocationPtr ? (*newLocationPtr) : RenderLayer::positionFromPaintInvalidationContainer(this, paintInvalidationContainer);
   1655 
   1656     // FIXME: This should use a ConvertableToTraceFormat when they are available in Blink.
   1657     TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "RenderObject::invalidatePaintAfterLayoutIfNeeded()",
   1658         "object", this->debugName().ascii(),
   1659         "info", TracedValue::fromJSONValue(jsonObjectForOldAndNewRects(oldBounds, newBounds)));
   1660 
   1661     InvalidationReason invalidationReason = wasSelfLayout ? InvalidationSelfLayout : InvalidationIncremental;
   1662 
   1663     // Presumably a background or a border exists if border-fit:lines was specified.
   1664     if (invalidationReason == InvalidationIncremental && style()->borderFit() == BorderFitLines)
   1665         invalidationReason = InvalidationBorderFitLines;
   1666 
   1667     if (invalidationReason == InvalidationIncremental && style()->hasBorderRadius()) {
   1668         // If a border-radius exists and width/height is smaller than
   1669         // radius width/height, we cannot use delta-paint-invalidation.
   1670         RoundedRect oldRoundedRect = style()->getRoundedBorderFor(oldBounds);
   1671         RoundedRect newRoundedRect = style()->getRoundedBorderFor(newBounds);
   1672         if (oldRoundedRect.radii() != newRoundedRect.radii())
   1673             invalidationReason = InvalidationBorderRadius;
   1674     }
   1675 
   1676     if (invalidationReason == InvalidationIncremental && compositingState() != PaintsIntoOwnBacking && newLocation != oldLocation)
   1677         invalidationReason = InvalidationLocationChange;
   1678 
   1679     // If the bounds are the same then we know that none of the statements below
   1680     // can match, so we can early out since we will not need to do any
   1681     // invalidation.
   1682     if (invalidationReason == InvalidationIncremental && oldBounds == newBounds)
   1683         return false;
   1684 
   1685     if (invalidationReason == InvalidationIncremental) {
   1686         if (oldBounds.width() != newBounds.width() && mustInvalidateBackgroundOrBorderPaintOnWidthChange())
   1687             invalidationReason = InvalidationBoundsChangeWithBackground;
   1688         else if (oldBounds.height() != newBounds.height() && mustInvalidateBackgroundOrBorderPaintOnHeightChange())
   1689             invalidationReason = InvalidationBoundsChangeWithBackground;
   1690     }
   1691 
   1692     // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could
   1693     // be caused by some layout property (left / top) or some in-flow renderer inserted / removed before us in the tree.
   1694     if (invalidationReason == InvalidationIncremental && newBounds.location() != oldBounds.location())
   1695         invalidationReason = InvalidationBoundsChange;
   1696 
   1697     // If the size is zero on one of our bounds then we know we're going to have
   1698     // to do a full invalidation of either old bounds or new bounds. If we fall
   1699     // into the incremental invalidation we'll issue two invalidations instead
   1700     // of one.
   1701     if (invalidationReason == InvalidationIncremental && (oldBounds.size().isZero() || newBounds.size().isZero()))
   1702         invalidationReason = InvalidationBoundsChange;
   1703 
   1704     ASSERT(paintInvalidationContainer);
   1705 
   1706     if (invalidationReason != InvalidationIncremental) {
   1707         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds), invalidationReason);
   1708         if (newBounds != oldBounds)
   1709             invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds), invalidationReason);
   1710         return true;
   1711     }
   1712 
   1713     LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
   1714     if (deltaLeft > 0)
   1715         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()), invalidationReason);
   1716     else if (deltaLeft < 0)
   1717         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()), invalidationReason);
   1718 
   1719     LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
   1720     if (deltaRight > 0)
   1721         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()), invalidationReason);
   1722     else if (deltaRight < 0)
   1723         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()), invalidationReason);
   1724 
   1725     LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
   1726     if (deltaTop > 0)
   1727         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop), invalidationReason);
   1728     else if (deltaTop < 0)
   1729         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop), invalidationReason);
   1730 
   1731     LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
   1732     if (deltaBottom > 0)
   1733         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom), invalidationReason);
   1734     else if (deltaBottom < 0)
   1735         invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom), invalidationReason);
   1736 
   1737     // FIXME: This is a limitation of our visual overflow being a single rectangle.
   1738     if (!style()->boxShadow() && !style()->hasBorderImageOutsets() && !style()->hasOutline())
   1739         return false;
   1740 
   1741     // We didn't move, but we did change size. Invalidate the delta, which will consist of possibly
   1742     // two rectangles (but typically only one).
   1743     RenderStyle* outlineStyle = outlineStyleForPaintInvalidation();
   1744     LayoutUnit outlineWidth = outlineStyle->outlineSize();
   1745     LayoutBoxExtent insetShadowExtent = style()->getBoxShadowInsetExtent();
   1746     LayoutUnit width = absoluteValue(newBounds.width() - oldBounds.width());
   1747     if (width) {
   1748         LayoutUnit shadowLeft;
   1749         LayoutUnit shadowRight;
   1750         style()->getBoxShadowHorizontalExtent(shadowLeft, shadowRight);
   1751         int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0;
   1752         LayoutUnit boxWidth = isBox() ? toRenderBox(this)->width() : LayoutUnit();
   1753         LayoutUnit minInsetRightShadowExtent = min<LayoutUnit>(-insetShadowExtent.right(), min<LayoutUnit>(newBounds.width(), oldBounds.width()));
   1754         LayoutUnit borderWidth = max<LayoutUnit>(borderRight, max<LayoutUnit>(valueForLength(style()->borderTopRightRadius().width(), boxWidth), valueForLength(style()->borderBottomRightRadius().width(), boxWidth)));
   1755         LayoutUnit decorationsLeftWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderWidth + minInsetRightShadowExtent) + max<LayoutUnit>(outlineWidth, -shadowLeft);
   1756         LayoutUnit decorationsRightWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderWidth + minInsetRightShadowExtent) + max<LayoutUnit>(outlineWidth, shadowRight);
   1757         LayoutRect rightRect(newBounds.x() + min(newBounds.width(), oldBounds.width()) - decorationsLeftWidth,
   1758             newBounds.y(),
   1759             width + decorationsLeftWidth + decorationsRightWidth,
   1760             max(newBounds.height(), oldBounds.height()));
   1761         LayoutUnit right = min<LayoutUnit>(newBounds.maxX(), oldBounds.maxX());
   1762         if (rightRect.x() < right) {
   1763             rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
   1764             invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(rightRect), invalidationReason);
   1765         }
   1766     }
   1767     LayoutUnit height = absoluteValue(newBounds.height() - oldBounds.height());
   1768     if (height) {
   1769         LayoutUnit shadowTop;
   1770         LayoutUnit shadowBottom;
   1771         style()->getBoxShadowVerticalExtent(shadowTop, shadowBottom);
   1772         int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0;
   1773         LayoutUnit boxHeight = isBox() ? toRenderBox(this)->height() : LayoutUnit();
   1774         LayoutUnit minInsetBottomShadowExtent = min<LayoutUnit>(-insetShadowExtent.bottom(), min<LayoutUnit>(newBounds.height(), oldBounds.height()));
   1775         LayoutUnit borderHeight = max<LayoutUnit>(borderBottom, max<LayoutUnit>(valueForLength(style()->borderBottomLeftRadius().height(), boxHeight), valueForLength(style()->borderBottomRightRadius().height(), boxHeight)));
   1776         LayoutUnit decorationsTopHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderHeight + minInsetBottomShadowExtent) + max<LayoutUnit>(outlineWidth, -shadowTop);
   1777         LayoutUnit decorationsBottomHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderHeight + minInsetBottomShadowExtent) + max<LayoutUnit>(outlineWidth, shadowBottom);
   1778         LayoutRect bottomRect(newBounds.x(),
   1779             min(newBounds.maxY(), oldBounds.maxY()) - decorationsTopHeight,
   1780             max(newBounds.width(), oldBounds.width()),
   1781             height + decorationsTopHeight + decorationsBottomHeight);
   1782         LayoutUnit bottom = min(newBounds.maxY(), oldBounds.maxY());
   1783         if (bottomRect.y() < bottom) {
   1784             bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
   1785             invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(bottomRect), invalidationReason);
   1786         }
   1787     }
   1788     return false;
   1789 }
   1790 
   1791 void RenderObject::invalidatePaintForOverflow()
   1792 {
   1793 }
   1794 
   1795 void RenderObject::invalidatePaintForOverflowIfNeeded()
   1796 {
   1797     if (shouldInvalidateOverflowForPaint())
   1798         invalidatePaintForOverflow();
   1799 }
   1800 
   1801 bool RenderObject::checkForPaintInvalidation() const
   1802 {
   1803     return !document().view()->needsFullPaintInvalidation() && everHadLayout();
   1804 }
   1805 
   1806 bool RenderObject::checkForPaintInvalidationDuringLayout() const
   1807 {
   1808     return !RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && checkForPaintInvalidation();
   1809 }
   1810 
   1811 LayoutRect RenderObject::rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth) const
   1812 {
   1813     LayoutRect r(clippedOverflowRectForPaintInvalidation(paintInvalidationContainer));
   1814     r.inflate(outlineWidth);
   1815     return r;
   1816 }
   1817 
   1818 LayoutRect RenderObject::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject*) const
   1819 {
   1820     ASSERT_NOT_REACHED();
   1821     return LayoutRect();
   1822 }
   1823 
   1824 void RenderObject::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, bool fixed) const
   1825 {
   1826     if (paintInvalidationContainer == this)
   1827         return;
   1828 
   1829     if (RenderObject* o = parent()) {
   1830         if (o->isRenderBlockFlow()) {
   1831             RenderBlock* cb = toRenderBlock(o);
   1832             if (cb->hasColumns())
   1833                 cb->adjustRectForColumns(rect);
   1834         }
   1835 
   1836         if (o->hasOverflowClip()) {
   1837             RenderBox* boxParent = toRenderBox(o);
   1838             boxParent->applyCachedClipAndScrollOffsetForRepaint(rect);
   1839             if (rect.isEmpty())
   1840                 return;
   1841         }
   1842 
   1843         o->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, fixed);
   1844     }
   1845 }
   1846 
   1847 void RenderObject::computeFloatRectForPaintInvalidation(const RenderLayerModelObject*, FloatRect&, bool) const
   1848 {
   1849     ASSERT_NOT_REACHED();
   1850 }
   1851 
   1852 void RenderObject::dirtyLinesFromChangedChild(RenderObject*)
   1853 {
   1854 }
   1855 
   1856 #ifndef NDEBUG
   1857 
   1858 void RenderObject::showTreeForThis() const
   1859 {
   1860     if (node())
   1861         node()->showTreeForThis();
   1862 }
   1863 
   1864 void RenderObject::showRenderTreeForThis() const
   1865 {
   1866     showRenderTree(this, 0);
   1867 }
   1868 
   1869 void RenderObject::showLineTreeForThis() const
   1870 {
   1871     if (containingBlock())
   1872         containingBlock()->showLineTreeAndMark(0, 0, 0, 0, this);
   1873 }
   1874 
   1875 void RenderObject::showRenderObject() const
   1876 {
   1877     showRenderObject(0);
   1878 }
   1879 
   1880 void RenderObject::showRenderObject(int printedCharacters) const
   1881 {
   1882     // As this function is intended to be used when debugging, the
   1883     // this pointer may be 0.
   1884     if (!this) {
   1885         fputs("(null)\n", stderr);
   1886         return;
   1887     }
   1888 
   1889     printedCharacters += fprintf(stderr, "%s %p", renderName(), this);
   1890 
   1891     if (node()) {
   1892         if (printedCharacters)
   1893             for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
   1894                 fputc(' ', stderr);
   1895         fputc('\t', stderr);
   1896         node()->showNode();
   1897     } else
   1898         fputc('\n', stderr);
   1899 }
   1900 
   1901 void RenderObject::showRenderTreeAndMark(const RenderObject* markedObject1, const char* markedLabel1, const RenderObject* markedObject2, const char* markedLabel2, int depth) const
   1902 {
   1903     int printedCharacters = 0;
   1904     if (markedObject1 == this && markedLabel1)
   1905         printedCharacters += fprintf(stderr, "%s", markedLabel1);
   1906     if (markedObject2 == this && markedLabel2)
   1907         printedCharacters += fprintf(stderr, "%s", markedLabel2);
   1908     for (; printedCharacters < depth * 2; printedCharacters++)
   1909         fputc(' ', stderr);
   1910 
   1911     showRenderObject(printedCharacters);
   1912     if (!this)
   1913         return;
   1914 
   1915     for (const RenderObject* child = slowFirstChild(); child; child = child->nextSibling())
   1916         child->showRenderTreeAndMark(markedObject1, markedLabel1, markedObject2, markedLabel2, depth + 1);
   1917 }
   1918 
   1919 #endif // NDEBUG
   1920 
   1921 bool RenderObject::isSelectable() const
   1922 {
   1923     return !isInert() && !(style()->userSelect() == SELECT_NONE && style()->userModify() == READ_ONLY);
   1924 }
   1925 
   1926 Color RenderObject::selectionBackgroundColor() const
   1927 {
   1928     if (!isSelectable())
   1929         return Color::transparent;
   1930 
   1931     if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyleFromParentOrShadowHost())
   1932         return resolveColor(pseudoStyle.get(), CSSPropertyBackgroundColor).blendWithWhite();
   1933     return frame()->selection().isFocusedAndActive() ?
   1934         RenderTheme::theme().activeSelectionBackgroundColor() :
   1935         RenderTheme::theme().inactiveSelectionBackgroundColor();
   1936 }
   1937 
   1938 Color RenderObject::selectionColor(int colorProperty) const
   1939 {
   1940     // If the element is unselectable, or we are only painting the selection,
   1941     // don't override the foreground color with the selection foreground color.
   1942     if (!isSelectable() || (frame()->view()->paintBehavior() & PaintBehaviorSelectionOnly))
   1943         return resolveColor(colorProperty);
   1944 
   1945     if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyleFromParentOrShadowHost())
   1946         return resolveColor(pseudoStyle.get(), colorProperty);
   1947     if (!RenderTheme::theme().supportsSelectionForegroundColors())
   1948         return resolveColor(colorProperty);
   1949     return frame()->selection().isFocusedAndActive() ?
   1950         RenderTheme::theme().activeSelectionForegroundColor() :
   1951         RenderTheme::theme().inactiveSelectionForegroundColor();
   1952 }
   1953 
   1954 Color RenderObject::selectionForegroundColor() const
   1955 {
   1956     return selectionColor(CSSPropertyWebkitTextFillColor);
   1957 }
   1958 
   1959 Color RenderObject::selectionEmphasisMarkColor() const
   1960 {
   1961     return selectionColor(CSSPropertyWebkitTextEmphasisColor);
   1962 }
   1963 
   1964 void RenderObject::selectionStartEnd(int& spos, int& epos) const
   1965 {
   1966     view()->selectionStartEnd(spos, epos);
   1967 }
   1968 
   1969 void RenderObject::handleDynamicFloatPositionChange()
   1970 {
   1971     // We have gone from not affecting the inline status of the parent flow to suddenly
   1972     // having an impact.  See if there is a mismatch between the parent flow's
   1973     // childrenInline() state and our state.
   1974     setInline(style()->isDisplayInlineType());
   1975     if (isInline() != parent()->childrenInline()) {
   1976         if (!isInline())
   1977             toRenderBoxModelObject(parent())->childBecameNonInline(this);
   1978         else {
   1979             // An anonymous block must be made to wrap this inline.
   1980             RenderBlock* block = toRenderBlock(parent())->createAnonymousBlock();
   1981             RenderObjectChildList* childlist = parent()->virtualChildren();
   1982             childlist->insertChildNode(parent(), block, this);
   1983             block->children()->appendChildNode(block, childlist->removeChildNode(parent(), this));
   1984         }
   1985     }
   1986 }
   1987 
   1988 StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
   1989 {
   1990     if (contextSensitiveProperties & ContextSensitivePropertyTransform && isSVG())
   1991         diff.setNeedsFullLayout();
   1992 
   1993     // If transform changed, and the layer does not paint into its own separate backing, then we need to invalidate paints.
   1994     if (contextSensitiveProperties & ContextSensitivePropertyTransform) {
   1995         // Text nodes share style with their parents but transforms don't apply to them,
   1996         // hence the !isText() check.
   1997         if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer()->styleDeterminedCompositingReasons()))
   1998             diff.setNeedsRepaintLayer();
   1999         else
   2000             diff.setNeedsRecompositeLayer();
   2001     }
   2002 
   2003     // If opacity or zIndex changed, and the layer does not paint into its own separate backing, then we need to invalidate paints (also
   2004     // ignoring text nodes)
   2005     if (contextSensitiveProperties & (ContextSensitivePropertyOpacity | ContextSensitivePropertyZIndex)) {
   2006         if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer()->styleDeterminedCompositingReasons()))
   2007             diff.setNeedsRepaintLayer();
   2008         else
   2009             diff.setNeedsRecompositeLayer();
   2010     }
   2011 
   2012     // If filter changed, and the layer does not paint into its own separate backing or it paints with filters, then we need to invalidate paints.
   2013     if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLayer()) {
   2014         RenderLayer* layer = toRenderLayerModelObject(this)->layer();
   2015         if (!layer->styleDeterminedCompositingReasons() || layer->paintsWithFilters())
   2016             diff.setNeedsRepaintLayer();
   2017         else
   2018             diff.setNeedsRecompositeLayer();
   2019     }
   2020 
   2021     if ((contextSensitiveProperties & ContextSensitivePropertyTextOrColor) && !diff.needsRepaint()
   2022         && hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor())
   2023         diff.setNeedsRepaintObject();
   2024 
   2025     // The answer to layerTypeRequired() for plugins, iframes, and canvas can change without the actual
   2026     // style changing, since it depends on whether we decide to composite these elements. When the
   2027     // layer status of one of these elements changes, we need to force a layout.
   2028     if (!diff.needsFullLayout() && style() && isLayerModelObject()) {
   2029         bool requiresLayer = toRenderLayerModelObject(this)->layerTypeRequired() != NoLayer;
   2030         if (hasLayer() != requiresLayer)
   2031             diff.setNeedsFullLayout();
   2032     }
   2033 
   2034     // If we have no layer(), just treat a RepaintLayer hint as a normal paint invalidation.
   2035     if (diff.needsRepaintLayer() && !hasLayer()) {
   2036         diff.clearNeedsRepaint();
   2037         diff.setNeedsRepaintObject();
   2038     }
   2039 
   2040     return diff;
   2041 }
   2042 
   2043 void RenderObject::setPseudoStyle(PassRefPtr<RenderStyle> pseudoStyle)
   2044 {
   2045     ASSERT(pseudoStyle->styleType() == BEFORE || pseudoStyle->styleType() == AFTER);
   2046 
   2047     // FIXME: We should consider just making all pseudo items use an inherited style.
   2048 
   2049     // Images are special and must inherit the pseudoStyle so the width and height of
   2050     // the pseudo element doesn't change the size of the image. In all other cases we
   2051     // can just share the style.
   2052     //
   2053     // Quotes are also RenderInline, so we need to create an inherited style to avoid
   2054     // getting an inline with positioning or an invalid display.
   2055     //
   2056     if (isImage() || isQuote()) {
   2057         RefPtr<RenderStyle> style = RenderStyle::create();
   2058         style->inheritFrom(pseudoStyle.get());
   2059         setStyle(style.release());
   2060         return;
   2061     }
   2062 
   2063     setStyle(pseudoStyle);
   2064 }
   2065 
   2066 inline bool RenderObject::hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor() const
   2067 {
   2068     if (style()->hasBorder() || style()->hasOutline())
   2069         return true;
   2070     for (const RenderObject* r = slowFirstChild(); r; r = r->nextSibling()) {
   2071         if (r->isText() && !toRenderText(r)->isAllCollapsibleWhitespace())
   2072             return true;
   2073         if (r->style()->hasOutline() || r->style()->hasBorder())
   2074             return true;
   2075     }
   2076     return false;
   2077 }
   2078 
   2079 void RenderObject::markContainingBlocksForOverflowRecalc()
   2080 {
   2081     for (RenderBlock* container = containingBlock(); container && !container->childNeedsOverflowRecalcAfterStyleChange(); container = container->containingBlock())
   2082         container->setChildNeedsOverflowRecalcAfterStyleChange(true);
   2083 }
   2084 
   2085 void RenderObject::setNeedsOverflowRecalcAfterStyleChange()
   2086 {
   2087     bool neededRecalc = needsOverflowRecalcAfterStyleChange();
   2088     setSelfNeedsOverflowRecalcAfterStyleChange(true);
   2089     if (!neededRecalc)
   2090         markContainingBlocksForOverflowRecalc();
   2091 }
   2092 
   2093 void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
   2094 {
   2095     ASSERT(style);
   2096 
   2097     if (m_style == style) {
   2098         // We need to run through adjustStyleDifference() for iframes, plugins, and canvas so
   2099         // style sharing is disabled for them. That should ensure that we never hit this code path.
   2100         ASSERT(!isRenderIFrame() && !isEmbeddedObject() && !isCanvas());
   2101         return;
   2102     }
   2103 
   2104     StyleDifference diff;
   2105     unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
   2106     if (m_style)
   2107         diff = m_style->visualInvalidationDiff(*style, contextSensitiveProperties);
   2108 
   2109     diff = adjustStyleDifference(diff, contextSensitiveProperties);
   2110 
   2111     styleWillChange(diff, *style);
   2112 
   2113     RefPtr<RenderStyle> oldStyle = m_style.release();
   2114     setStyleInternal(style);
   2115 
   2116     updateFillImages(oldStyle ? oldStyle->backgroundLayers() : 0, m_style ? m_style->backgroundLayers() : 0);
   2117     updateFillImages(oldStyle ? oldStyle->maskLayers() : 0, m_style ? m_style->maskLayers() : 0);
   2118 
   2119     updateImage(oldStyle ? oldStyle->borderImage().image() : 0, m_style ? m_style->borderImage().image() : 0);
   2120     updateImage(oldStyle ? oldStyle->maskBoxImage().image() : 0, m_style ? m_style->maskBoxImage().image() : 0);
   2121 
   2122     updateShapeImage(oldStyle ? oldStyle->shapeOutside() : 0, m_style ? m_style->shapeOutside() : 0);
   2123 
   2124     bool doesNotNeedLayout = !m_parent || isText();
   2125 
   2126     styleDidChange(diff, oldStyle.get());
   2127 
   2128     // FIXME: |this| might be destroyed here. This can currently happen for a RenderTextFragment when
   2129     // its first-letter block gets an update in RenderTextFragment::styleDidChange. For RenderTextFragment(s),
   2130     // we will safely bail out with the doesNotNeedLayout flag. We might want to broaden this condition
   2131     // in the future as we move renderer changes out of layout and into style changes.
   2132     if (doesNotNeedLayout)
   2133         return;
   2134 
   2135     // Now that the layer (if any) has been updated, we need to adjust the diff again,
   2136     // check whether we should layout now, and decide if we need to invalidate paints.
   2137     StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
   2138 
   2139     if (!diff.needsFullLayout()) {
   2140         if (updatedDiff.needsFullLayout())
   2141             setNeedsLayoutAndPrefWidthsRecalc();
   2142         else if (updatedDiff.needsPositionedMovementLayout())
   2143             setNeedsPositionedMovementLayout();
   2144     }
   2145 
   2146     if (contextSensitiveProperties & ContextSensitivePropertyTransform && !needsLayout()) {
   2147         if (RenderBlock* container = containingBlock())
   2148             container->setNeedsOverflowRecalcAfterStyleChange();
   2149     }
   2150 
   2151     if (updatedDiff.needsRepaintLayer()) {
   2152         toRenderLayerModelObject(this)->layer()->repainter().repaintIncludingNonCompositingDescendants();
   2153     } else if (updatedDiff.needsRepaint()) {
   2154         // Invalidate paints with the new style, e.g., for example if we go from not having
   2155         // an outline to having an outline.
   2156         if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && needsLayout())
   2157             setShouldDoFullPaintInvalidationAfterLayout(true);
   2158         else if (!selfNeedsLayout())
   2159             paintInvalidationForWholeRenderer();
   2160     }
   2161 }
   2162 
   2163 static inline bool rendererHasBackground(const RenderObject* renderer)
   2164 {
   2165     return renderer && renderer->hasBackground();
   2166 }
   2167 
   2168 void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
   2169 {
   2170     if (m_style) {
   2171         // If our z-index changes value or our visibility changes,
   2172         // we need to dirty our stacking context's z-order list.
   2173         bool visibilityChanged = m_style->visibility() != newStyle.visibility()
   2174             || m_style->zIndex() != newStyle.zIndex()
   2175             || m_style->hasAutoZIndex() != newStyle.hasAutoZIndex();
   2176         if (visibilityChanged) {
   2177             document().setAnnotatedRegionsDirty(true);
   2178             if (AXObjectCache* cache = document().existingAXObjectCache())
   2179                 cache->childrenChanged(parent());
   2180         }
   2181 
   2182         // Keep layer hierarchy visibility bits up to date if visibility changes.
   2183         if (m_style->visibility() != newStyle.visibility()) {
   2184             // We might not have an enclosing layer yet because we might not be in the tree.
   2185             if (RenderLayer* layer = enclosingLayer()) {
   2186                 if (newStyle.visibility() == VISIBLE) {
   2187                     layer->setHasVisibleContent();
   2188                 } else if (layer->hasVisibleContent() && (this == layer->renderer() || layer->renderer()->style()->visibility() != VISIBLE)) {
   2189                     layer->dirtyVisibleContentStatus();
   2190                     if (diff.needsLayout())
   2191                         paintInvalidationForWholeRenderer();
   2192                 }
   2193             }
   2194         }
   2195 
   2196         if (m_parent && diff.needsRepaintObject()) {
   2197             if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && (diff.needsLayout() || needsLayout()))
   2198                 setShouldDoFullPaintInvalidationAfterLayout(true);
   2199             else if (!diff.needsFullLayout() && !selfNeedsLayout())
   2200                 paintInvalidationForWholeRenderer();
   2201         }
   2202 
   2203         if (isFloating() && (m_style->floating() != newStyle.floating()))
   2204             // For changes in float styles, we need to conceivably remove ourselves
   2205             // from the floating objects list.
   2206             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
   2207         else if (isOutOfFlowPositioned() && (m_style->position() != newStyle.position()))
   2208             // For changes in positioning styles, we need to conceivably remove ourselves
   2209             // from the positioned objects list.
   2210             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
   2211 
   2212         s_affectsParentBlock = isFloatingOrOutOfFlowPositioned()
   2213             && (!newStyle.isFloating() && !newStyle.hasOutOfFlowPosition())
   2214             && parent() && (parent()->isRenderBlockFlow() || parent()->isRenderInline());
   2215 
   2216         // Clearing these bits is required to avoid leaving stale renderers.
   2217         // FIXME: We shouldn't need that hack if our logic was totally correct.
   2218         if (diff.needsLayout()) {
   2219             setFloating(false);
   2220             clearPositionedState();
   2221         }
   2222     } else {
   2223         s_affectsParentBlock = false;
   2224     }
   2225 
   2226     if (view()->frameView()) {
   2227         bool shouldBlitOnFixedBackgroundImage = false;
   2228         if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) {
   2229             // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
   2230             // when scrolling a page with a fixed background image. As an optimization, assuming there are
   2231             // no fixed positoned elements on the page, we can acclerate scrolling (via blitting) if we
   2232             // ignore the CSS property "background-attachment: fixed".
   2233             shouldBlitOnFixedBackgroundImage = true;
   2234         }
   2235         bool newStyleSlowScroll = !shouldBlitOnFixedBackgroundImage && newStyle.hasFixedBackgroundImage();
   2236         bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
   2237 
   2238         bool drawsRootBackground = isDocumentElement() || (isBody() && !rendererHasBackground(document().documentElement()->renderer()));
   2239         if (drawsRootBackground && !shouldBlitOnFixedBackgroundImage) {
   2240             if (view()->compositor()->supportsFixedRootBackgroundCompositing()) {
   2241                 if (newStyleSlowScroll && newStyle.hasEntirelyFixedBackground())
   2242                     newStyleSlowScroll = false;
   2243 
   2244                 if (oldStyleSlowScroll && m_style->hasEntirelyFixedBackground())
   2245                     oldStyleSlowScroll = false;
   2246             }
   2247         }
   2248 
   2249         if (oldStyleSlowScroll != newStyleSlowScroll) {
   2250             if (oldStyleSlowScroll)
   2251                 view()->frameView()->removeSlowRepaintObject();
   2252             if (newStyleSlowScroll)
   2253                 view()->frameView()->addSlowRepaintObject();
   2254         }
   2255     }
   2256 
   2257     // Elements with non-auto touch-action will send a SetTouchAction message
   2258     // on touchstart in EventHandler::handleTouchEvent, and so effectively have
   2259     // a touchstart handler that must be reported.
   2260     //
   2261     // Since a CSS property cannot be applied directly to a text node, a
   2262     // handler will have already been added for its parent so ignore it.
   2263     TouchAction oldTouchAction = m_style ? m_style->touchAction() : TouchActionAuto;
   2264     if (node() && !node()->isTextNode() && (oldTouchAction == TouchActionAuto) != (newStyle.touchAction() == TouchActionAuto)) {
   2265         if (newStyle.touchAction() != TouchActionAuto)
   2266             document().didAddTouchEventHandler(node());
   2267         else
   2268             document().didRemoveTouchEventHandler(node());
   2269     }
   2270 }
   2271 
   2272 static bool areNonIdenticalCursorListsEqual(const RenderStyle* a, const RenderStyle* b)
   2273 {
   2274     ASSERT(a->cursors() != b->cursors());
   2275     return a->cursors() && b->cursors() && *a->cursors() == *b->cursors();
   2276 }
   2277 
   2278 static inline bool areCursorsEqual(const RenderStyle* a, const RenderStyle* b)
   2279 {
   2280     return a->cursor() == b->cursor() && (a->cursors() == b->cursors() || areNonIdenticalCursorListsEqual(a, b));
   2281 }
   2282 
   2283 void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
   2284 {
   2285     if (s_affectsParentBlock)
   2286         handleDynamicFloatPositionChange();
   2287 
   2288     if (!m_parent)
   2289         return;
   2290 
   2291     if (diff.needsFullLayout()) {
   2292         RenderCounter::rendererStyleChanged(*this, oldStyle, m_style.get());
   2293 
   2294         // If the object already needs layout, then setNeedsLayout won't do
   2295         // any work. But if the containing block has changed, then we may need
   2296         // to mark the new containing blocks for layout. The change that can
   2297         // directly affect the containing block of this object is a change to
   2298         // the position style.
   2299         if (needsLayout() && oldStyle->position() != m_style->position())
   2300             markContainingBlocksForLayout();
   2301 
   2302         // Ditto.
   2303         if (needsOverflowRecalcAfterStyleChange() && oldStyle->position() != m_style->position())
   2304             markContainingBlocksForOverflowRecalc();
   2305 
   2306         if (diff.needsFullLayout())
   2307             setNeedsLayoutAndPrefWidthsRecalc();
   2308     } else if (diff.needsPositionedMovementLayout())
   2309         setNeedsPositionedMovementLayout();
   2310 
   2311     // Don't check for paint invalidation here; we need to wait until the layer has been
   2312     // updated by subclasses before we know if we have to invalidate paints (in setStyle()).
   2313 
   2314     if (oldStyle && !areCursorsEqual(oldStyle, style())) {
   2315         if (LocalFrame* frame = this->frame())
   2316             frame->eventHandler().scheduleCursorUpdate();
   2317     }
   2318 }
   2319 
   2320 void RenderObject::propagateStyleToAnonymousChildren(bool blockChildrenOnly)
   2321 {
   2322     // FIXME: We could save this call when the change only affected non-inherited properties.
   2323     for (RenderObject* child = slowFirstChild(); child; child = child->nextSibling()) {
   2324         if (!child->isAnonymous() || child->style()->styleType() != NOPSEUDO)
   2325             continue;
   2326 
   2327         if (blockChildrenOnly && !child->isRenderBlock())
   2328             continue;
   2329 
   2330         if (child->isRenderFullScreen() || child->isRenderFullScreenPlaceholder())
   2331             continue;
   2332 
   2333         RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), child->style()->display());
   2334         if (style()->specifiesColumns()) {
   2335             if (child->style()->specifiesColumns())
   2336                 newStyle->inheritColumnPropertiesFrom(style());
   2337             if (child->style()->columnSpan())
   2338                 newStyle->setColumnSpan(ColumnSpanAll);
   2339         }
   2340 
   2341         // Preserve the position style of anonymous block continuations as they can have relative or sticky position when
   2342         // they contain block descendants of relative or sticky positioned inlines.
   2343         if (child->isInFlowPositioned() && toRenderBlock(child)->isAnonymousBlockContinuation())
   2344             newStyle->setPosition(child->style()->position());
   2345 
   2346         child->setStyle(newStyle.release());
   2347     }
   2348 }
   2349 
   2350 void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers)
   2351 {
   2352     // Optimize the common case
   2353     if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && (oldLayers->image() == newLayers->image()))
   2354         return;
   2355 
   2356     // Go through the new layers and addClients first, to avoid removing all clients of an image.
   2357     for (const FillLayer* currNew = newLayers; currNew; currNew = currNew->next()) {
   2358         if (currNew->image())
   2359             currNew->image()->addClient(this);
   2360     }
   2361 
   2362     for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) {
   2363         if (currOld->image())
   2364             currOld->image()->removeClient(this);
   2365     }
   2366 }
   2367 
   2368 void RenderObject::updateImage(StyleImage* oldImage, StyleImage* newImage)
   2369 {
   2370     if (oldImage != newImage) {
   2371         if (oldImage)
   2372             oldImage->removeClient(this);
   2373         if (newImage)
   2374             newImage->addClient(this);
   2375     }
   2376 }
   2377 
   2378 void RenderObject::updateShapeImage(const ShapeValue* oldShapeValue, const ShapeValue* newShapeValue)
   2379 {
   2380     if (oldShapeValue || newShapeValue)
   2381         updateImage(oldShapeValue ? oldShapeValue->image() : 0, newShapeValue ? newShapeValue->image() : 0);
   2382 }
   2383 
   2384 LayoutRect RenderObject::viewRect() const
   2385 {
   2386     return view()->viewRect();
   2387 }
   2388 
   2389 FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode) const
   2390 {
   2391     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
   2392     mapLocalToContainer(0, transformState, mode | ApplyContainerFlip);
   2393     transformState.flatten();
   2394 
   2395     return transformState.lastPlanarPoint();
   2396 }
   2397 
   2398 FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, MapCoordinatesFlags mode) const
   2399 {
   2400     TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
   2401     mapAbsoluteToLocalPoint(mode, transformState);
   2402     transformState.flatten();
   2403 
   2404     return transformState.lastPlanarPoint();
   2405 }
   2406 
   2407 FloatQuad RenderObject::absoluteToLocalQuad(const FloatQuad& quad, MapCoordinatesFlags mode) const
   2408 {
   2409     TransformState transformState(TransformState::UnapplyInverseTransformDirection, quad.boundingBox().center(), quad);
   2410     mapAbsoluteToLocalPoint(mode, transformState);
   2411     transformState.flatten();
   2412     return transformState.lastPlanarQuad();
   2413 }
   2414 
   2415 void RenderObject::mapLocalToContainer(const RenderLayerModelObject* paintInvalidationContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
   2416 {
   2417     if (paintInvalidationContainer == this)
   2418         return;
   2419 
   2420     RenderObject* o = parent();
   2421     if (!o)
   2422         return;
   2423 
   2424     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
   2425     LayoutPoint centerPoint = roundedLayoutPoint(transformState.mappedPoint());
   2426     if (mode & ApplyContainerFlip && o->isBox()) {
   2427         if (o->style()->isFlippedBlocksWritingMode())
   2428             transformState.move(toRenderBox(o)->flipForWritingModeIncludingColumns(roundedLayoutPoint(transformState.mappedPoint())) - centerPoint);
   2429         mode &= ~ApplyContainerFlip;
   2430     }
   2431 
   2432     transformState.move(o->columnOffset(roundedLayoutPoint(transformState.mappedPoint())));
   2433 
   2434     if (o->hasOverflowClip())
   2435         transformState.move(-toRenderBox(o)->scrolledContentOffset());
   2436 
   2437     o->mapLocalToContainer(paintInvalidationContainer, transformState, mode, wasFixed);
   2438 }
   2439 
   2440 const RenderObject* RenderObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
   2441 {
   2442     ASSERT_UNUSED(ancestorToStopAt, ancestorToStopAt != this);
   2443 
   2444     RenderObject* container = parent();
   2445     if (!container)
   2446         return 0;
   2447 
   2448     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
   2449     LayoutSize offset;
   2450     if (container->hasOverflowClip())
   2451         offset = -toRenderBox(container)->scrolledContentOffset();
   2452 
   2453     geometryMap.push(this, offset, hasColumns());
   2454 
   2455     return container;
   2456 }
   2457 
   2458 void RenderObject::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
   2459 {
   2460     RenderObject* o = parent();
   2461     if (o) {
   2462         o->mapAbsoluteToLocalPoint(mode, transformState);
   2463         if (o->hasOverflowClip())
   2464             transformState.move(toRenderBox(o)->scrolledContentOffset());
   2465     }
   2466 }
   2467 
   2468 bool RenderObject::shouldUseTransformFromContainer(const RenderObject* containerObject) const
   2469 {
   2470     // hasTransform() indicates whether the object has transform, transform-style or perspective. We just care about transform,
   2471     // so check the layer's transform directly.
   2472     return (hasLayer() && toRenderLayerModelObject(this)->layer()->transform()) || (containerObject && containerObject->style()->hasPerspective());
   2473 }
   2474 
   2475 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
   2476 {
   2477     transform.makeIdentity();
   2478     transform.translate(offsetInContainer.width().toFloat(), offsetInContainer.height().toFloat());
   2479     RenderLayer* layer;
   2480     if (hasLayer() && (layer = toRenderLayerModelObject(this)->layer()) && layer->transform())
   2481         transform.multiply(layer->currentTransform());
   2482 
   2483     if (containerObject && containerObject->hasLayer() && containerObject->style()->hasPerspective()) {
   2484         // Perpsective on the container affects us, so we have to factor it in here.
   2485         ASSERT(containerObject->hasLayer());
   2486         FloatPoint perspectiveOrigin = toRenderLayerModelObject(containerObject)->layer()->perspectiveOrigin();
   2487 
   2488         TransformationMatrix perspectiveMatrix;
   2489         perspectiveMatrix.applyPerspective(containerObject->style()->perspective());
   2490 
   2491         transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
   2492         transform = perspectiveMatrix * transform;
   2493         transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
   2494     }
   2495 }
   2496 
   2497 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, const RenderLayerModelObject* paintInvalidationContainer, MapCoordinatesFlags mode, bool* wasFixed) const
   2498 {
   2499     // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
   2500     // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
   2501     TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
   2502     mapLocalToContainer(paintInvalidationContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
   2503     transformState.flatten();
   2504 
   2505     return transformState.lastPlanarQuad();
   2506 }
   2507 
   2508 FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, const RenderLayerModelObject* paintInvalidationContainer, MapCoordinatesFlags mode, bool* wasFixed) const
   2509 {
   2510     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
   2511     mapLocalToContainer(paintInvalidationContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
   2512     transformState.flatten();
   2513 
   2514     return transformState.lastPlanarPoint();
   2515 }
   2516 
   2517 LayoutSize RenderObject::offsetFromContainer(const RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
   2518 {
   2519     ASSERT(o == container());
   2520 
   2521     LayoutSize offset = o->columnOffset(point);
   2522 
   2523     if (o->hasOverflowClip())
   2524         offset -= toRenderBox(o)->scrolledContentOffset();
   2525 
   2526     if (offsetDependsOnPoint)
   2527         *offsetDependsOnPoint = hasColumns() || o->isRenderFlowThread();
   2528 
   2529     return offset;
   2530 }
   2531 
   2532 LayoutSize RenderObject::offsetFromAncestorContainer(const RenderObject* container) const
   2533 {
   2534     LayoutSize offset;
   2535     LayoutPoint referencePoint;
   2536     const RenderObject* currContainer = this;
   2537     do {
   2538         const RenderObject* nextContainer = currContainer->container();
   2539         ASSERT(nextContainer);  // This means we reached the top without finding container.
   2540         if (!nextContainer)
   2541             break;
   2542         ASSERT(!currContainer->hasTransform());
   2543         LayoutSize currentOffset = currContainer->offsetFromContainer(nextContainer, referencePoint);
   2544         offset += currentOffset;
   2545         referencePoint.move(currentOffset);
   2546         currContainer = nextContainer;
   2547     } while (currContainer != container);
   2548 
   2549     return offset;
   2550 }
   2551 
   2552 LayoutRect RenderObject::localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine)
   2553 {
   2554     if (extraWidthToEndOfLine)
   2555         *extraWidthToEndOfLine = 0;
   2556 
   2557     return LayoutRect();
   2558 }
   2559 
   2560 void RenderObject::computeLayerHitTestRects(LayerHitTestRects& layerRects) const
   2561 {
   2562     // Figure out what layer our container is in. Any offset (or new layer) for this
   2563     // renderer within it's container will be applied in addLayerHitTestRects.
   2564     LayoutPoint layerOffset;
   2565     const RenderLayer* currentLayer = 0;
   2566 
   2567     if (!hasLayer()) {
   2568         RenderObject* container = this->container();
   2569         currentLayer = container->enclosingLayer();
   2570         if (container && currentLayer->renderer() != container) {
   2571             layerOffset.move(container->offsetFromAncestorContainer(currentLayer->renderer()));
   2572             // If the layer itself is scrolled, we have to undo the subtraction of its scroll
   2573             // offset since we want the offset relative to the scrolling content, not the
   2574             // element itself.
   2575             if (currentLayer->renderer()->hasOverflowClip())
   2576                 layerOffset.move(currentLayer->renderBox()->scrolledContentOffset());
   2577         }
   2578     }
   2579 
   2580     this->addLayerHitTestRects(layerRects, currentLayer, layerOffset, LayoutRect());
   2581 }
   2582 
   2583 void RenderObject::addLayerHitTestRects(LayerHitTestRects& layerRects, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const
   2584 {
   2585     ASSERT(currentLayer);
   2586     ASSERT(currentLayer == this->enclosingLayer());
   2587 
   2588     // Compute the rects for this renderer only and add them to the results.
   2589     // Note that we could avoid passing the offset and instead adjust each result, but this
   2590     // seems slightly simpler.
   2591     Vector<LayoutRect> ownRects;
   2592     LayoutRect newContainerRect;
   2593     computeSelfHitTestRects(ownRects, layerOffset);
   2594 
   2595     // When we get to have a lot of rects on a layer, the performance cost of tracking those
   2596     // rects outweighs the benefit of doing compositor thread hit testing.
   2597     // FIXME: This limit needs to be low due to the O(n^2) algorithm in
   2598     // WebLayer::setTouchEventHandlerRegion - crbug.com/300282.
   2599     const size_t maxRectsPerLayer = 100;
   2600 
   2601     LayerHitTestRects::iterator iter = layerRects.find(currentLayer);
   2602     Vector<WebCore::LayoutRect>* iterValue;
   2603     if (iter == layerRects.end())
   2604         iterValue = &layerRects.add(currentLayer, Vector<LayoutRect>()).storedValue->value;
   2605     else
   2606         iterValue = &iter->value;
   2607     for (size_t i = 0; i < ownRects.size(); i++) {
   2608         if (!containerRect.contains(ownRects[i])) {
   2609             iterValue->append(ownRects[i]);
   2610             if (iterValue->size() > maxRectsPerLayer) {
   2611                 // Just mark the entire layer instead, and switch to walking the layer
   2612                 // tree instead of the render tree.
   2613                 layerRects.remove(currentLayer);
   2614                 currentLayer->addLayerHitTestRects(layerRects);
   2615                 return;
   2616             }
   2617             if (newContainerRect.isEmpty())
   2618                 newContainerRect = ownRects[i];
   2619         }
   2620     }
   2621     if (newContainerRect.isEmpty())
   2622         newContainerRect = containerRect;
   2623 
   2624     // If it's possible for children to have rects outside our bounds, then we need to descend into
   2625     // the children and compute them.
   2626     // Ideally there would be other cases where we could detect that children couldn't have rects
   2627     // outside our bounds and prune the tree walk.
   2628     // Note that we don't use Region here because Union is O(N) - better to just keep a list of
   2629     // partially redundant rectangles. If we find examples where this is expensive, then we could
   2630     // rewrite Region to be more efficient. See https://bugs.webkit.org/show_bug.cgi?id=100814.
   2631     if (!isRenderView()) {
   2632         for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling()) {
   2633             curr->addLayerHitTestRects(layerRects, currentLayer,  layerOffset, newContainerRect);
   2634         }
   2635     }
   2636 }
   2637 
   2638 bool RenderObject::isRooted() const
   2639 {
   2640     const RenderObject* object = this;
   2641     while (object->parent() && !object->hasLayer())
   2642         object = object->parent();
   2643     if (object->hasLayer())
   2644         return toRenderLayerModelObject(object)->layer()->root()->isRootLayer();
   2645     return false;
   2646 }
   2647 
   2648 RenderObject* RenderObject::rendererForRootBackground()
   2649 {
   2650     ASSERT(isDocumentElement());
   2651     if (!hasBackground() && isHTMLHtmlElement(node())) {
   2652         // Locate the <body> element using the DOM. This is easier than trying
   2653         // to crawl around a render tree with potential :before/:after content and
   2654         // anonymous blocks created by inline <body> tags etc. We can locate the <body>
   2655         // render object very easily via the DOM.
   2656         HTMLElement* body = document().body();
   2657         RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
   2658         if (bodyObject)
   2659             return bodyObject;
   2660     }
   2661 
   2662     return this;
   2663 }
   2664 
   2665 RespectImageOrientationEnum RenderObject::shouldRespectImageOrientation() const
   2666 {
   2667     // Respect the image's orientation if it's being used as a full-page image or it's
   2668     // an <img> and the setting to respect it everywhere is set.
   2669     return document().isImageDocument()
   2670         || (document().settings() && document().settings()->shouldRespectImageOrientation() && isHTMLImageElement(node())) ? RespectImageOrientation : DoNotRespectImageOrientation;
   2671 }
   2672 
   2673 bool RenderObject::hasOutlineAnnotation() const
   2674 {
   2675     return node() && node()->isLink() && document().printing();
   2676 }
   2677 
   2678 bool RenderObject::hasEntirelyFixedBackground() const
   2679 {
   2680     return m_style->hasEntirelyFixedBackground();
   2681 }
   2682 
   2683 RenderObject* RenderObject::container(const RenderLayerModelObject* paintInvalidationContainer, bool* paintInvalidationContainerSkipped) const
   2684 {
   2685     if (paintInvalidationContainerSkipped)
   2686         *paintInvalidationContainerSkipped = false;
   2687 
   2688     // This method is extremely similar to containingBlock(), but with a few notable
   2689     // exceptions.
   2690     // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when
   2691     // the object is not part of the primary document subtree yet.
   2692     // (2) For normal flow elements, it just returns the parent.
   2693     // (3) For absolute positioned elements, it will return a relative positioned inline.
   2694     // containingBlock() simply skips relpositioned inlines and lets an enclosing block handle
   2695     // the layout of the positioned object.  This does mean that computePositionedLogicalWidth and
   2696     // computePositionedLogicalHeight have to use container().
   2697     RenderObject* o = parent();
   2698 
   2699     if (isText())
   2700         return o;
   2701 
   2702     EPosition pos = m_style->position();
   2703     if (pos == FixedPosition) {
   2704         return containerForFixedPosition(paintInvalidationContainer, paintInvalidationContainerSkipped);
   2705     } else if (pos == AbsolutePosition) {
   2706         // We technically just want our containing block, but
   2707         // we may not have one if we're part of an uninstalled
   2708         // subtree. We'll climb as high as we can though.
   2709         while (o) {
   2710             if (o->style()->position() != StaticPosition)
   2711                 break;
   2712 
   2713             if (o->canContainFixedPositionObjects())
   2714                 break;
   2715 
   2716             if (paintInvalidationContainerSkipped && o == paintInvalidationContainer)
   2717                 *paintInvalidationContainerSkipped = true;
   2718 
   2719             o = o->parent();
   2720         }
   2721     }
   2722 
   2723     return o;
   2724 }
   2725 
   2726 bool RenderObject::isSelectionBorder() const
   2727 {
   2728     SelectionState st = selectionState();
   2729     return st == SelectionStart || st == SelectionEnd || st == SelectionBoth;
   2730 }
   2731 
   2732 inline void RenderObject::clearLayoutRootIfNeeded() const
   2733 {
   2734     if (frame()) {
   2735         if (FrameView* view = frame()->view()) {
   2736             if (view->layoutRoot() == this) {
   2737                 if (!documentBeingDestroyed())
   2738                     ASSERT_NOT_REACHED();
   2739                 // This indicates a failure to layout the child, which is why
   2740                 // the layout root is still set to |this|. Make sure to clear it
   2741                 // since we are getting destroyed.
   2742                 view->clearLayoutSubtreeRoot();
   2743             }
   2744         }
   2745     }
   2746 }
   2747 
   2748 void RenderObject::willBeDestroyed()
   2749 {
   2750     // Destroy any leftover anonymous children.
   2751     RenderObjectChildList* children = virtualChildren();
   2752     if (children)
   2753         children->destroyLeftoverChildren();
   2754 
   2755     // If this renderer is being autoscrolled, stop the autoscrolling.
   2756     if (LocalFrame* frame = this->frame()) {
   2757         if (frame->page())
   2758             frame->page()->autoscrollController().stopAutoscrollIfNeeded(this);
   2759     }
   2760 
   2761     // For accessibility management, notify the parent of the imminent change to its child set.
   2762     // We do it now, before remove(), while the parent pointer is still available.
   2763     if (AXObjectCache* cache = document().existingAXObjectCache())
   2764         cache->childrenChanged(this->parent());
   2765 
   2766     remove();
   2767 
   2768     // The remove() call above may invoke axObjectCache()->childrenChanged() on the parent, which may require the AX render
   2769     // object for this renderer. So we remove the AX render object now, after the renderer is removed.
   2770     if (AXObjectCache* cache = document().existingAXObjectCache())
   2771         cache->remove(this);
   2772 
   2773     // If this renderer had a parent, remove should have destroyed any counters
   2774     // attached to this renderer and marked the affected other counters for
   2775     // reevaluation. This apparently redundant check is here for the case when
   2776     // this renderer had no parent at the time remove() was called.
   2777 
   2778     if (hasCounterNodeMap())
   2779         RenderCounter::destroyCounterNodes(*this);
   2780 
   2781     // Remove the handler if node had touch-action set. Don't call when
   2782     // document is being destroyed as all handlers will have been cleared
   2783     // previously. Handlers are not added for text nodes so don't try removing
   2784     // for one too. Need to check if m_style is null in cases of partial construction.
   2785     if (!documentBeingDestroyed() && node() && !node()->isTextNode() && m_style && m_style->touchAction() != TouchActionAuto)
   2786         document().didRemoveTouchEventHandler(node());
   2787 
   2788     setAncestorLineBoxDirty(false);
   2789 
   2790     clearLayoutRootIfNeeded();
   2791 }
   2792 
   2793 void RenderObject::insertedIntoTree()
   2794 {
   2795     // FIXME: We should ASSERT(isRooted()) here but generated content makes some out-of-order insertion.
   2796 
   2797     // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
   2798     // and don't have a layer attached to ourselves.
   2799     RenderLayer* layer = 0;
   2800     if (slowFirstChild() || hasLayer()) {
   2801         layer = parent()->enclosingLayer();
   2802         addLayers(layer);
   2803     }
   2804 
   2805     // If |this| is visible but this object was not, tell the layer it has some visible content
   2806     // that needs to be drawn and layer visibility optimization can't be used
   2807     if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
   2808         if (!layer)
   2809             layer = parent()->enclosingLayer();
   2810         if (layer)
   2811             layer->setHasVisibleContent();
   2812     }
   2813 
   2814     if (!isFloating() && parent()->childrenInline())
   2815         parent()->dirtyLinesFromChangedChild(this);
   2816 }
   2817 
   2818 void RenderObject::willBeRemovedFromTree()
   2819 {
   2820     // FIXME: We should ASSERT(isRooted()) but we have some out-of-order removals which would need to be fixed first.
   2821 
   2822     // If we remove a visible child from an invisible parent, we don't know the layer visibility any more.
   2823     RenderLayer* layer = 0;
   2824     if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
   2825         layer = parent()->enclosingLayer();
   2826         if (layer)
   2827             layer->dirtyVisibleContentStatus();
   2828     }
   2829 
   2830     // Keep our layer hierarchy updated.
   2831     if (slowFirstChild() || hasLayer()) {
   2832         if (!layer)
   2833             layer = parent()->enclosingLayer();
   2834         removeLayers(layer);
   2835     }
   2836 
   2837     if (isOutOfFlowPositioned() && parent()->childrenInline())
   2838         parent()->dirtyLinesFromChangedChild(this);
   2839 
   2840     removeFromRenderFlowThread();
   2841 
   2842     // Update cached boundaries in SVG renderers if a child is removed.
   2843     if (parent()->isSVG())
   2844         parent()->setNeedsBoundariesUpdate();
   2845 }
   2846 
   2847 void RenderObject::removeFromRenderFlowThread()
   2848 {
   2849     if (flowThreadState() == NotInsideFlowThread)
   2850         return;
   2851 
   2852     // Sometimes we remove the element from the flow, but it's not destroyed at that time.
   2853     // It's only until later when we actually destroy it and remove all the children from it.
   2854     // Currently, that happens for firstLetter elements and list markers.
   2855     // Pass in the flow thread so that we don't have to look it up for all the children.
   2856     removeFromRenderFlowThreadRecursive(flowThreadContainingBlock());
   2857 }
   2858 
   2859 void RenderObject::removeFromRenderFlowThreadRecursive(RenderFlowThread* renderFlowThread)
   2860 {
   2861     if (const RenderObjectChildList* children = virtualChildren()) {
   2862         for (RenderObject* child = children->firstChild(); child; child = child->nextSibling())
   2863             child->removeFromRenderFlowThreadRecursive(renderFlowThread);
   2864     }
   2865 
   2866     setFlowThreadState(NotInsideFlowThread);
   2867 }
   2868 
   2869 void RenderObject::destroyAndCleanupAnonymousWrappers()
   2870 {
   2871     // If the tree is destroyed, there is no need for a clean-up phase.
   2872     if (documentBeingDestroyed()) {
   2873         destroy();
   2874         return;
   2875     }
   2876 
   2877     RenderObject* destroyRoot = this;
   2878     for (RenderObject* destroyRootParent = destroyRoot->parent(); destroyRootParent && destroyRootParent->isAnonymous(); destroyRoot = destroyRootParent, destroyRootParent = destroyRootParent->parent()) {
   2879         // Anonymous block continuations are tracked and destroyed elsewhere (see the bottom of RenderBlock::removeChild)
   2880         if (destroyRootParent->isRenderBlock() && toRenderBlock(destroyRootParent)->isAnonymousBlockContinuation())
   2881             break;
   2882         // Render flow threads are tracked by the FlowThreadController, so we can't destroy them here.
   2883         // Column spans are tracked elsewhere.
   2884         if (destroyRootParent->isRenderFlowThread() || destroyRootParent->isAnonymousColumnSpanBlock())
   2885             break;
   2886 
   2887         if (destroyRootParent->slowFirstChild() != this || destroyRootParent->slowLastChild() != this)
   2888             break;
   2889     }
   2890 
   2891     destroyRoot->destroy();
   2892 
   2893     // WARNING: |this| is deleted here.
   2894 }
   2895 
   2896 void RenderObject::destroy()
   2897 {
   2898     willBeDestroyed();
   2899     postDestroy();
   2900 }
   2901 
   2902 void RenderObject::removeShapeImageClient(ShapeValue* shapeValue)
   2903 {
   2904     if (!shapeValue)
   2905         return;
   2906     if (StyleImage* shapeImage = shapeValue->image())
   2907         shapeImage->removeClient(this);
   2908 }
   2909 
   2910 void RenderObject::postDestroy()
   2911 {
   2912     // It seems ugly that this is not in willBeDestroyed().
   2913     if (m_style) {
   2914         for (const FillLayer* bgLayer = m_style->backgroundLayers(); bgLayer; bgLayer = bgLayer->next()) {
   2915             if (StyleImage* backgroundImage = bgLayer->image())
   2916                 backgroundImage->removeClient(this);
   2917         }
   2918 
   2919         for (const FillLayer* maskLayer = m_style->maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
   2920             if (StyleImage* maskImage = maskLayer->image())
   2921                 maskImage->removeClient(this);
   2922         }
   2923 
   2924         if (StyleImage* borderImage = m_style->borderImage().image())
   2925             borderImage->removeClient(this);
   2926 
   2927         if (StyleImage* maskBoxImage = m_style->maskBoxImage().image())
   2928             maskBoxImage->removeClient(this);
   2929 
   2930         removeShapeImageClient(m_style->shapeOutside());
   2931     }
   2932 
   2933     delete this;
   2934 }
   2935 
   2936 PositionWithAffinity RenderObject::positionForPoint(const LayoutPoint&)
   2937 {
   2938     return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM);
   2939 }
   2940 
   2941 void RenderObject::updateDragState(bool dragOn)
   2942 {
   2943     bool valueChanged = (dragOn != isDragging());
   2944     setIsDragging(dragOn);
   2945     if (valueChanged && node()) {
   2946         if (node()->isElementNode() && toElement(node())->childrenOrSiblingsAffectedByDrag())
   2947             node()->setNeedsStyleRecalc(SubtreeStyleChange);
   2948         else if (style()->affectedByDrag())
   2949             node()->setNeedsStyleRecalc(LocalStyleChange);
   2950     }
   2951     for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling())
   2952         curr->updateDragState(dragOn);
   2953 }
   2954 
   2955 CompositingState RenderObject::compositingState() const
   2956 {
   2957     return hasLayer() ? toRenderLayerModelObject(this)->layer()->compositingState() : NotComposited;
   2958 }
   2959 
   2960 CompositingReasons RenderObject::additionalCompositingReasons(CompositingTriggerFlags) const
   2961 {
   2962     return CompositingReasonNone;
   2963 }
   2964 
   2965 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
   2966 {
   2967     bool inside = false;
   2968     if (hitTestFilter != HitTestSelf) {
   2969         // First test the foreground layer (lines and inlines).
   2970         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestForeground);
   2971 
   2972         // Test floats next.
   2973         if (!inside)
   2974             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestFloat);
   2975 
   2976         // Finally test to see if the mouse is in the background (within a child block's background).
   2977         if (!inside)
   2978             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestChildBlockBackgrounds);
   2979     }
   2980 
   2981     // See if the mouse is inside us but not any of our descendants
   2982     if (hitTestFilter != HitTestDescendants && !inside)
   2983         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestBlockBackground);
   2984 
   2985     return inside;
   2986 }
   2987 
   2988 void RenderObject::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
   2989 {
   2990     if (result.innerNode())
   2991         return;
   2992 
   2993     Node* node = this->node();
   2994 
   2995     // If we hit the anonymous renderers inside generated content we should
   2996     // actually hit the generated content so walk up to the PseudoElement.
   2997     if (!node && parent() && parent()->isBeforeOrAfterContent()) {
   2998         for (RenderObject* renderer = parent(); renderer && !node; renderer = renderer->parent())
   2999             node = renderer->node();
   3000     }
   3001 
   3002     if (node) {
   3003         result.setInnerNode(node);
   3004         if (!result.innerNonSharedNode())
   3005             result.setInnerNonSharedNode(node);
   3006         result.setLocalPoint(point);
   3007     }
   3008 }
   3009 
   3010 bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& /*locationInContainer*/, const LayoutPoint& /*accumulatedOffset*/, HitTestAction)
   3011 {
   3012     return false;
   3013 }
   3014 
   3015 void RenderObject::scheduleRelayout()
   3016 {
   3017     if (isRenderView()) {
   3018         FrameView* view = toRenderView(this)->frameView();
   3019         if (view)
   3020             view->scheduleRelayout();
   3021     } else {
   3022         if (isRooted()) {
   3023             if (RenderView* renderView = view()) {
   3024                 if (FrameView* frameView = renderView->frameView())
   3025                     frameView->scheduleRelayoutOfSubtree(this);
   3026             }
   3027         }
   3028     }
   3029 }
   3030 
   3031 void RenderObject::forceLayout()
   3032 {
   3033     setSelfNeedsLayout(true);
   3034     setShouldDoFullPaintInvalidationAfterLayout(true);
   3035     layout();
   3036 }
   3037 
   3038 // FIXME: Does this do anything different than forceLayout given that we don't walk
   3039 // the containing block chain. If not, we should change all callers to use forceLayout.
   3040 void RenderObject::forceChildLayout()
   3041 {
   3042     setNormalChildNeedsLayout(true);
   3043     layout();
   3044 }
   3045 
   3046 enum StyleCacheState {
   3047     Cached,
   3048     Uncached
   3049 };
   3050 
   3051 static PassRefPtr<RenderStyle> firstLineStyleForCachedUncachedType(StyleCacheState type, const RenderObject* renderer, RenderStyle* style)
   3052 {
   3053     const RenderObject* rendererForFirstLineStyle = renderer;
   3054     if (renderer->isBeforeOrAfterContent())
   3055         rendererForFirstLineStyle = renderer->parent();
   3056 
   3057     if (rendererForFirstLineStyle->isRenderBlockFlow() || rendererForFirstLineStyle->isRenderButton()) {
   3058         if (RenderBlock* firstLineBlock = rendererForFirstLineStyle->firstLineBlock()) {
   3059             if (type == Cached)
   3060                 return firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style);
   3061             return firstLineBlock->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE), style, firstLineBlock == renderer ? style : 0);
   3062         }
   3063     } else if (!rendererForFirstLineStyle->isAnonymous() && rendererForFirstLineStyle->isRenderInline()) {
   3064         RenderStyle* parentStyle = rendererForFirstLineStyle->parent()->firstLineStyle();
   3065         if (parentStyle != rendererForFirstLineStyle->parent()->style()) {
   3066             if (type == Cached) {
   3067                 // A first-line style is in effect. Cache a first-line style for ourselves.
   3068                 rendererForFirstLineStyle->style()->setHasPseudoStyle(FIRST_LINE_INHERITED);
   3069                 return rendererForFirstLineStyle->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle);
   3070             }
   3071             return rendererForFirstLineStyle->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE_INHERITED), parentStyle, style);
   3072         }
   3073     }
   3074     return nullptr;
   3075 }
   3076 
   3077 PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const
   3078 {
   3079     if (!document().styleEngine()->usesFirstLineRules())
   3080         return nullptr;
   3081 
   3082     ASSERT(!isText());
   3083 
   3084     return firstLineStyleForCachedUncachedType(Uncached, this, style);
   3085 }
   3086 
   3087 RenderStyle* RenderObject::cachedFirstLineStyle() const
   3088 {
   3089     ASSERT(document().styleEngine()->usesFirstLineRules());
   3090 
   3091     if (RefPtr<RenderStyle> style = firstLineStyleForCachedUncachedType(Cached, isText() ? parent() : this, m_style.get()))
   3092         return style.get();
   3093 
   3094     return m_style.get();
   3095 }
   3096 
   3097 RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
   3098 {
   3099     if (pseudo < FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
   3100         return 0;
   3101 
   3102     RenderStyle* cachedStyle = style()->getCachedPseudoStyle(pseudo);
   3103     if (cachedStyle)
   3104         return cachedStyle;
   3105 
   3106     RefPtr<RenderStyle> result = getUncachedPseudoStyle(PseudoStyleRequest(pseudo), parentStyle);
   3107     if (result)
   3108         return style()->addCachedPseudoStyle(result.release());
   3109     return 0;
   3110 }
   3111 
   3112 PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, RenderStyle* ownStyle) const
   3113 {
   3114     if (pseudoStyleRequest.pseudoId < FIRST_INTERNAL_PSEUDOID && !ownStyle && !style()->hasPseudoStyle(pseudoStyleRequest.pseudoId))
   3115         return nullptr;
   3116 
   3117     if (!parentStyle) {
   3118         ASSERT(!ownStyle);
   3119         parentStyle = style();
   3120     }
   3121 
   3122     if (!node())
   3123         return nullptr;
   3124 
   3125     Element* element = Traversal<Element>::firstAncestorOrSelf(*node());
   3126     if (!element)
   3127         return nullptr;
   3128 
   3129     if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) {
   3130         RefPtr<RenderStyle> result = document().ensureStyleResolver().styleForElement(element, parentStyle, DisallowStyleSharing);
   3131         result->setStyleType(FIRST_LINE_INHERITED);
   3132         return result.release();
   3133     }
   3134 
   3135     return document().ensureStyleResolver().pseudoStyleForElement(element, pseudoStyleRequest, parentStyle);
   3136 }
   3137 
   3138 PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyleFromParentOrShadowHost() const
   3139 {
   3140     if (!node())
   3141         return nullptr;
   3142 
   3143     if (ShadowRoot* root = node()->containingShadowRoot()) {
   3144         if (root->type() == ShadowRoot::UserAgentShadowRoot) {
   3145             if (Element* shadowHost = node()->shadowHost()) {
   3146                 return shadowHost->renderer()->getUncachedPseudoStyle(PseudoStyleRequest(SELECTION));
   3147             }
   3148         }
   3149     }
   3150 
   3151     return getUncachedPseudoStyle(PseudoStyleRequest(SELECTION));
   3152 }
   3153 
   3154 bool RenderObject::hasBlendMode() const
   3155 {
   3156     return RuntimeEnabledFeatures::cssCompositingEnabled() && style() && style()->hasBlendMode();
   3157 }
   3158 
   3159 void RenderObject::getTextDecorations(unsigned decorations, AppliedTextDecoration& underline, AppliedTextDecoration& overline, AppliedTextDecoration& linethrough, bool quirksMode, bool firstlineStyle)
   3160 {
   3161     RenderObject* curr = this;
   3162     RenderStyle* styleToUse = 0;
   3163     unsigned currDecs = TextDecorationNone;
   3164     Color resultColor;
   3165     TextDecorationStyle resultStyle;
   3166     do {
   3167         styleToUse = curr->style(firstlineStyle);
   3168         currDecs = styleToUse->textDecoration();
   3169         currDecs &= decorations;
   3170         resultColor = styleToUse->visitedDependentDecorationColor();
   3171         resultStyle = styleToUse->textDecorationStyle();
   3172         // Parameter 'decorations' is cast as an int to enable the bitwise operations below.
   3173         if (currDecs) {
   3174             if (currDecs & TextDecorationUnderline) {
   3175                 decorations &= ~TextDecorationUnderline;
   3176                 underline.color = resultColor;
   3177                 underline.style = resultStyle;
   3178             }
   3179             if (currDecs & TextDecorationOverline) {
   3180                 decorations &= ~TextDecorationOverline;
   3181                 overline.color = resultColor;
   3182                 overline.style = resultStyle;
   3183             }
   3184             if (currDecs & TextDecorationLineThrough) {
   3185                 decorations &= ~TextDecorationLineThrough;
   3186                 linethrough.color = resultColor;
   3187                 linethrough.style = resultStyle;
   3188             }
   3189         }
   3190         if (curr->isRubyText())
   3191             return;
   3192         curr = curr->parent();
   3193         if (curr && curr->isAnonymousBlock() && toRenderBlock(curr)->continuation())
   3194             curr = toRenderBlock(curr)->continuation();
   3195     } while (curr && decorations && (!quirksMode || !curr->node() || (!isHTMLAnchorElement(*curr->node()) && !isHTMLFontElement(*curr->node()))));
   3196 
   3197     // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
   3198     if (decorations && curr) {
   3199         styleToUse = curr->style(firstlineStyle);
   3200         resultColor = styleToUse->visitedDependentDecorationColor();
   3201         if (decorations & TextDecorationUnderline) {
   3202             underline.color = resultColor;
   3203             underline.style = resultStyle;
   3204         }
   3205         if (decorations & TextDecorationOverline) {
   3206             overline.color = resultColor;
   3207             overline.style = resultStyle;
   3208         }
   3209         if (decorations & TextDecorationLineThrough) {
   3210             linethrough.color = resultColor;
   3211             linethrough.style = resultStyle;
   3212         }
   3213     }
   3214 }
   3215 
   3216 void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
   3217 {
   3218     // Convert the style regions to absolute coordinates.
   3219     if (style()->visibility() != VISIBLE || !isBox())
   3220         return;
   3221 
   3222     if (style()->getDraggableRegionMode() == DraggableRegionNone)
   3223         return;
   3224 
   3225     RenderBox* box = toRenderBox(this);
   3226     FloatRect localBounds(FloatPoint(), FloatSize(box->width().toFloat(), box->height().toFloat()));
   3227     FloatRect absBounds = localToAbsoluteQuad(localBounds).boundingBox();
   3228 
   3229     AnnotatedRegionValue region;
   3230     region.draggable = style()->getDraggableRegionMode() == DraggableRegionDrag;
   3231     region.bounds = LayoutRect(absBounds);
   3232     regions.append(region);
   3233 }
   3234 
   3235 void RenderObject::collectAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
   3236 {
   3237     // RenderTexts don't have their own style, they just use their parent's style,
   3238     // so we don't want to include them.
   3239     if (isText())
   3240         return;
   3241 
   3242     addAnnotatedRegions(regions);
   3243     for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling())
   3244         curr->collectAnnotatedRegions(regions);
   3245 }
   3246 
   3247 bool RenderObject::willRenderImage(ImageResource*)
   3248 {
   3249     // Without visibility we won't render (and therefore don't care about animation).
   3250     if (style()->visibility() != VISIBLE)
   3251         return false;
   3252 
   3253     // We will not render a new image when Active DOM is suspended
   3254     if (document().activeDOMObjectsAreSuspended())
   3255         return false;
   3256 
   3257     // If we're not in a window (i.e., we're dormant from being in a background tab)
   3258     // then we don't want to render either.
   3259     return document().view()->isVisible();
   3260 }
   3261 
   3262 int RenderObject::caretMinOffset() const
   3263 {
   3264     return 0;
   3265 }
   3266 
   3267 int RenderObject::caretMaxOffset() const
   3268 {
   3269     if (isReplaced())
   3270         return node() ? max(1U, node()->countChildren()) : 1;
   3271     if (isHR())
   3272         return 1;
   3273     return 0;
   3274 }
   3275 
   3276 int RenderObject::previousOffset(int current) const
   3277 {
   3278     return current - 1;
   3279 }
   3280 
   3281 int RenderObject::previousOffsetForBackwardDeletion(int current) const
   3282 {
   3283     return current - 1;
   3284 }
   3285 
   3286 int RenderObject::nextOffset(int current) const
   3287 {
   3288     return current + 1;
   3289 }
   3290 
   3291 bool RenderObject::isInert() const
   3292 {
   3293     const RenderObject* renderer = this;
   3294     while (!renderer->node())
   3295         renderer = renderer->parent();
   3296     return renderer->node()->isInert();
   3297 }
   3298 
   3299 // touch-action applies to all elements with both width AND height properties.
   3300 // According to the CSS Box Model Spec (http://dev.w3.org/csswg/css-box/#the-width-and-height-properties)
   3301 // width applies to all elements but non-replaced inline elements, table rows, and row groups and
   3302 // height applies to all elements but non-replaced inline elements, table columns, and column groups.
   3303 bool RenderObject::supportsTouchAction() const
   3304 {
   3305     if (isInline() && !isReplaced())
   3306         return false;
   3307     if (isTableRow() || isRenderTableCol())
   3308         return false;
   3309 
   3310     return true;
   3311 }
   3312 
   3313 void RenderObject::imageChanged(ImageResource* image, const IntRect* rect)
   3314 {
   3315     imageChanged(static_cast<WrappedImagePtr>(image), rect);
   3316 }
   3317 
   3318 Element* RenderObject::offsetParent() const
   3319 {
   3320     if (isDocumentElement() || isBody())
   3321         return 0;
   3322 
   3323     if (isOutOfFlowPositioned() && style()->position() == FixedPosition)
   3324         return 0;
   3325 
   3326     // If A is an area HTML element which has a map HTML element somewhere in the ancestor
   3327     // chain return the nearest ancestor map HTML element and stop this algorithm.
   3328     // FIXME: Implement!
   3329 
   3330     float effectiveZoom = style()->effectiveZoom();
   3331     Node* node = 0;
   3332     for (RenderObject* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
   3333         // Spec: http://www.w3.org/TR/cssom-view/#offset-attributes
   3334 
   3335         node = ancestor->node();
   3336 
   3337         if (!node)
   3338             continue;
   3339 
   3340         if (ancestor->isPositioned())
   3341             break;
   3342 
   3343         if (isHTMLBodyElement(*node))
   3344             break;
   3345 
   3346         if (!isPositioned() && (isHTMLTableElement(*node) || isHTMLTableCellElement(*node)))
   3347             break;
   3348 
   3349         // Webkit specific extension where offsetParent stops at zoom level changes.
   3350         if (effectiveZoom != ancestor->style()->effectiveZoom())
   3351             break;
   3352     }
   3353 
   3354     return node && node->isElementNode() ? toElement(node) : 0;
   3355 }
   3356 
   3357 PositionWithAffinity RenderObject::createPositionWithAffinity(int offset, EAffinity affinity)
   3358 {
   3359     // If this is a non-anonymous renderer in an editable area, then it's simple.
   3360     if (Node* node = nonPseudoNode()) {
   3361         if (!node->rendererIsEditable()) {
   3362             // If it can be found, we prefer a visually equivalent position that is editable.
   3363             Position position = createLegacyEditingPosition(node, offset);
   3364             Position candidate = position.downstream(CanCrossEditingBoundary);
   3365             if (candidate.deprecatedNode()->rendererIsEditable())
   3366                 return PositionWithAffinity(candidate, affinity);
   3367             candidate = position.upstream(CanCrossEditingBoundary);
   3368             if (candidate.deprecatedNode()->rendererIsEditable())
   3369                 return PositionWithAffinity(candidate, affinity);
   3370         }
   3371         // FIXME: Eliminate legacy editing positions
   3372         return PositionWithAffinity(createLegacyEditingPosition(node, offset), affinity);
   3373     }
   3374 
   3375     // We don't want to cross the boundary between editable and non-editable
   3376     // regions of the document, but that is either impossible or at least
   3377     // extremely unlikely in any normal case because we stop as soon as we
   3378     // find a single non-anonymous renderer.
   3379 
   3380     // Find a nearby non-anonymous renderer.
   3381     RenderObject* child = this;
   3382     while (RenderObject* parent = child->parent()) {
   3383         // Find non-anonymous content after.
   3384         RenderObject* renderer = child;
   3385         while ((renderer = renderer->nextInPreOrder(parent))) {
   3386             if (Node* node = renderer->nonPseudoNode())
   3387                 return PositionWithAffinity(firstPositionInOrBeforeNode(node), DOWNSTREAM);
   3388         }
   3389 
   3390         // Find non-anonymous content before.
   3391         renderer = child;
   3392         while ((renderer = renderer->previousInPreOrder())) {
   3393             if (renderer == parent)
   3394                 break;
   3395             if (Node* node = renderer->nonPseudoNode())
   3396                 return PositionWithAffinity(lastPositionInOrAfterNode(node), DOWNSTREAM);
   3397         }
   3398 
   3399         // Use the parent itself unless it too is anonymous.
   3400         if (Node* node = parent->nonPseudoNode())
   3401             return PositionWithAffinity(firstPositionInOrBeforeNode(node), DOWNSTREAM);
   3402 
   3403         // Repeat at the next level up.
   3404         child = parent;
   3405     }
   3406 
   3407     // Everything was anonymous. Give up.
   3408     return PositionWithAffinity();
   3409 }
   3410 
   3411 PositionWithAffinity RenderObject::createPositionWithAffinity(const Position& position)
   3412 {
   3413     if (position.isNotNull())
   3414         return PositionWithAffinity(position);
   3415 
   3416     ASSERT(!node());
   3417     return createPositionWithAffinity(0, DOWNSTREAM);
   3418 }
   3419 
   3420 CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
   3421 {
   3422     return SetCursorBasedOnStyle;
   3423 }
   3424 
   3425 bool RenderObject::canUpdateSelectionOnRootLineBoxes()
   3426 {
   3427     if (needsLayout())
   3428         return false;
   3429 
   3430     RenderBlock* containingBlock = this->containingBlock();
   3431     return containingBlock ? !containingBlock->needsLayout() : true;
   3432 }
   3433 
   3434 // We only create "generated" child renderers like one for first-letter if:
   3435 // - the firstLetterBlock can have children in the DOM and
   3436 // - the block doesn't have any special assumption on its text children.
   3437 // This correctly prevents form controls from having such renderers.
   3438 bool RenderObject::canHaveGeneratedChildren() const
   3439 {
   3440     return canHaveChildren();
   3441 }
   3442 
   3443 void RenderObject::setNeedsBoundariesUpdate()
   3444 {
   3445     if (RenderObject* renderer = parent())
   3446         renderer->setNeedsBoundariesUpdate();
   3447 }
   3448 
   3449 FloatRect RenderObject::objectBoundingBox() const
   3450 {
   3451     ASSERT_NOT_REACHED();
   3452     return FloatRect();
   3453 }
   3454 
   3455 FloatRect RenderObject::strokeBoundingBox() const
   3456 {
   3457     ASSERT_NOT_REACHED();
   3458     return FloatRect();
   3459 }
   3460 
   3461 // Returns the smallest rectangle enclosing all of the painted content
   3462 // respecting clipping, masking, filters, opacity, stroke-width and markers
   3463 FloatRect RenderObject::paintInvalidationRectInLocalCoordinates() const
   3464 {
   3465     ASSERT_NOT_REACHED();
   3466     return FloatRect();
   3467 }
   3468 
   3469 AffineTransform RenderObject::localTransform() const
   3470 {
   3471     static const AffineTransform identity;
   3472     return identity;
   3473 }
   3474 
   3475 const AffineTransform& RenderObject::localToParentTransform() const
   3476 {
   3477     static const AffineTransform identity;
   3478     return identity;
   3479 }
   3480 
   3481 bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
   3482 {
   3483     ASSERT_NOT_REACHED();
   3484     return false;
   3485 }
   3486 
   3487 bool RenderObject::isRelayoutBoundaryForInspector() const
   3488 {
   3489     return objectIsRelayoutBoundary(this);
   3490 }
   3491 
   3492 void RenderObject::clearPaintInvalidationState()
   3493 {
   3494     setShouldDoFullPaintInvalidationAfterLayout(false);
   3495     setShouldDoFullPaintInvalidationIfSelfPaintingLayer(false);
   3496     setOnlyNeededPositionedMovementLayout(false);
   3497     setShouldInvalidateOverflowForPaint(false);
   3498     setLayoutDidGetCalled(false);
   3499     setMayNeedPaintInvalidation(false);
   3500 }
   3501 
   3502 bool RenderObject::isAllowedToModifyRenderTreeStructure(Document& document)
   3503 {
   3504     return DeprecatedDisableModifyRenderTreeStructureAsserts::canModifyRenderTreeStateInAnyState()
   3505         || document.lifecycle().stateAllowsRenderTreeMutations();
   3506 }
   3507 
   3508 DeprecatedDisableModifyRenderTreeStructureAsserts::DeprecatedDisableModifyRenderTreeStructureAsserts()
   3509     : m_disabler(gModifyRenderTreeStructureAnyState, true)
   3510 {
   3511 }
   3512 
   3513 bool DeprecatedDisableModifyRenderTreeStructureAsserts::canModifyRenderTreeStateInAnyState()
   3514 {
   3515     return gModifyRenderTreeStructureAnyState;
   3516 }
   3517 
   3518 } // namespace WebCore
   3519 
   3520 #ifndef NDEBUG
   3521 
   3522 void showTree(const WebCore::RenderObject* object)
   3523 {
   3524     if (object)
   3525         object->showTreeForThis();
   3526 }
   3527 
   3528 void showLineTree(const WebCore::RenderObject* object)
   3529 {
   3530     if (object)
   3531         object->showLineTreeForThis();
   3532 }
   3533 
   3534 void showRenderTree(const WebCore::RenderObject* object1)
   3535 {
   3536     showRenderTree(object1, 0);
   3537 }
   3538 
   3539 void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2)
   3540 {
   3541     if (object1) {
   3542         const WebCore::RenderObject* root = object1;
   3543         while (root->parent())
   3544             root = root->parent();
   3545         root->showRenderTreeAndMark(object1, "*", object2, "-", 0);
   3546     }
   3547 }
   3548 
   3549 #endif
   3550