Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      3  *
      4  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
      5  *
      6  * Other contributors:
      7  *   Robert O'Callahan <roc+@cs.cmu.edu>
      8  *   David Baron <dbaron (at) fas.harvard.edu>
      9  *   Christian Biesinger <cbiesinger (at) web.de>
     10  *   Randall Jesup <rjesup (at) wgate.com>
     11  *   Roland Mainz <roland.mainz (at) informatik.med.uni-giessen.de>
     12  *   Josh Soref <timeless (at) mac.com>
     13  *   Boris Zbarsky <bzbarsky (at) mit.edu>
     14  *
     15  * This library is free software; you can redistribute it and/or
     16  * modify it under the terms of the GNU Lesser General Public
     17  * License as published by the Free Software Foundation; either
     18  * version 2.1 of the License, or (at your option) any later version.
     19  *
     20  * This library is distributed in the hope that it will be useful,
     21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23  * Lesser General Public License for more details.
     24  *
     25  * You should have received a copy of the GNU Lesser General Public
     26  * License along with this library; if not, write to the Free Software
     27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     28  *
     29  * Alternatively, the contents of this file may be used under the terms
     30  * of either the Mozilla Public License Version 1.1, found at
     31  * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
     32  * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
     33  * (the "GPL"), in which case the provisions of the MPL or the GPL are
     34  * applicable instead of those above.  If you wish to allow use of your
     35  * version of this file only under the terms of one of those two
     36  * licenses (the MPL or the GPL) and not to allow others to use your
     37  * version of this file under the LGPL, indicate your decision by
     38  * deletingthe provisions above and replace them with the notice and
     39  * other provisions required by the MPL or the GPL, as the case may be.
     40  * If you do not delete the provisions above, a recipient may use your
     41  * version of this file under any of the LGPL, the MPL or the GPL.
     42  */
     43 
     44 #include "config.h"
     45 #include "RenderLayer.h"
     46 
     47 #include "ColumnInfo.h"
     48 #include "CSSPropertyNames.h"
     49 #include "CSSStyleDeclaration.h"
     50 #include "CSSStyleSelector.h"
     51 #include "Chrome.h"
     52 #include "Document.h"
     53 #include "EventHandler.h"
     54 #include "EventQueue.h"
     55 #include "FloatPoint3D.h"
     56 #include "FloatRect.h"
     57 #include "FocusController.h"
     58 #include "Frame.h"
     59 #include "FrameTree.h"
     60 #include "FrameView.h"
     61 #include "Gradient.h"
     62 #include "GraphicsContext.h"
     63 #include "HTMLFrameOwnerElement.h"
     64 #include "HTMLNames.h"
     65 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
     66 #include "HTMLTextAreaElement.h"
     67 #endif
     68 #include "HitTestRequest.h"
     69 #include "HitTestResult.h"
     70 #include "OverflowEvent.h"
     71 #include "OverlapTestRequestClient.h"
     72 #include "Page.h"
     73 #include "PlatformMouseEvent.h"
     74 #include "RenderArena.h"
     75 #include "RenderInline.h"
     76 #include "RenderMarquee.h"
     77 #include "RenderReplica.h"
     78 #include "RenderScrollbar.h"
     79 #include "RenderScrollbarPart.h"
     80 #include "RenderTheme.h"
     81 #include "RenderTreeAsText.h"
     82 #include "RenderView.h"
     83 #include "ScaleTransformOperation.h"
     84 #include "Scrollbar.h"
     85 #include "ScrollbarTheme.h"
     86 #include "SelectionController.h"
     87 #include "TextStream.h"
     88 #include "TransformState.h"
     89 #include "TransformationMatrix.h"
     90 #include "TranslateTransformOperation.h"
     91 #include <wtf/StdLibExtras.h>
     92 #include <wtf/UnusedParam.h>
     93 #include <wtf/text/CString.h>
     94 
     95 #if USE(ACCELERATED_COMPOSITING)
     96 #include "RenderLayerBacking.h"
     97 #include "RenderLayerCompositor.h"
     98 #endif
     99 
    100 #if ENABLE(SVG)
    101 #include "SVGNames.h"
    102 #endif
    103 
    104 #define MIN_INTERSECT_FOR_REVEAL 32
    105 
    106 using namespace std;
    107 
    108 namespace WebCore {
    109 
    110 using namespace HTMLNames;
    111 
    112 const int MinimumWidthWhileResizing = 100;
    113 const int MinimumHeightWhileResizing = 40;
    114 
    115 void* ClipRects::operator new(size_t sz, RenderArena* renderArena) throw()
    116 {
    117     return renderArena->allocate(sz);
    118 }
    119 
    120 void ClipRects::operator delete(void* ptr, size_t sz)
    121 {
    122     // Stash size where destroy can find it.
    123     *(size_t *)ptr = sz;
    124 }
    125 
    126 void ClipRects::destroy(RenderArena* renderArena)
    127 {
    128     delete this;
    129 
    130     // Recover the size left there for us by operator delete and free the memory.
    131     renderArena->free(*(size_t *)this, this);
    132 }
    133 
    134 RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
    135     : m_renderer(renderer)
    136     , m_parent(0)
    137     , m_previous(0)
    138     , m_next(0)
    139     , m_first(0)
    140     , m_last(0)
    141     , m_relX(0)
    142     , m_relY(0)
    143     , m_x(0)
    144     , m_y(0)
    145     , m_width(0)
    146     , m_height(0)
    147     , m_scrollX(0)
    148     , m_scrollY(0)
    149     , m_scrollLeftOverflow(0)
    150     , m_scrollTopOverflow(0)
    151     , m_scrollWidth(0)
    152     , m_scrollHeight(0)
    153     , m_inResizeMode(false)
    154     , m_posZOrderList(0)
    155     , m_negZOrderList(0)
    156     , m_normalFlowList(0)
    157     , m_clipRects(0)
    158 #ifndef NDEBUG
    159     , m_clipRectsRoot(0)
    160 #endif
    161     , m_scrollDimensionsDirty(true)
    162     , m_zOrderListsDirty(true)
    163     , m_normalFlowListDirty(true)
    164     , m_isNormalFlowOnly(shouldBeNormalFlowOnly())
    165     , m_usedTransparency(false)
    166     , m_paintingInsideReflection(false)
    167     , m_inOverflowRelayout(false)
    168     , m_needsFullRepaint(false)
    169     , m_overflowStatusDirty(true)
    170     , m_visibleContentStatusDirty(true)
    171     , m_hasVisibleContent(false)
    172     , m_visibleDescendantStatusDirty(false)
    173     , m_hasVisibleDescendant(false)
    174     , m_isPaginated(false)
    175     , m_3DTransformedDescendantStatusDirty(true)
    176     , m_has3DTransformedDescendant(false)
    177 #if USE(ACCELERATED_COMPOSITING)
    178     , m_hasCompositingDescendant(false)
    179     , m_mustOverlapCompositedLayers(false)
    180 #if ENABLE(COMPOSITED_FIXED_ELEMENTS)
    181     , m_shouldComposite(false)
    182 #endif
    183 #endif
    184     , m_containsDirtyOverlayScrollbars(false)
    185 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    186     , m_hasOverflowScroll(false)
    187 #endif
    188     , m_marquee(0)
    189     , m_staticInlinePosition(0)
    190     , m_staticBlockPosition(0)
    191     , m_reflection(0)
    192     , m_scrollCorner(0)
    193     , m_resizer(0)
    194 {
    195     ScrollableArea::setConstrainsScrollingToContentEdge(false);
    196 
    197     if (!renderer->firstChild() && renderer->style()) {
    198         m_visibleContentStatusDirty = false;
    199         m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
    200     }
    201 
    202     if (Frame* frame = renderer->frame()) {
    203         if (Page* page = frame->page()) {
    204             m_page = page;
    205             m_page->addScrollableArea(this);
    206         }
    207     }
    208 }
    209 
    210 RenderLayer::~RenderLayer()
    211 {
    212     if (inResizeMode() && !renderer()->documentBeingDestroyed()) {
    213         if (Frame* frame = renderer()->frame())
    214             frame->eventHandler()->resizeLayerDestroyed();
    215     }
    216 
    217     if (m_page)
    218         m_page->removeScrollableArea(this);
    219 
    220     destroyScrollbar(HorizontalScrollbar);
    221     destroyScrollbar(VerticalScrollbar);
    222 
    223     if (m_reflection)
    224         removeReflection();
    225 
    226     // Child layers will be deleted by their corresponding render objects, so
    227     // we don't need to delete them ourselves.
    228 
    229     delete m_posZOrderList;
    230     delete m_negZOrderList;
    231     delete m_normalFlowList;
    232     delete m_marquee;
    233 
    234 #if USE(ACCELERATED_COMPOSITING)
    235     clearBacking();
    236 #endif
    237 
    238     // Make sure we have no lingering clip rects.
    239     ASSERT(!m_clipRects);
    240 
    241     if (m_scrollCorner)
    242         m_scrollCorner->destroy();
    243     if (m_resizer)
    244         m_resizer->destroy();
    245 }
    246 
    247 #if USE(ACCELERATED_COMPOSITING)
    248 RenderLayerCompositor* RenderLayer::compositor() const
    249 {
    250     ASSERT(renderer()->view());
    251     return renderer()->view()->compositor();
    252 }
    253 
    254 void RenderLayer::contentChanged(ContentChangeType changeType)
    255 {
    256     // This can get called when video becomes accelerated, so the layers may change.
    257     if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged) && compositor()->updateLayerCompositingState(this))
    258         compositor()->setCompositingLayersNeedRebuild();
    259 
    260     if (m_backing)
    261         m_backing->contentChanged(changeType);
    262 }
    263 #endif // USE(ACCELERATED_COMPOSITING)
    264 
    265 bool RenderLayer::hasAcceleratedCompositing() const
    266 {
    267 #if USE(ACCELERATED_COMPOSITING)
    268     return compositor()->hasAcceleratedCompositing();
    269 #else
    270     return false;
    271 #endif
    272 }
    273 
    274 bool RenderLayer::canRender3DTransforms() const
    275 {
    276 #if USE(ACCELERATED_COMPOSITING)
    277     return compositor()->canRender3DTransforms();
    278 #else
    279     return false;
    280 #endif
    281 }
    282 
    283 void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags, IntPoint* cachedOffset)
    284 {
    285     updateLayerPosition(); // For relpositioned layers or non-positioned layers,
    286                            // we need to keep in sync, since we may have shifted relative
    287                            // to our parent layer.
    288     IntPoint oldCachedOffset;
    289     if (cachedOffset) {
    290         // We can't cache our offset to the repaint container if the mapping is anything more complex than a simple translation
    291         bool disableOffsetCache = renderer()->hasColumns() || renderer()->hasTransform() || isComposited();
    292 #if ENABLE(SVG)
    293         disableOffsetCache = disableOffsetCache || renderer()->isSVGRoot();
    294 #endif
    295         if (disableOffsetCache)
    296             cachedOffset = 0; // If our cached offset is invalid make sure it's not passed to any of our children
    297         else {
    298             oldCachedOffset = *cachedOffset;
    299             // Frequently our parent layer's renderer will be the same as our renderer's containing block.  In that case,
    300             // we just update the cache using our offset to our parent (which is m_x / m_y).  Otherwise, regenerated cached
    301             // offsets to the root from the render tree.
    302             if (!m_parent || m_parent->renderer() == renderer()->containingBlock())
    303                 cachedOffset->move(m_x, m_y); // Fast case
    304             else {
    305                 int x = 0;
    306                 int y = 0;
    307                 convertToLayerCoords(root(), x, y);
    308                 *cachedOffset = IntPoint(x, y);
    309             }
    310         }
    311     }
    312 
    313     int x = 0;
    314     int y = 0;
    315     if (cachedOffset) {
    316         x += cachedOffset->x();
    317         y += cachedOffset->y();
    318 #ifndef NDEBUG
    319         int nonCachedX = 0;
    320         int nonCachedY = 0;
    321         convertToLayerCoords(root(), nonCachedX, nonCachedY);
    322         ASSERT(x == nonCachedX);
    323         ASSERT(y == nonCachedY);
    324 #endif
    325     } else
    326         convertToLayerCoords(root(), x, y);
    327     positionOverflowControls(x, y);
    328 
    329     updateVisibilityStatus();
    330 
    331     if (flags & UpdatePagination)
    332         updatePagination();
    333     else
    334         m_isPaginated = false;
    335 
    336     if (m_hasVisibleContent) {
    337         RenderView* view = renderer()->view();
    338         ASSERT(view);
    339         // FIXME: Optimize using LayoutState and remove the disableLayoutState() call
    340         // from updateScrollInfoAfterLayout().
    341         ASSERT(!view->layoutStateEnabled());
    342 
    343         RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
    344         IntRect newRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
    345         IntRect newOutlineBox = renderer()->outlineBoundsForRepaint(repaintContainer, cachedOffset);
    346         // FIXME: Should ASSERT that value calculated for newOutlineBox using the cached offset is the same
    347         // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
    348         if (flags & CheckForRepaint) {
    349             if (view && !view->printing()) {
    350                 if (m_needsFullRepaint) {
    351                     renderer()->repaintUsingContainer(repaintContainer, m_repaintRect);
    352                     if (newRect != m_repaintRect)
    353                         renderer()->repaintUsingContainer(repaintContainer, newRect);
    354                 } else
    355                     renderer()->repaintAfterLayoutIfNeeded(repaintContainer, m_repaintRect, m_outlineBox, &newRect, &newOutlineBox);
    356             }
    357         }
    358         m_repaintRect = newRect;
    359         m_outlineBox = newOutlineBox;
    360     } else {
    361         m_repaintRect = IntRect();
    362         m_outlineBox = IntRect();
    363     }
    364 
    365     m_needsFullRepaint = false;
    366 
    367     // Go ahead and update the reflection's position and size.
    368     if (m_reflection)
    369         m_reflection->layout();
    370 
    371 #if USE(ACCELERATED_COMPOSITING)
    372     // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
    373     bool isUpdateRoot = (flags & IsCompositingUpdateRoot);
    374     if (isComposited())
    375         flags &= ~IsCompositingUpdateRoot;
    376 #endif
    377 
    378     if (renderer()->hasColumns())
    379         flags |= UpdatePagination;
    380 
    381     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
    382         child->updateLayerPositions(flags, cachedOffset);
    383 
    384 #if USE(ACCELERATED_COMPOSITING)
    385     if ((flags & UpdateCompositingLayers) && isComposited())
    386         backing()->updateAfterLayout(RenderLayerBacking::CompositingChildren, isUpdateRoot);
    387 #endif
    388 
    389     // With all our children positioned, now update our marquee if we need to.
    390     if (m_marquee)
    391         m_marquee->updateMarqueePosition();
    392 
    393     if (cachedOffset)
    394         *cachedOffset = oldCachedOffset;
    395 }
    396 
    397 IntRect RenderLayer::repaintRectIncludingDescendants() const
    398 {
    399     IntRect repaintRect = m_repaintRect;
    400     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
    401         repaintRect.unite(child->repaintRectIncludingDescendants());
    402     return repaintRect;
    403 }
    404 
    405 void RenderLayer::computeRepaintRects()
    406 {
    407     RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
    408     m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
    409     m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer);
    410 }
    411 
    412 void RenderLayer::updateRepaintRectsAfterScroll(bool fixed)
    413 {
    414     if (fixed || renderer()->style()->position() == FixedPosition) {
    415         computeRepaintRects();
    416         fixed = true;
    417     } else if (renderer()->hasTransform() && !renderer()->isRenderView()) {
    418         // Transforms act as fixed position containers, so nothing inside a
    419         // transformed element can be fixed relative to the viewport if the
    420         // transformed element is not fixed itself or child of a fixed element.
    421         return;
    422     }
    423 
    424     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
    425         child->updateRepaintRectsAfterScroll(fixed);
    426 }
    427 
    428 void RenderLayer::updateTransform()
    429 {
    430     // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
    431     // so check style too.
    432     bool hasTransform = renderer()->hasTransform() && renderer()->style()->hasTransform();
    433     bool had3DTransform = has3DTransform();
    434 
    435     bool hadTransform = m_transform;
    436     if (hasTransform != hadTransform) {
    437         if (hasTransform)
    438             m_transform.set(new TransformationMatrix);
    439         else
    440             m_transform.clear();
    441     }
    442 
    443     if (hasTransform) {
    444         RenderBox* box = renderBox();
    445         ASSERT(box);
    446         m_transform->makeIdentity();
    447         box->style()->applyTransform(*m_transform, box->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
    448         makeMatrixRenderable(*m_transform, canRender3DTransforms());
    449     }
    450 
    451     if (had3DTransform != has3DTransform())
    452         dirty3DTransformedDescendantStatus();
    453 }
    454 
    455 TransformationMatrix RenderLayer::currentTransform() const
    456 {
    457     if (!m_transform)
    458         return TransformationMatrix();
    459 
    460 #if USE(ACCELERATED_COMPOSITING)
    461     if (renderer()->style()->isRunningAcceleratedAnimation()) {
    462         TransformationMatrix currTransform;
    463         RefPtr<RenderStyle> style = renderer()->animation()->getAnimatedStyleForRenderer(renderer());
    464         style->applyTransform(currTransform, renderBox()->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
    465         makeMatrixRenderable(currTransform, canRender3DTransforms());
    466         return currTransform;
    467     }
    468 #endif
    469 
    470     return *m_transform;
    471 }
    472 
    473 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
    474 {
    475     if (!m_transform)
    476         return TransformationMatrix();
    477 
    478     if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
    479         TransformationMatrix matrix = *m_transform;
    480         makeMatrixRenderable(matrix, false /* flatten 3d */);
    481         return matrix;
    482     }
    483 
    484     return *m_transform;
    485 }
    486 
    487 static bool checkContainingBlockChainForPagination(RenderBoxModelObject* renderer, RenderBox* ancestorColumnsRenderer)
    488 {
    489     RenderView* view = renderer->view();
    490     RenderBoxModelObject* prevBlock = renderer;
    491     RenderBlock* containingBlock;
    492     for (containingBlock = renderer->containingBlock();
    493          containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer;
    494          containingBlock = containingBlock->containingBlock())
    495         prevBlock = containingBlock;
    496 
    497     // If the columns block wasn't in our containing block chain, then we aren't paginated by it.
    498     if (containingBlock != ancestorColumnsRenderer)
    499         return false;
    500 
    501     // If the previous block is absolutely positioned, then we can't be paginated by the columns block.
    502     if (prevBlock->isPositioned())
    503         return false;
    504 
    505     // Otherwise we are paginated by the columns block.
    506     return true;
    507 }
    508 
    509 void RenderLayer::updatePagination()
    510 {
    511     m_isPaginated = false;
    512     if (isComposited() || !parent())
    513         return; // FIXME: We will have to deal with paginated compositing layers someday.
    514                 // FIXME: For now the RenderView can't be paginated.  Eventually printing will move to a model where it is though.
    515 
    516     if (isNormalFlowOnly()) {
    517         m_isPaginated = parent()->renderer()->hasColumns();
    518         return;
    519     }
    520 
    521     // If we're not normal flow, then we need to look for a multi-column object between us and our stacking context.
    522     RenderLayer* ancestorStackingContext = stackingContext();
    523     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
    524         if (curr->renderer()->hasColumns()) {
    525             m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox());
    526             return;
    527         }
    528         if (curr == ancestorStackingContext)
    529             return;
    530     }
    531 }
    532 
    533 void RenderLayer::setHasVisibleContent(bool b)
    534 {
    535     if (m_hasVisibleContent == b && !m_visibleContentStatusDirty)
    536         return;
    537     m_visibleContentStatusDirty = false;
    538     m_hasVisibleContent = b;
    539     if (m_hasVisibleContent) {
    540         RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
    541         m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
    542         m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer);
    543         if (!isNormalFlowOnly()) {
    544             for (RenderLayer* sc = stackingContext(); sc; sc = sc->stackingContext()) {
    545                 sc->dirtyZOrderLists();
    546                 if (sc->hasVisibleContent())
    547                     break;
    548             }
    549         }
    550     }
    551     if (parent())
    552         parent()->childVisibilityChanged(m_hasVisibleContent);
    553 }
    554 
    555 void RenderLayer::dirtyVisibleContentStatus()
    556 {
    557     m_visibleContentStatusDirty = true;
    558     if (parent())
    559         parent()->dirtyVisibleDescendantStatus();
    560 }
    561 
    562 void RenderLayer::childVisibilityChanged(bool newVisibility)
    563 {
    564     if (m_hasVisibleDescendant == newVisibility || m_visibleDescendantStatusDirty)
    565         return;
    566     if (newVisibility) {
    567         RenderLayer* l = this;
    568         while (l && !l->m_visibleDescendantStatusDirty && !l->m_hasVisibleDescendant) {
    569             l->m_hasVisibleDescendant = true;
    570             l = l->parent();
    571         }
    572     } else
    573         dirtyVisibleDescendantStatus();
    574 }
    575 
    576 void RenderLayer::dirtyVisibleDescendantStatus()
    577 {
    578     RenderLayer* l = this;
    579     while (l && !l->m_visibleDescendantStatusDirty) {
    580         l->m_visibleDescendantStatusDirty = true;
    581         l = l->parent();
    582     }
    583 }
    584 
    585 void RenderLayer::updateVisibilityStatus()
    586 {
    587     if (m_visibleDescendantStatusDirty) {
    588         m_hasVisibleDescendant = false;
    589         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
    590             child->updateVisibilityStatus();
    591             if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
    592                 m_hasVisibleDescendant = true;
    593                 break;
    594             }
    595         }
    596         m_visibleDescendantStatusDirty = false;
    597     }
    598 
    599     if (m_visibleContentStatusDirty) {
    600         if (renderer()->style()->visibility() == VISIBLE)
    601             m_hasVisibleContent = true;
    602         else {
    603             // layer may be hidden but still have some visible content, check for this
    604             m_hasVisibleContent = false;
    605             RenderObject* r = renderer()->firstChild();
    606             while (r) {
    607                 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
    608                     m_hasVisibleContent = true;
    609                     break;
    610                 }
    611                 if (r->firstChild() && !r->hasLayer())
    612                     r = r->firstChild();
    613                 else if (r->nextSibling())
    614                     r = r->nextSibling();
    615                 else {
    616                     do {
    617                         r = r->parent();
    618                         if (r == renderer())
    619                             r = 0;
    620                     } while (r && !r->nextSibling());
    621                     if (r)
    622                         r = r->nextSibling();
    623                 }
    624             }
    625         }
    626         m_visibleContentStatusDirty = false;
    627     }
    628 }
    629 
    630 void RenderLayer::dirty3DTransformedDescendantStatus()
    631 {
    632     RenderLayer* curr = stackingContext();
    633     if (curr)
    634         curr->m_3DTransformedDescendantStatusDirty = true;
    635 
    636     // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
    637     // Note that preserves3D() creates stacking context, so we can just run up the stacking contexts.
    638     while (curr && curr->preserves3D()) {
    639         curr->m_3DTransformedDescendantStatusDirty = true;
    640         curr = curr->stackingContext();
    641     }
    642 }
    643 
    644 // Return true if this layer or any preserve-3d descendants have 3d.
    645 bool RenderLayer::update3DTransformedDescendantStatus()
    646 {
    647     if (m_3DTransformedDescendantStatusDirty) {
    648         m_has3DTransformedDescendant = false;
    649 
    650         // Transformed or preserve-3d descendants can only be in the z-order lists, not
    651         // in the normal flow list, so we only need to check those.
    652         if (m_posZOrderList) {
    653             for (unsigned i = 0; i < m_posZOrderList->size(); ++i)
    654                 m_has3DTransformedDescendant |= m_posZOrderList->at(i)->update3DTransformedDescendantStatus();
    655         }
    656 
    657         // Now check our negative z-index children.
    658         if (m_negZOrderList) {
    659             for (unsigned i = 0; i < m_negZOrderList->size(); ++i)
    660                 m_has3DTransformedDescendant |= m_negZOrderList->at(i)->update3DTransformedDescendantStatus();
    661         }
    662 
    663         m_3DTransformedDescendantStatusDirty = false;
    664     }
    665 
    666     // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
    667     // the m_has3DTransformedDescendant set.
    668     if (preserves3D())
    669         return has3DTransform() || m_has3DTransformedDescendant;
    670 
    671     return has3DTransform();
    672 }
    673 
    674 void RenderLayer::updateLayerPosition()
    675 {
    676     IntPoint localPoint;
    677     IntSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
    678     if (renderer()->isRenderInline()) {
    679         RenderInline* inlineFlow = toRenderInline(renderer());
    680         IntRect lineBox = inlineFlow->linesBoundingBox();
    681         setWidth(lineBox.width());
    682         setHeight(lineBox.height());
    683         inlineBoundingBoxOffset = IntSize(lineBox.x(), lineBox.y());
    684         localPoint += inlineBoundingBoxOffset;
    685     } else if (RenderBox* box = renderBox()) {
    686         setWidth(box->width());
    687         setHeight(box->height());
    688         localPoint += box->locationOffsetIncludingFlipping();
    689     }
    690 
    691     // Clear our cached clip rect information.
    692     clearClipRects();
    693 
    694     if (!renderer()->isPositioned() && renderer()->parent()) {
    695         // We must adjust our position by walking up the render tree looking for the
    696         // nearest enclosing object with a layer.
    697         RenderObject* curr = renderer()->parent();
    698         while (curr && !curr->hasLayer()) {
    699             if (curr->isBox() && !curr->isTableRow()) {
    700                 // Rows and cells share the same coordinate space (that of the section).
    701                 // Omit them when computing our xpos/ypos.
    702                 localPoint += toRenderBox(curr)->locationOffsetIncludingFlipping();
    703             }
    704             curr = curr->parent();
    705         }
    706         if (curr->isBox() && curr->isTableRow()) {
    707             // Put ourselves into the row coordinate space.
    708             localPoint -= toRenderBox(curr)->locationOffsetIncludingFlipping();
    709         }
    710     }
    711 
    712     // Subtract our parent's scroll offset.
    713     if (renderer()->isPositioned() && enclosingPositionedAncestor()) {
    714         RenderLayer* positionedParent = enclosingPositionedAncestor();
    715 
    716         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
    717         IntSize offset = positionedParent->scrolledContentOffset();
    718         localPoint -= offset;
    719 
    720         if (renderer()->isPositioned() && positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
    721             IntSize offset = toRenderInline(positionedParent->renderer())->relativePositionedInlineOffset(toRenderBox(renderer()));
    722             localPoint += offset;
    723         }
    724     } else if (parent()) {
    725         if (isComposited()) {
    726             // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column.
    727             // They won't split across columns properly.
    728             IntSize columnOffset;
    729             parent()->renderer()->adjustForColumns(columnOffset, localPoint);
    730             localPoint += columnOffset;
    731         }
    732 
    733         IntSize scrollOffset = parent()->scrolledContentOffset();
    734         localPoint -= scrollOffset;
    735     }
    736 
    737     m_relX = m_relY = 0;
    738     if (renderer()->isRelPositioned()) {
    739         m_relX = renderer()->relativePositionOffsetX();
    740         m_relY = renderer()->relativePositionOffsetY();
    741         localPoint.move(m_relX, m_relY);
    742     }
    743 
    744     // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
    745     localPoint -= inlineBoundingBoxOffset;
    746     setLocation(localPoint.x(), localPoint.y());
    747 }
    748 
    749 TransformationMatrix RenderLayer::perspectiveTransform() const
    750 {
    751     if (!renderer()->hasTransform())
    752         return TransformationMatrix();
    753 
    754     RenderStyle* style = renderer()->style();
    755     if (!style->hasPerspective())
    756         return TransformationMatrix();
    757 
    758     // Maybe fetch the perspective from the backing?
    759     const IntRect borderBox = toRenderBox(renderer())->borderBoxRect();
    760     const float boxWidth = borderBox.width();
    761     const float boxHeight = borderBox.height();
    762 
    763     float perspectiveOriginX = style->perspectiveOriginX().calcFloatValue(boxWidth);
    764     float perspectiveOriginY = style->perspectiveOriginY().calcFloatValue(boxHeight);
    765 
    766     // A perspective origin of 0,0 makes the vanishing point in the center of the element.
    767     // We want it to be in the top-left, so subtract half the height and width.
    768     perspectiveOriginX -= boxWidth / 2.0f;
    769     perspectiveOriginY -= boxHeight / 2.0f;
    770 
    771     TransformationMatrix t;
    772     t.translate(perspectiveOriginX, perspectiveOriginY);
    773     t.applyPerspective(style->perspective());
    774     t.translate(-perspectiveOriginX, -perspectiveOriginY);
    775 
    776     return t;
    777 }
    778 
    779 FloatPoint RenderLayer::perspectiveOrigin() const
    780 {
    781     if (!renderer()->hasTransform())
    782         return FloatPoint();
    783 
    784     const IntRect borderBox = toRenderBox(renderer())->borderBoxRect();
    785     RenderStyle* style = renderer()->style();
    786 
    787     return FloatPoint(style->perspectiveOriginX().calcFloatValue(borderBox.width()),
    788                       style->perspectiveOriginY().calcFloatValue(borderBox.height()));
    789 }
    790 
    791 RenderLayer* RenderLayer::stackingContext() const
    792 {
    793     RenderLayer* layer = parent();
    794 #if ENABLE(COMPOSITED_FIXED_ELEMENTS) || ENABLE(ANDROID_OVERFLOW_SCROLL)
    795     // When using composited fixed elements, they are turned into a stacking
    796     // context and we thus need to return them.
    797     // We can simplify the while loop by using isStackingContext(); with
    798     // composited fixed elements turned on, this will return true for them,
    799     // and is otherwise equivalent to the replaced statements.
    800     while (layer && !layer->renderer()->isRoot() && !layer->isStackingContext())
    801 #else
    802     while (layer && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex())
    803 #endif
    804         layer = layer->parent();
    805     return layer;
    806 }
    807 
    808 static inline bool isPositionedContainer(RenderLayer* layer)
    809 {
    810     RenderObject* o = layer->renderer();
    811     return o->isRenderView() || o->isPositioned() || o->isRelPositioned() || layer->hasTransform();
    812 }
    813 
    814 static inline bool isFixedPositionedContainer(RenderLayer* layer)
    815 {
    816     RenderObject* o = layer->renderer();
    817     return o->isRenderView() || layer->hasTransform();
    818 }
    819 
    820 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
    821 {
    822     RenderLayer* curr = parent();
    823     while (curr && !isPositionedContainer(curr))
    824         curr = curr->parent();
    825 
    826     return curr;
    827 }
    828 
    829 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
    830 {
    831     RenderLayer* curr = parent();
    832     while (curr && !curr->renderer()->isRenderView() && !curr->transform())
    833         curr = curr->parent();
    834 
    835     return curr;
    836 }
    837 
    838 static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
    839 {
    840     return layer->isNormalFlowOnly() ? layer->parent() : layer->stackingContext();
    841 }
    842 
    843 #if USE(ACCELERATED_COMPOSITING)
    844 RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
    845 {
    846     if (includeSelf && isComposited())
    847         return const_cast<RenderLayer*>(this);
    848 
    849     for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
    850         if (curr->isComposited())
    851             return const_cast<RenderLayer*>(curr);
    852     }
    853 
    854     return 0;
    855 }
    856 #endif
    857 
    858 RenderLayer* RenderLayer::clippingRoot() const
    859 {
    860 #if USE(ACCELERATED_COMPOSITING)
    861     if (isComposited())
    862         return const_cast<RenderLayer*>(this);
    863 #endif
    864 
    865     const RenderLayer* current = this;
    866     while (current) {
    867         if (current->renderer()->isRenderView())
    868             return const_cast<RenderLayer*>(current);
    869 
    870         current = compositingContainer(current);
    871         ASSERT(current);
    872         if (current->transform()
    873 #if USE(ACCELERATED_COMPOSITING)
    874             || current->isComposited()
    875 #endif
    876         )
    877             return const_cast<RenderLayer*>(current);
    878     }
    879 
    880     ASSERT_NOT_REACHED();
    881     return 0;
    882 }
    883 
    884 IntPoint RenderLayer::absoluteToContents(const IntPoint& absolutePoint) const
    885 {
    886     // We don't use convertToLayerCoords because it doesn't know about transforms
    887     return roundedIntPoint(renderer()->absoluteToLocal(absolutePoint, false, true));
    888 }
    889 
    890 bool RenderLayer::requiresSlowRepaints() const
    891 {
    892     if (isTransparent() || hasReflection() || hasTransform())
    893         return true;
    894     if (!parent())
    895         return false;
    896     return parent()->requiresSlowRepaints();
    897 }
    898 
    899 bool RenderLayer::isTransparent() const
    900 {
    901 #if ENABLE(SVG)
    902     if (renderer()->node() && renderer()->node()->namespaceURI() == SVGNames::svgNamespaceURI)
    903         return false;
    904 #endif
    905     return renderer()->isTransparent() || renderer()->hasMask();
    906 }
    907 
    908 RenderLayer* RenderLayer::transparentPaintingAncestor()
    909 {
    910     if (isComposited())
    911         return 0;
    912 
    913     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
    914         if (curr->isComposited())
    915             return 0;
    916         if (curr->isTransparent())
    917             return curr;
    918     }
    919     return 0;
    920 }
    921 
    922 static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior);
    923 
    924 static void expandClipRectForDescendantsAndReflection(IntRect& clipRect, const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
    925 {
    926     // If we have a mask, then the clip is limited to the border box area (and there is
    927     // no need to examine child layers).
    928     if (!l->renderer()->hasMask()) {
    929         // Note: we don't have to walk z-order lists since transparent elements always establish
    930         // a stacking context.  This means we can just walk the layer tree directly.
    931         for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling()) {
    932             if (!l->reflection() || l->reflectionLayer() != curr)
    933                 clipRect.unite(transparencyClipBox(curr, rootLayer, paintBehavior));
    934         }
    935     }
    936 
    937     // If we have a reflection, then we need to account for that when we push the clip.  Reflect our entire
    938     // current transparencyClipBox to catch all child layers.
    939     // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
    940     // size into the parent layer.
    941     if (l->renderer()->hasReflection()) {
    942         int deltaX = 0;
    943         int deltaY = 0;
    944         l->convertToLayerCoords(rootLayer, deltaX, deltaY);
    945         clipRect.move(-deltaX, -deltaY);
    946         clipRect.unite(l->renderBox()->reflectedRect(clipRect));
    947         clipRect.move(deltaX, deltaY);
    948     }
    949 }
    950 
    951 static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
    952 {
    953     // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
    954     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
    955     // would be better to respect clips.
    956 
    957     if (rootLayer != l && l->paintsWithTransform(paintBehavior)) {
    958         // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
    959         // the transformed layer and all of its children.
    960         int x = 0;
    961         int y = 0;
    962         l->convertToLayerCoords(rootLayer, x, y);
    963 
    964         TransformationMatrix transform;
    965         transform.translate(x, y);
    966         transform = transform * *l->transform();
    967 
    968         IntRect clipRect = l->boundingBox(l);
    969         expandClipRectForDescendantsAndReflection(clipRect, l, l, paintBehavior);
    970         return transform.mapRect(clipRect);
    971     }
    972 
    973     IntRect clipRect = l->boundingBox(rootLayer);
    974     expandClipRectForDescendantsAndReflection(clipRect, l, rootLayer, paintBehavior);
    975     return clipRect;
    976 }
    977 
    978 void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
    979 {
    980     if (p->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
    981         return;
    982 
    983     RenderLayer* ancestor = transparentPaintingAncestor();
    984     if (ancestor)
    985         ancestor->beginTransparencyLayers(p, rootLayer, paintBehavior);
    986 
    987     if (paintsWithTransparency(paintBehavior)) {
    988         m_usedTransparency = true;
    989         p->save();
    990         IntRect clipRect = transparencyClipBox(this, rootLayer, paintBehavior);
    991         p->clip(clipRect);
    992         p->beginTransparencyLayer(renderer()->opacity());
    993 #ifdef REVEAL_TRANSPARENCY_LAYERS
    994         p->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), ColorSpaceDeviceRGB);
    995         p->fillRect(clipRect);
    996 #endif
    997     }
    998 }
    999 
   1000 void* RenderLayer::operator new(size_t sz, RenderArena* renderArena) throw()
   1001 {
   1002     return renderArena->allocate(sz);
   1003 }
   1004 
   1005 void RenderLayer::operator delete(void* ptr, size_t sz)
   1006 {
   1007     // Stash size where destroy can find it.
   1008     *(size_t *)ptr = sz;
   1009 }
   1010 
   1011 void RenderLayer::destroy(RenderArena* renderArena)
   1012 {
   1013     delete this;
   1014 
   1015     // Recover the size left there for us by operator delete and free the memory.
   1016     renderArena->free(*(size_t *)this, this);
   1017 }
   1018 
   1019 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
   1020 {
   1021     RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
   1022     if (prevSibling) {
   1023         child->setPreviousSibling(prevSibling);
   1024         prevSibling->setNextSibling(child);
   1025         ASSERT(prevSibling != child);
   1026     } else
   1027         setFirstChild(child);
   1028 
   1029     if (beforeChild) {
   1030         beforeChild->setPreviousSibling(child);
   1031         child->setNextSibling(beforeChild);
   1032         ASSERT(beforeChild != child);
   1033     } else
   1034         setLastChild(child);
   1035 
   1036     child->setParent(this);
   1037 
   1038     if (child->isNormalFlowOnly())
   1039         dirtyNormalFlowList();
   1040 
   1041     if (!child->isNormalFlowOnly() || child->firstChild()) {
   1042         // Dirty the z-order list in which we are contained.  The stackingContext() can be null in the
   1043         // case where we're building up generated content layers.  This is ok, since the lists will start
   1044         // off dirty in that case anyway.
   1045         child->dirtyStackingContextZOrderLists();
   1046     }
   1047 
   1048     child->updateVisibilityStatus();
   1049     if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
   1050         childVisibilityChanged(true);
   1051 
   1052 #if USE(ACCELERATED_COMPOSITING)
   1053     compositor()->layerWasAdded(this, child);
   1054 #endif
   1055 }
   1056 
   1057 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
   1058 {
   1059 #if USE(ACCELERATED_COMPOSITING)
   1060     if (!renderer()->documentBeingDestroyed())
   1061         compositor()->layerWillBeRemoved(this, oldChild);
   1062 #endif
   1063 
   1064     // remove the child
   1065     if (oldChild->previousSibling())
   1066         oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
   1067     if (oldChild->nextSibling())
   1068         oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
   1069 
   1070     if (m_first == oldChild)
   1071         m_first = oldChild->nextSibling();
   1072     if (m_last == oldChild)
   1073         m_last = oldChild->previousSibling();
   1074 
   1075     if (oldChild->isNormalFlowOnly())
   1076         dirtyNormalFlowList();
   1077     if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) {
   1078         // Dirty the z-order list in which we are contained.  When called via the
   1079         // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
   1080         // from the main layer tree, so we need to null-check the |stackingContext| value.
   1081         oldChild->dirtyStackingContextZOrderLists();
   1082     }
   1083 
   1084     oldChild->setPreviousSibling(0);
   1085     oldChild->setNextSibling(0);
   1086     oldChild->setParent(0);
   1087 
   1088     oldChild->updateVisibilityStatus();
   1089     if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
   1090         childVisibilityChanged(false);
   1091 
   1092     return oldChild;
   1093 }
   1094 
   1095 void RenderLayer::removeOnlyThisLayer()
   1096 {
   1097     if (!m_parent)
   1098         return;
   1099 
   1100     // Mark that we are about to lose our layer. This makes render tree
   1101     // walks ignore this layer while we're removing it.
   1102     m_renderer->setHasLayer(false);
   1103 
   1104 #if USE(ACCELERATED_COMPOSITING)
   1105     compositor()->layerWillBeRemoved(m_parent, this);
   1106 #endif
   1107 
   1108     // Dirty the clip rects.
   1109     clearClipRectsIncludingDescendants();
   1110 
   1111     // Remove us from the parent.
   1112     RenderLayer* parent = m_parent;
   1113     RenderLayer* nextSib = nextSibling();
   1114     parent->removeChild(this);
   1115 
   1116     if (reflection())
   1117         removeChild(reflectionLayer());
   1118 
   1119     // Now walk our kids and reattach them to our parent.
   1120     RenderLayer* current = m_first;
   1121     while (current) {
   1122         RenderLayer* next = current->nextSibling();
   1123         removeChild(current);
   1124         parent->addChild(current, nextSib);
   1125         current->setNeedsFullRepaint();
   1126         current->updateLayerPositions(); // Depends on hasLayer() already being false for proper layout.
   1127         current = next;
   1128     }
   1129 
   1130     m_renderer->destroyLayer();
   1131 }
   1132 
   1133 void RenderLayer::insertOnlyThisLayer()
   1134 {
   1135     if (!m_parent && renderer()->parent()) {
   1136         // We need to connect ourselves when our renderer() has a parent.
   1137         // Find our enclosingLayer and add ourselves.
   1138         RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
   1139         ASSERT(parentLayer);
   1140         RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0;
   1141         parentLayer->addChild(this, beforeChild);
   1142     }
   1143 
   1144     // Remove all descendant layers from the hierarchy and add them to the new position.
   1145     for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())
   1146         curr->moveLayers(m_parent, this);
   1147 
   1148     // Clear out all the clip rects.
   1149     clearClipRectsIncludingDescendants();
   1150 }
   1151 
   1152 void
   1153 RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, int& yPos) const
   1154 {
   1155     if (ancestorLayer == this)
   1156         return;
   1157 
   1158     EPosition position = renderer()->style()->position();
   1159     if (position == FixedPosition && (!ancestorLayer || ancestorLayer == renderer()->view()->layer())) {
   1160         // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
   1161         // localToAbsolute() on the RenderView.
   1162         FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
   1163         xPos += absPos.x();
   1164         yPos += absPos.y();
   1165         return;
   1166     }
   1167 
   1168     if (position == FixedPosition) {
   1169         // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
   1170         // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
   1171         // so we should always find the ancestor at or before we find the fixed position container.
   1172         RenderLayer* fixedPositionContainerLayer = 0;
   1173         bool foundAncestor = false;
   1174         for (RenderLayer* currLayer = parent(); currLayer; currLayer = currLayer->parent()) {
   1175             if (currLayer == ancestorLayer)
   1176                 foundAncestor = true;
   1177 
   1178             if (isFixedPositionedContainer(currLayer)) {
   1179                 fixedPositionContainerLayer = currLayer;
   1180                 ASSERT(foundAncestor);
   1181                 break;
   1182             }
   1183         }
   1184 
   1185         ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
   1186 
   1187         if (fixedPositionContainerLayer != ancestorLayer) {
   1188             int fixedContainerX = 0;
   1189             int fixedContainerY = 0;
   1190             convertToLayerCoords(fixedPositionContainerLayer, fixedContainerX, fixedContainerY);
   1191 
   1192             int ancestorX = 0;
   1193             int ancestorY = 0;
   1194             ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorX, ancestorY);
   1195 
   1196             xPos += (fixedContainerX - ancestorX);
   1197             yPos += (fixedContainerY - ancestorY);
   1198             return;
   1199         }
   1200     }
   1201 
   1202 
   1203     RenderLayer* parentLayer;
   1204     if (position == AbsolutePosition || position == FixedPosition) {
   1205         // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
   1206         parentLayer = parent();
   1207         bool foundAncestorFirst = false;
   1208         while (parentLayer) {
   1209             if (isPositionedContainer(parentLayer))
   1210                 break;
   1211 
   1212             if (parentLayer == ancestorLayer) {
   1213                 foundAncestorFirst = true;
   1214                 break;
   1215             }
   1216 
   1217             parentLayer = parentLayer->parent();
   1218         }
   1219 
   1220         if (foundAncestorFirst) {
   1221             // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
   1222             // to enclosingPositionedAncestor and subtract.
   1223             RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
   1224 
   1225             int thisX = 0;
   1226             int thisY = 0;
   1227             convertToLayerCoords(positionedAncestor, thisX, thisY);
   1228 
   1229             int ancestorX = 0;
   1230             int ancestorY = 0;
   1231             ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorX, ancestorY);
   1232 
   1233             xPos += (thisX - ancestorX);
   1234             yPos += (thisY - ancestorY);
   1235             return;
   1236         }
   1237     } else
   1238         parentLayer = parent();
   1239 
   1240     if (!parentLayer)
   1241         return;
   1242 
   1243     parentLayer->convertToLayerCoords(ancestorLayer, xPos, yPos);
   1244 
   1245     xPos += x();
   1246     yPos += y();
   1247 }
   1248 
   1249 static inline int adjustedScrollDelta(int beginningDelta) {
   1250     // This implemention matches Firefox's.
   1251     // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856.
   1252     const int speedReducer = 12;
   1253 
   1254     int adjustedDelta = beginningDelta / speedReducer;
   1255     if (adjustedDelta > 1)
   1256         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(adjustedDelta))) - 1;
   1257     else if (adjustedDelta < -1)
   1258         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(-adjustedDelta))) + 1;
   1259 
   1260     return adjustedDelta;
   1261 }
   1262 
   1263 void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
   1264 {
   1265     Frame* frame = renderer()->frame();
   1266     if (!frame)
   1267         return;
   1268 
   1269     IntPoint currentMousePosition = frame->eventHandler()->currentMousePosition();
   1270 
   1271     // We need to check if the current mouse position is out of the window. When the mouse is out of the window, the position is incoherent
   1272     static IntPoint previousMousePosition;
   1273     if (currentMousePosition.x() < 0 || currentMousePosition.y() < 0)
   1274         currentMousePosition = previousMousePosition;
   1275     else
   1276         previousMousePosition = currentMousePosition;
   1277 
   1278     int xDelta = currentMousePosition.x() - sourcePoint.x();
   1279     int yDelta = currentMousePosition.y() - sourcePoint.y();
   1280 
   1281     if (abs(xDelta) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon
   1282         xDelta = 0;
   1283     if (abs(yDelta) <= ScrollView::noPanScrollRadius)
   1284         yDelta = 0;
   1285 
   1286     scrollByRecursively(adjustedScrollDelta(xDelta), adjustedScrollDelta(yDelta));
   1287 }
   1288 
   1289 void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
   1290 {
   1291     if (!xDelta && !yDelta)
   1292         return;
   1293 
   1294     bool restrictedByLineClamp = false;
   1295     if (renderer()->parent())
   1296         restrictedByLineClamp = !renderer()->parent()->style()->lineClamp().isNone();
   1297 
   1298     if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
   1299         int newOffsetX = scrollXOffset() + xDelta;
   1300         int newOffsetY = scrollYOffset() + yDelta;
   1301         scrollToOffset(newOffsetX, newOffsetY);
   1302 
   1303         // If this layer can't do the scroll we ask the next layer up that can scroll to try
   1304         int leftToScrollX = newOffsetX - scrollXOffset();
   1305         int leftToScrollY = newOffsetY - scrollYOffset();
   1306         if ((leftToScrollX || leftToScrollY) && renderer()->parent()) {
   1307             RenderObject* nextRenderer = renderer()->parent();
   1308             while (nextRenderer) {
   1309                 if (nextRenderer->isBox() && toRenderBox(nextRenderer)->canBeScrolledAndHasScrollableArea()) {
   1310                     nextRenderer->enclosingLayer()->scrollByRecursively(leftToScrollX, leftToScrollY);
   1311                     break;
   1312                 }
   1313                 nextRenderer = nextRenderer->parent();
   1314             }
   1315 
   1316             Frame* frame = renderer()->frame();
   1317             if (frame)
   1318                 frame->eventHandler()->updateAutoscrollRenderer();
   1319         }
   1320     } else if (renderer()->view()->frameView()) {
   1321         // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
   1322         // have an overflow clip. Which means that it is a document node that can be scrolled.
   1323         renderer()->view()->frameView()->scrollBy(IntSize(xDelta, yDelta));
   1324         // FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement?
   1325         // https://bugs.webkit.org/show_bug.cgi?id=28237
   1326     }
   1327 }
   1328 
   1329 void RenderLayer::scrollToOffset(int x, int y)
   1330 {
   1331     ScrollableArea::scrollToOffsetWithoutAnimation(IntPoint(x, y));
   1332 }
   1333 
   1334 void RenderLayer::scrollTo(int x, int y)
   1335 {
   1336     RenderBox* box = renderBox();
   1337     if (!box)
   1338         return;
   1339 
   1340     if (box->style()->overflowX() != OMARQUEE) {
   1341         if (x < 0)
   1342             x = 0;
   1343         if (y < 0)
   1344             y = 0;
   1345 
   1346         // Call the scrollWidth/Height functions so that the dimensions will be computed if they need
   1347         // to be (for overflow:hidden blocks).
   1348         int maxX = scrollWidth() - box->clientWidth();
   1349         if (maxX < 0)
   1350             maxX = 0;
   1351         int maxY = scrollHeight() - box->clientHeight();
   1352         if (maxY < 0)
   1353             maxY = 0;
   1354 
   1355         if (x > maxX)
   1356             x = maxX;
   1357         if (y > maxY)
   1358             y = maxY;
   1359     }
   1360 
   1361     // FIXME: Eventually, we will want to perform a blit.  For now never
   1362     // blit, since the check for blitting is going to be very
   1363     // complicated (since it will involve testing whether our layer
   1364     // is either occluded by another layer or clipped by an enclosing
   1365     // layer or contains fixed backgrounds, etc.).
   1366     int newScrollX = x - m_scrollOrigin.x();
   1367     int newScrollY = y - m_scrollOrigin.y();
   1368     if (m_scrollY == newScrollY && m_scrollX == newScrollX)
   1369         return;
   1370     m_scrollX = newScrollX;
   1371     m_scrollY = newScrollY;
   1372 
   1373     // Update the positions of our child layers. Don't have updateLayerPositions() update
   1374     // compositing layers, because we need to do a deep update from the compositing ancestor.
   1375     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
   1376         child->updateLayerPositions(0);
   1377 
   1378     RenderView* view = renderer()->view();
   1379 
   1380     // We should have a RenderView if we're trying to scroll.
   1381     ASSERT(view);
   1382     if (view) {
   1383 #if ENABLE(DASHBOARD_SUPPORT)
   1384         // Update dashboard regions, scrolling may change the clip of a
   1385         // particular region.
   1386         view->frameView()->updateDashboardRegions();
   1387 #endif
   1388 
   1389         view->updateWidgetPositions();
   1390     }
   1391 
   1392 #if USE(ACCELERATED_COMPOSITING)
   1393     if (compositor()->inCompositingMode()) {
   1394         // Our stacking context is guaranteed to contain all of our descendants that may need
   1395         // repositioning, so update compositing layers from there.
   1396         if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
   1397             if (compositor()->compositingConsultsOverlap())
   1398                 compositor()->updateCompositingLayers(CompositingUpdateOnScroll, compositingAncestor);
   1399             else {
   1400                 bool isUpdateRoot = true;
   1401                 compositingAncestor->backing()->updateAfterLayout(RenderLayerBacking::AllDescendants, isUpdateRoot);
   1402             }
   1403         }
   1404     }
   1405 #endif
   1406 
   1407     RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
   1408     IntRect rectForRepaint = renderer()->clippedOverflowRectForRepaint(repaintContainer);
   1409 
   1410     Frame* frame = renderer()->frame();
   1411     if (frame) {
   1412         // The caret rect needs to be invalidated after scrolling
   1413         frame->selection()->setCaretRectNeedsUpdate();
   1414 
   1415         FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint);
   1416         if (repaintContainer)
   1417             quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
   1418         frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
   1419     }
   1420 
   1421     // Just schedule a full repaint of our object.
   1422 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   1423     // On android, scrollable areas are put on composited layers, so we
   1424     // do not need to repaint simply because we are scrolling
   1425     if (view && !hasOverflowScroll())
   1426         renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
   1427 #else
   1428     if (view)
   1429         renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
   1430 #endif
   1431 
   1432     // Schedule the scroll DOM event.
   1433     renderer()->node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(renderer()->node(), EventQueue::ScrollEventElementTarget);
   1434 }
   1435 
   1436 void RenderLayer::scrollRectToVisible(const IntRect& rect, bool scrollToAnchor, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
   1437 {
   1438     RenderLayer* parentLayer = 0;
   1439     IntRect newRect = rect;
   1440     int xOffset = 0, yOffset = 0;
   1441 
   1442     // We may end up propagating a scroll event. It is important that we suspend events until
   1443     // the end of the function since they could delete the layer or the layer's renderer().
   1444     FrameView* frameView = renderer()->document()->view();
   1445     if (frameView)
   1446         frameView->pauseScheduledEvents();
   1447 
   1448     bool restrictedByLineClamp = false;
   1449     if (renderer()->parent()) {
   1450         parentLayer = renderer()->parent()->enclosingLayer();
   1451         restrictedByLineClamp = !renderer()->parent()->style()->lineClamp().isNone();
   1452     }
   1453 
   1454     if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
   1455         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
   1456         // This will prevent us from revealing text hidden by the slider in Safari RSS.
   1457         RenderBox* box = renderBox();
   1458         ASSERT(box);
   1459         FloatPoint absPos = box->localToAbsolute();
   1460         absPos.move(box->borderLeft(), box->borderTop());
   1461 
   1462         IntRect layerBounds = IntRect(absPos.x() + scrollXOffset(), absPos.y() + scrollYOffset(), box->clientWidth(), box->clientHeight());
   1463         IntRect exposeRect = IntRect(rect.x() + scrollXOffset(), rect.y() + scrollYOffset(), rect.width(), rect.height());
   1464         IntRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
   1465 
   1466         xOffset = r.x() - absPos.x();
   1467         yOffset = r.y() - absPos.y();
   1468         // Adjust offsets if they're outside of the allowable range.
   1469         xOffset = max(0, min(scrollWidth() - layerBounds.width(), xOffset));
   1470         yOffset = max(0, min(scrollHeight() - layerBounds.height(), yOffset));
   1471 
   1472         if (xOffset != scrollXOffset() || yOffset != scrollYOffset()) {
   1473             int diffX = scrollXOffset();
   1474             int diffY = scrollYOffset();
   1475             scrollToOffset(xOffset, yOffset);
   1476             diffX = scrollXOffset() - diffX;
   1477             diffY = scrollYOffset() - diffY;
   1478             newRect.setX(rect.x() - diffX);
   1479             newRect.setY(rect.y() - diffY);
   1480         }
   1481     } else if (!parentLayer && renderer()->isBox() && renderBox()->canBeProgramaticallyScrolled(scrollToAnchor)) {
   1482         if (frameView) {
   1483             if (renderer()->document() && renderer()->document()->ownerElement() && renderer()->document()->ownerElement()->renderer()) {
   1484                 IntRect viewRect = frameView->visibleContentRect();
   1485                 IntRect r = getRectToExpose(viewRect, rect, alignX, alignY);
   1486 
   1487                 xOffset = r.x();
   1488                 yOffset = r.y();
   1489                 // Adjust offsets if they're outside of the allowable range.
   1490                 xOffset = max(0, min(frameView->contentsWidth(), xOffset));
   1491                 yOffset = max(0, min(frameView->contentsHeight(), yOffset));
   1492 
   1493                 frameView->setScrollPosition(IntPoint(xOffset, yOffset));
   1494                 parentLayer = renderer()->document()->ownerElement()->renderer()->enclosingLayer();
   1495                 newRect.setX(rect.x() - frameView->scrollX() + frameView->x());
   1496                 newRect.setY(rect.y() - frameView->scrollY() + frameView->y());
   1497             } else {
   1498                 IntRect viewRect = frameView->visibleContentRect();
   1499                 IntRect r = getRectToExpose(viewRect, rect, alignX, alignY);
   1500 
   1501                 frameView->setScrollPosition(r.location());
   1502 
   1503                 // This is the outermost view of a web page, so after scrolling this view we
   1504                 // scroll its container by calling Page::scrollRectIntoView.
   1505                 // This only has an effect on the Mac platform in applications
   1506                 // that put web views into scrolling containers, such as Mac OS X Mail.
   1507                 // The canAutoscroll function in EventHandler also knows about this.
   1508                 if (Frame* frame = frameView->frame()) {
   1509                     if (Page* page = frame->page())
   1510                         page->chrome()->scrollRectIntoView(rect);
   1511                 }
   1512             }
   1513         }
   1514     }
   1515 
   1516     if (parentLayer)
   1517         parentLayer->scrollRectToVisible(newRect, scrollToAnchor, alignX, alignY);
   1518 
   1519     if (frameView)
   1520         frameView->resumeScheduledEvents();
   1521 }
   1522 
   1523 IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
   1524 {
   1525     // Determine the appropriate X behavior.
   1526     ScrollBehavior scrollX;
   1527     IntRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
   1528     int intersectWidth = intersection(visibleRect, exposeRectX).width();
   1529     if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
   1530         // If the rectangle is fully visible, use the specified visible behavior.
   1531         // If the rectangle is partially visible, but over a certain threshold,
   1532         // then treat it as fully visible to avoid unnecessary horizontal scrolling
   1533         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
   1534     else if (intersectWidth == visibleRect.width()) {
   1535         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
   1536         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
   1537         if (scrollX == alignCenter)
   1538             scrollX = noScroll;
   1539     } else if (intersectWidth > 0)
   1540         // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
   1541         scrollX = ScrollAlignment::getPartialBehavior(alignX);
   1542     else
   1543         scrollX = ScrollAlignment::getHiddenBehavior(alignX);
   1544     // If we're trying to align to the closest edge, and the exposeRect is further right
   1545     // than the visibleRect, and not bigger than the visible area, then align with the right.
   1546     if (scrollX == alignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
   1547         scrollX = alignRight;
   1548 
   1549     // Given the X behavior, compute the X coordinate.
   1550     int x;
   1551     if (scrollX == noScroll)
   1552         x = visibleRect.x();
   1553     else if (scrollX == alignRight)
   1554         x = exposeRect.maxX() - visibleRect.width();
   1555     else if (scrollX == alignCenter)
   1556         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
   1557     else
   1558         x = exposeRect.x();
   1559 
   1560     // Determine the appropriate Y behavior.
   1561     ScrollBehavior scrollY;
   1562     IntRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
   1563     int intersectHeight = intersection(visibleRect, exposeRectY).height();
   1564     if (intersectHeight == exposeRect.height())
   1565         // If the rectangle is fully visible, use the specified visible behavior.
   1566         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
   1567     else if (intersectHeight == visibleRect.height()) {
   1568         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
   1569         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
   1570         if (scrollY == alignCenter)
   1571             scrollY = noScroll;
   1572     } else if (intersectHeight > 0)
   1573         // If the rectangle is partially visible, use the specified partial behavior
   1574         scrollY = ScrollAlignment::getPartialBehavior(alignY);
   1575     else
   1576         scrollY = ScrollAlignment::getHiddenBehavior(alignY);
   1577     // If we're trying to align to the closest edge, and the exposeRect is further down
   1578     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
   1579     if (scrollY == alignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
   1580         scrollY = alignBottom;
   1581 
   1582     // Given the Y behavior, compute the Y coordinate.
   1583     int y;
   1584     if (scrollY == noScroll)
   1585         y = visibleRect.y();
   1586     else if (scrollY == alignBottom)
   1587         y = exposeRect.maxY() - visibleRect.height();
   1588     else if (scrollY == alignCenter)
   1589         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
   1590     else
   1591         y = exposeRect.y();
   1592 
   1593     return IntRect(IntPoint(x, y), visibleRect.size());
   1594 }
   1595 
   1596 void RenderLayer::autoscroll()
   1597 {
   1598     Frame* frame = renderer()->frame();
   1599     if (!frame)
   1600         return;
   1601 
   1602     FrameView* frameView = frame->view();
   1603     if (!frameView)
   1604         return;
   1605 
   1606 #if ENABLE(DRAG_SUPPORT)
   1607     frame->eventHandler()->updateSelectionForMouseDrag();
   1608 #endif
   1609 
   1610     IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->currentMousePosition());
   1611     scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
   1612 }
   1613 
   1614 void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset)
   1615 {
   1616     // FIXME: This should be possible on generated content but is not right now.
   1617     if (!inResizeMode() || !renderer()->hasOverflowClip() || !renderer()->node())
   1618         return;
   1619 
   1620     // Set the width and height of the shadow ancestor node if there is one.
   1621     // This is necessary for textarea elements since the resizable layer is in the shadow content.
   1622     Element* element = static_cast<Element*>(renderer()->node()->shadowAncestorNode());
   1623     RenderBox* renderer = toRenderBox(element->renderer());
   1624 
   1625     EResize resize = renderer->style()->resize();
   1626     if (resize == RESIZE_NONE)
   1627         return;
   1628 
   1629     Document* document = element->document();
   1630     if (!document->frame()->eventHandler()->mousePressed())
   1631         return;
   1632 
   1633     float zoomFactor = renderer->style()->effectiveZoom();
   1634 
   1635     IntSize newOffset = offsetFromResizeCorner(document->view()->windowToContents(evt.pos()));
   1636     newOffset.setWidth(newOffset.width() / zoomFactor);
   1637     newOffset.setHeight(newOffset.height() / zoomFactor);
   1638 
   1639     IntSize currentSize = IntSize(renderer->width() / zoomFactor, renderer->height() / zoomFactor);
   1640     IntSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
   1641     element->setMinimumSizeForResizing(minimumSize);
   1642 
   1643     IntSize adjustedOldOffset = IntSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
   1644 
   1645     IntSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
   1646 
   1647     CSSStyleDeclaration* style = element->style();
   1648     bool isBoxSizingBorder = renderer->style()->boxSizing() == BORDER_BOX;
   1649 
   1650     ExceptionCode ec;
   1651 
   1652     if (resize != RESIZE_VERTICAL && difference.width()) {
   1653         if (element->isFormControlElement()) {
   1654             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
   1655             style->setProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false, ec);
   1656             style->setProperty(CSSPropertyMarginRight, String::number(renderer->marginRight() / zoomFactor) + "px", false, ec);
   1657         }
   1658         int baseWidth = renderer->width() - (isBoxSizingBorder ? 0 : renderer->borderAndPaddingWidth());
   1659         baseWidth = baseWidth / zoomFactor;
   1660         style->setProperty(CSSPropertyWidth, String::number(baseWidth + difference.width()) + "px", false, ec);
   1661     }
   1662 
   1663     if (resize != RESIZE_HORIZONTAL && difference.height()) {
   1664         if (element->isFormControlElement()) {
   1665             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
   1666             style->setProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false, ec);
   1667             style->setProperty(CSSPropertyMarginBottom, String::number(renderer->marginBottom() / zoomFactor) + "px", false, ec);
   1668         }
   1669         int baseHeight = renderer->height() - (isBoxSizingBorder ? 0 : renderer->borderAndPaddingHeight());
   1670         baseHeight = baseHeight / zoomFactor;
   1671         style->setProperty(CSSPropertyHeight, String::number(baseHeight + difference.height()) + "px", false, ec);
   1672     }
   1673 
   1674     document->updateLayout();
   1675 
   1676     // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
   1677 }
   1678 
   1679 int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
   1680 {
   1681     Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
   1682     return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
   1683 }
   1684 
   1685 void RenderLayer::setScrollOffset(const IntPoint& offset)
   1686 {
   1687     scrollTo(offset.x(), offset.y());
   1688 }
   1689 
   1690 int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
   1691 {
   1692     if (scrollbar->orientation() == HorizontalScrollbar)
   1693         return scrollXOffset();
   1694     if (scrollbar->orientation() == VerticalScrollbar)
   1695         return scrollYOffset();
   1696     return 0;
   1697 }
   1698 
   1699 bool RenderLayer::isActive() const
   1700 {
   1701     Page* page = renderer()->frame()->page();
   1702     return page && page->focusController()->isActive();
   1703 }
   1704 
   1705 static IntRect cornerRect(const RenderLayer* layer, const IntRect& bounds)
   1706 {
   1707     int horizontalThickness;
   1708     int verticalThickness;
   1709     if (!layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
   1710         // FIXME: This isn't right.  We need to know the thickness of custom scrollbars
   1711         // even when they don't exist in order to set the resizer square size properly.
   1712         horizontalThickness = ScrollbarTheme::nativeTheme()->scrollbarThickness();
   1713         verticalThickness = horizontalThickness;
   1714     } else if (layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
   1715         horizontalThickness = layer->verticalScrollbar()->width();
   1716         verticalThickness = horizontalThickness;
   1717     } else if (layer->horizontalScrollbar() && !layer->verticalScrollbar()) {
   1718         verticalThickness = layer->horizontalScrollbar()->height();
   1719         horizontalThickness = verticalThickness;
   1720     } else {
   1721         horizontalThickness = layer->verticalScrollbar()->width();
   1722         verticalThickness = layer->horizontalScrollbar()->height();
   1723     }
   1724     return IntRect(bounds.maxX() - horizontalThickness - layer->renderer()->style()->borderRightWidth(),
   1725                    bounds.maxY() - verticalThickness - layer->renderer()->style()->borderBottomWidth(),
   1726                    horizontalThickness, verticalThickness);
   1727 }
   1728 
   1729 IntRect RenderLayer::scrollCornerRect() const
   1730 {
   1731     // We have a scrollbar corner when a scrollbar is visible and not filling the entire length of the box.
   1732     // This happens when:
   1733     // (a) A resizer is present and at least one scrollbar is present
   1734     // (b) Both scrollbars are present.
   1735     bool hasHorizontalBar = horizontalScrollbar();
   1736     bool hasVerticalBar = verticalScrollbar();
   1737     bool hasResizer = renderer()->style()->resize() != RESIZE_NONE;
   1738     if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
   1739         return cornerRect(this, renderBox()->borderBoxRect());
   1740     return IntRect();
   1741 }
   1742 
   1743 static IntRect resizerCornerRect(const RenderLayer* layer, const IntRect& bounds)
   1744 {
   1745     ASSERT(layer->renderer()->isBox());
   1746     if (layer->renderer()->style()->resize() == RESIZE_NONE)
   1747         return IntRect();
   1748     return cornerRect(layer, bounds);
   1749 }
   1750 
   1751 IntRect RenderLayer::scrollCornerAndResizerRect() const
   1752 {
   1753     RenderBox* box = renderBox();
   1754     if (!box)
   1755         return IntRect();
   1756     IntRect scrollCornerAndResizer = scrollCornerRect();
   1757     if (scrollCornerAndResizer.isEmpty())
   1758         scrollCornerAndResizer = resizerCornerRect(this, box->borderBoxRect());
   1759     return scrollCornerAndResizer;
   1760 }
   1761 
   1762 bool RenderLayer::isScrollCornerVisible() const
   1763 {
   1764     ASSERT(renderer()->isBox());
   1765     return !scrollCornerRect().isEmpty();
   1766 }
   1767 
   1768 IntRect RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
   1769 {
   1770     RenderView* view = renderer()->view();
   1771     if (!view)
   1772         return scrollbarRect;
   1773 
   1774     IntRect rect = scrollbarRect;
   1775     rect.move(scrollbarOffset(scrollbar));
   1776 
   1777     return view->frameView()->convertFromRenderer(renderer(), rect);
   1778 }
   1779 
   1780 IntRect RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
   1781 {
   1782     RenderView* view = renderer()->view();
   1783     if (!view)
   1784         return parentRect;
   1785 
   1786     IntRect rect = view->frameView()->convertToRenderer(renderer(), parentRect);
   1787     rect.move(-scrollbarOffset(scrollbar));
   1788     return rect;
   1789 }
   1790 
   1791 IntPoint RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
   1792 {
   1793     RenderView* view = renderer()->view();
   1794     if (!view)
   1795         return scrollbarPoint;
   1796 
   1797     IntPoint point = scrollbarPoint;
   1798     point.move(scrollbarOffset(scrollbar));
   1799     return view->frameView()->convertFromRenderer(renderer(), point);
   1800 }
   1801 
   1802 IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
   1803 {
   1804     RenderView* view = renderer()->view();
   1805     if (!view)
   1806         return parentPoint;
   1807 
   1808     IntPoint point = view->frameView()->convertToRenderer(renderer(), parentPoint);
   1809 
   1810     point.move(-scrollbarOffset(scrollbar));
   1811     return point;
   1812 }
   1813 
   1814 IntSize RenderLayer::contentsSize() const
   1815 {
   1816     return IntSize(const_cast<RenderLayer*>(this)->scrollWidth(), const_cast<RenderLayer*>(this)->scrollHeight());
   1817 }
   1818 
   1819 int RenderLayer::visibleHeight() const
   1820 {
   1821     return m_height;
   1822 }
   1823 
   1824 int RenderLayer::visibleWidth() const
   1825 {
   1826     return m_width;
   1827 }
   1828 
   1829 bool RenderLayer::shouldSuspendScrollAnimations() const
   1830 {
   1831     RenderView* view = renderer()->view();
   1832     if (!view)
   1833         return true;
   1834     return view->frameView()->shouldSuspendScrollAnimations();
   1835 }
   1836 
   1837 IntPoint RenderLayer::currentMousePosition() const
   1838 {
   1839     return renderer()->frame() ? renderer()->frame()->eventHandler()->currentMousePosition() : IntPoint();
   1840 }
   1841 
   1842 IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
   1843 {
   1844     RenderBox* box = renderBox();
   1845 
   1846     if (scrollbar == m_vBar.get())
   1847         return IntSize(box->width() - box->borderRight() - scrollbar->width(), box->borderTop());
   1848 
   1849     if (scrollbar == m_hBar.get())
   1850         return IntSize(box->borderLeft(), box->height() - box->borderBottom() - scrollbar->height());
   1851 
   1852     ASSERT_NOT_REACHED();
   1853     return IntSize();
   1854 }
   1855 
   1856 void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
   1857 {
   1858 #if USE(ACCELERATED_COMPOSITING)
   1859     if (scrollbar == m_vBar.get()) {
   1860         if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
   1861             layer->setNeedsDisplayInRect(rect);
   1862             return;
   1863         }
   1864     } else {
   1865         if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
   1866             layer->setNeedsDisplayInRect(rect);
   1867             return;
   1868         }
   1869     }
   1870 #endif
   1871     IntRect scrollRect = rect;
   1872     RenderBox* box = renderBox();
   1873     ASSERT(box);
   1874     if (scrollbar == m_vBar.get())
   1875         scrollRect.move(box->width() - box->borderRight() - scrollbar->width(), box->borderTop());
   1876     else
   1877         scrollRect.move(box->borderLeft(), box->height() - box->borderBottom() - scrollbar->height());
   1878     renderer()->repaintRectangle(scrollRect);
   1879 }
   1880 
   1881 void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
   1882 {
   1883 #if USE(ACCELERATED_COMPOSITING)
   1884     if (GraphicsLayer* layer = layerForScrollCorner()) {
   1885         layer->setNeedsDisplayInRect(rect);
   1886         return;
   1887     }
   1888 #endif
   1889     if (m_scrollCorner)
   1890         m_scrollCorner->repaintRectangle(rect);
   1891     if (m_resizer)
   1892         m_resizer->repaintRectangle(rect);
   1893 }
   1894 
   1895 PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
   1896 {
   1897     RefPtr<Scrollbar> widget;
   1898     RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
   1899     bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style()->hasPseudoStyle(SCROLLBAR);
   1900     if (hasCustomScrollbarStyle)
   1901         widget = RenderScrollbar::createCustomScrollbar(this, orientation, toRenderBox(actualRenderer));
   1902     else {
   1903         widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
   1904         if (orientation == HorizontalScrollbar)
   1905             didAddHorizontalScrollbar(widget.get());
   1906         else
   1907             didAddVerticalScrollbar(widget.get());
   1908     }
   1909     renderer()->document()->view()->addChild(widget.get());
   1910     return widget.release();
   1911 }
   1912 
   1913 void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
   1914 {
   1915     RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
   1916     if (scrollbar) {
   1917         if (scrollbar->isCustomScrollbar())
   1918             static_cast<RenderScrollbar*>(scrollbar.get())->clearOwningRenderer();
   1919         else {
   1920             if (orientation == HorizontalScrollbar)
   1921                 willRemoveHorizontalScrollbar(scrollbar.get());
   1922             else
   1923                 willRemoveVerticalScrollbar(scrollbar.get());
   1924         }
   1925 
   1926         scrollbar->removeFromParent();
   1927         scrollbar->disconnectFromScrollableArea();
   1928         scrollbar = 0;
   1929     }
   1930 }
   1931 
   1932 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
   1933 {
   1934     if (hasScrollbar == (m_hBar != 0))
   1935         return;
   1936 
   1937     if (hasScrollbar)
   1938         m_hBar = createScrollbar(HorizontalScrollbar);
   1939     else
   1940         destroyScrollbar(HorizontalScrollbar);
   1941 
   1942     // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
   1943     if (m_hBar)
   1944         m_hBar->styleChanged();
   1945     if (m_vBar)
   1946         m_vBar->styleChanged();
   1947 
   1948 #if ENABLE(DASHBOARD_SUPPORT)
   1949     // Force an update since we know the scrollbars have changed things.
   1950     if (renderer()->document()->hasDashboardRegions())
   1951         renderer()->document()->setDashboardRegionsDirty(true);
   1952 #endif
   1953 }
   1954 
   1955 void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
   1956 {
   1957     if (hasScrollbar == (m_vBar != 0))
   1958         return;
   1959 
   1960     if (hasScrollbar)
   1961         m_vBar = createScrollbar(VerticalScrollbar);
   1962     else
   1963         destroyScrollbar(VerticalScrollbar);
   1964 
   1965      // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
   1966     if (m_hBar)
   1967         m_hBar->styleChanged();
   1968     if (m_vBar)
   1969         m_vBar->styleChanged();
   1970 
   1971 #if ENABLE(DASHBOARD_SUPPORT)
   1972     // Force an update since we know the scrollbars have changed things.
   1973     if (renderer()->document()->hasDashboardRegions())
   1974         renderer()->document()->setDashboardRegionsDirty(true);
   1975 #endif
   1976 }
   1977 
   1978 int RenderLayer::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const
   1979 {
   1980     if (!m_vBar || (m_vBar->isOverlayScrollbar() && relevancy == IgnoreOverlayScrollbarSize))
   1981         return 0;
   1982     return m_vBar->width();
   1983 }
   1984 
   1985 int RenderLayer::horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy relevancy) const
   1986 {
   1987     if (!m_hBar || (m_hBar->isOverlayScrollbar() && relevancy == IgnoreOverlayScrollbarSize))
   1988         return 0;
   1989     return m_hBar->height();
   1990 }
   1991 
   1992 IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
   1993 {
   1994     // Currently the resize corner is always the bottom right corner
   1995     IntPoint bottomRight(width(), height());
   1996     IntPoint localPoint = absoluteToContents(absolutePoint);
   1997     return localPoint - bottomRight;
   1998 }
   1999 
   2000 bool RenderLayer::hasOverflowControls() const
   2001 {
   2002     return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
   2003 }
   2004 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   2005 bool RenderLayer::hasOverflowParent() const
   2006 {
   2007     const RenderLayer* layer = this;
   2008     while (layer && !layer->hasOverflowScroll())
   2009         layer = layer->parent();
   2010     return layer;
   2011 }
   2012 #endif
   2013 
   2014 void RenderLayer::positionOverflowControls(int tx, int ty)
   2015 {
   2016     if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
   2017         return;
   2018 
   2019     RenderBox* box = renderBox();
   2020     if (!box)
   2021         return;
   2022 
   2023     const IntRect& borderBox = box->borderBoxRect();
   2024     const IntRect& scrollCorner = scrollCornerRect();
   2025     IntRect absBounds(borderBox.x() + tx, borderBox.y() + ty, borderBox.width(), borderBox.height());
   2026     if (m_vBar)
   2027         m_vBar->setFrameRect(IntRect(absBounds.maxX() - box->borderRight() - m_vBar->width(),
   2028                                      absBounds.y() + box->borderTop(),
   2029                                      m_vBar->width(),
   2030                                      absBounds.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height()));
   2031 
   2032     if (m_hBar)
   2033         m_hBar->setFrameRect(IntRect(absBounds.x() + box->borderLeft(),
   2034                                      absBounds.maxY() - box->borderBottom() - m_hBar->height(),
   2035                                      absBounds.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
   2036                                      m_hBar->height()));
   2037 
   2038 #if USE(ACCELERATED_COMPOSITING)
   2039     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
   2040         if (m_hBar) {
   2041             layer->setPosition(IntPoint(m_hBar->frameRect().x() - tx, m_hBar->frameRect().y() - ty));
   2042             layer->setSize(m_hBar->frameRect().size());
   2043         }
   2044         layer->setDrawsContent(m_hBar);
   2045     }
   2046     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
   2047         if (m_vBar) {
   2048             layer->setPosition(IntPoint(m_vBar->frameRect().x() - tx, m_vBar->frameRect().y() - ty));
   2049             layer->setSize(m_vBar->frameRect().size());
   2050         }
   2051         layer->setDrawsContent(m_vBar);
   2052     }
   2053 
   2054     if (GraphicsLayer* layer = layerForScrollCorner()) {
   2055         const IntRect& scrollCornerAndResizer = scrollCornerAndResizerRect();
   2056         layer->setPosition(scrollCornerAndResizer.location());
   2057         layer->setSize(scrollCornerAndResizer.size());
   2058         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
   2059     }
   2060 #endif
   2061 
   2062     if (m_scrollCorner)
   2063         m_scrollCorner->setFrameRect(scrollCorner);
   2064     if (m_resizer)
   2065         m_resizer->setFrameRect(resizerCornerRect(this, borderBox));
   2066 }
   2067 
   2068 #if PLATFORM(ANDROID)
   2069 // When width/height change, the scrollWidth/scrollHeight should be dirty.
   2070 // And this should be upstreamed to webkit.
   2071 void RenderLayer::setWidth(int w)
   2072 {
   2073     if (m_width != w) {
   2074         m_scrollDimensionsDirty = true;
   2075         m_width = w;
   2076     }
   2077 }
   2078 
   2079 void RenderLayer::setHeight(int h)
   2080 {
   2081     if (m_height != h) {
   2082         m_scrollDimensionsDirty = true;
   2083         m_height = h;
   2084     }
   2085 }
   2086 #endif
   2087 
   2088 int RenderLayer::scrollWidth()
   2089 {
   2090     if (m_scrollDimensionsDirty)
   2091         computeScrollDimensions();
   2092     return m_scrollWidth;
   2093 }
   2094 
   2095 int RenderLayer::scrollHeight()
   2096 {
   2097     if (m_scrollDimensionsDirty)
   2098         computeScrollDimensions();
   2099     return m_scrollHeight;
   2100 }
   2101 
   2102 int RenderLayer::overflowTop() const
   2103 {
   2104     RenderBox* box = renderBox();
   2105     IntRect overflowRect(box->layoutOverflowRect());
   2106     box->flipForWritingMode(overflowRect);
   2107     return overflowRect.y();
   2108 }
   2109 
   2110 int RenderLayer::overflowBottom() const
   2111 {
   2112     RenderBox* box = renderBox();
   2113     IntRect overflowRect(box->layoutOverflowRect());
   2114     box->flipForWritingMode(overflowRect);
   2115     return overflowRect.maxY();
   2116 }
   2117 
   2118 int RenderLayer::overflowLeft() const
   2119 {
   2120     RenderBox* box = renderBox();
   2121     IntRect overflowRect(box->layoutOverflowRect());
   2122     box->flipForWritingMode(overflowRect);
   2123     return overflowRect.x();
   2124 }
   2125 
   2126 int RenderLayer::overflowRight() const
   2127 {
   2128     RenderBox* box = renderBox();
   2129     IntRect overflowRect(box->layoutOverflowRect());
   2130     box->flipForWritingMode(overflowRect);
   2131     return overflowRect.maxX();
   2132 }
   2133 
   2134 void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
   2135 {
   2136     RenderBox* box = renderBox();
   2137     ASSERT(box);
   2138 
   2139     m_scrollDimensionsDirty = false;
   2140 
   2141     m_scrollLeftOverflow = overflowLeft() - box->borderLeft();
   2142     m_scrollTopOverflow = overflowTop() - box->borderTop();
   2143 
   2144     m_scrollWidth = overflowRight() - overflowLeft();
   2145     m_scrollHeight = overflowBottom() - overflowTop();
   2146 
   2147     m_scrollOrigin = IntPoint(-m_scrollLeftOverflow, -m_scrollTopOverflow);
   2148 
   2149     if (needHBar)
   2150         *needHBar = m_scrollWidth > box->clientWidth();
   2151     if (needVBar)
   2152         *needVBar = m_scrollHeight > box->clientHeight();
   2153 }
   2154 
   2155 void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
   2156 {
   2157     if (m_overflowStatusDirty) {
   2158         m_horizontalOverflow = horizontalOverflow;
   2159         m_verticalOverflow = verticalOverflow;
   2160         m_overflowStatusDirty = false;
   2161         return;
   2162     }
   2163 
   2164     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
   2165     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
   2166 
   2167     if (horizontalOverflowChanged || verticalOverflowChanged) {
   2168         m_horizontalOverflow = horizontalOverflow;
   2169         m_verticalOverflow = verticalOverflow;
   2170 
   2171         if (FrameView* frameView = renderer()->document()->view()) {
   2172             frameView->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow),
   2173                 renderer()->node());
   2174         }
   2175     }
   2176 }
   2177 
   2178 void RenderLayer::updateScrollInfoAfterLayout()
   2179 {
   2180     RenderBox* box = renderBox();
   2181     if (!box)
   2182         return;
   2183 
   2184     m_scrollDimensionsDirty = true;
   2185 
   2186     bool horizontalOverflow, verticalOverflow;
   2187     computeScrollDimensions(&horizontalOverflow, &verticalOverflow);
   2188 
   2189     if (box->style()->overflowX() != OMARQUEE) {
   2190         // Layout may cause us to be in an invalid scroll position.  In this case we need
   2191         // to pull our scroll offsets back to the max (or push them up to the min).
   2192         int newX = max(0, min(scrollXOffset(), scrollWidth() - box->clientWidth()));
   2193         int newY = max(0, min(scrollYOffset(), scrollHeight() - box->clientHeight()));
   2194         if (newX != scrollXOffset() || newY != scrollYOffset()) {
   2195             RenderView* view = renderer()->view();
   2196             ASSERT(view);
   2197             // scrollToOffset() may call updateLayerPositions(), which doesn't work
   2198             // with LayoutState.
   2199             // FIXME: Remove the disableLayoutState/enableLayoutState if the above changes.
   2200             if (view)
   2201                 view->disableLayoutState();
   2202             scrollToOffset(newX, newY);
   2203             if (view)
   2204                 view->enableLayoutState();
   2205         }
   2206     }
   2207 
   2208     bool haveHorizontalBar = m_hBar;
   2209     bool haveVerticalBar = m_vBar;
   2210 
   2211     // overflow:scroll should just enable/disable.
   2212     if (renderer()->style()->overflowX() == OSCROLL)
   2213         m_hBar->setEnabled(horizontalOverflow);
   2214     if (renderer()->style()->overflowY() == OSCROLL)
   2215         m_vBar->setEnabled(verticalOverflow);
   2216 
   2217     // A dynamic change from a scrolling overflow to overflow:hidden means we need to get rid of any
   2218     // scrollbars that may be present.
   2219     if (renderer()->style()->overflowX() == OHIDDEN && haveHorizontalBar)
   2220         setHasHorizontalScrollbar(false);
   2221     if (renderer()->style()->overflowY() == OHIDDEN && haveVerticalBar)
   2222         setHasVerticalScrollbar(false);
   2223 
   2224     // overflow:auto may need to lay out again if scrollbars got added/removed.
   2225     bool scrollbarsChanged = (box->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow) ||
   2226                              (box->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow);
   2227     if (scrollbarsChanged) {
   2228         if (box->hasAutoHorizontalScrollbar())
   2229             setHasHorizontalScrollbar(horizontalOverflow);
   2230         if (box->hasAutoVerticalScrollbar())
   2231             setHasVerticalScrollbar(verticalOverflow);
   2232 
   2233 #if ENABLE(DASHBOARD_SUPPORT)
   2234         // Force an update since we know the scrollbars have changed things.
   2235         if (renderer()->document()->hasDashboardRegions())
   2236             renderer()->document()->setDashboardRegionsDirty(true);
   2237 #endif
   2238 
   2239         renderer()->repaint();
   2240 
   2241         if (renderer()->style()->overflowX() == OAUTO || renderer()->style()->overflowY() == OAUTO) {
   2242             if (!m_inOverflowRelayout) {
   2243                 // Our proprietary overflow: overlay value doesn't trigger a layout.
   2244                 m_inOverflowRelayout = true;
   2245                 renderer()->setNeedsLayout(true, false);
   2246                 if (renderer()->isRenderBlock()) {
   2247                     RenderBlock* block = toRenderBlock(renderer());
   2248                     block->scrollbarsChanged(box->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow,
   2249                                              box->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow);
   2250                     block->layoutBlock(true);
   2251                 } else
   2252                     renderer()->layout();
   2253                 m_inOverflowRelayout = false;
   2254             }
   2255         }
   2256     }
   2257 
   2258     // If overflow:scroll is turned into overflow:auto a bar might still be disabled (Bug 11985).
   2259     if (m_hBar && box->hasAutoHorizontalScrollbar())
   2260         m_hBar->setEnabled(true);
   2261     if (m_vBar && box->hasAutoVerticalScrollbar())
   2262         m_vBar->setEnabled(true);
   2263 
   2264     // Set up the range (and page step/line step).
   2265     if (m_hBar) {
   2266         int clientWidth = box->clientWidth();
   2267         int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
   2268         m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
   2269         m_hBar->setProportion(clientWidth, m_scrollWidth);
   2270     }
   2271     if (m_vBar) {
   2272         int clientHeight = box->clientHeight();
   2273         int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
   2274         m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
   2275         m_vBar->setProportion(clientHeight, m_scrollHeight);
   2276     }
   2277 
   2278     RenderView* view = renderer()->view();
   2279     view->disableLayoutState();
   2280     scrollToOffset(scrollXOffset(), scrollYOffset());
   2281     view->enableLayoutState();
   2282 
   2283     if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
   2284         updateOverflowStatus(horizontalOverflow, verticalOverflow);
   2285 
   2286 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   2287     bool hasOverflowScroll = ((horizontalOverflow && m_hBar) || (verticalOverflow && m_vBar));
   2288     if (hasOverflowScroll) {
   2289         // Disable UI side scrolling for non-readonly textareas.
   2290         if (renderer()->isTextArea() && (!renderer()->node()
   2291                 || !static_cast<HTMLTextAreaElement*>(renderer()->node())->readOnly()))
   2292             hasOverflowScroll = false;
   2293     }
   2294     if (hasOverflowScroll != m_hasOverflowScroll) {
   2295         m_hasOverflowScroll = hasOverflowScroll;
   2296         dirtyZOrderLists();
   2297         dirtyStackingContextZOrderLists();
   2298         if (renderer()->node())
   2299             renderer()->node()->setNeedsStyleRecalc(SyntheticStyleChange);
   2300     }
   2301 #endif
   2302 }
   2303 
   2304 void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty, const IntRect& damageRect, bool paintingOverlayControls)
   2305 {
   2306     // Don't do anything if we have no overflow.
   2307     if (!renderer()->hasOverflowClip())
   2308         return;
   2309 
   2310     // Overlay scrollbars paint in a second pass through the layer tree so that they will paint
   2311     // on top of everything else. If this is the normal painting pass, paintingOverlayControls
   2312     // will be false, and we should just tell the root layer that there are overlay scrollbars
   2313     // that need to be painted. That will cause the second pass through the layer tree to run,
   2314     // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the
   2315     // second pass doesn't need to re-enter the RenderTree to get it right.
   2316     if (hasOverlayScrollbars() && !paintingOverlayControls) {
   2317         RenderView* renderView = renderer()->view();
   2318         renderView->layer()->setContainsDirtyOverlayScrollbars(true);
   2319         m_cachedOverlayScrollbarOffset = IntPoint(tx, ty);
   2320         renderView->frameView()->setContainsScrollableAreaWithOverlayScrollbars(true);
   2321         return;
   2322     }
   2323 
   2324     int offsetX = tx;
   2325     int offsetY = ty;
   2326     if (paintingOverlayControls) {
   2327         offsetX = m_cachedOverlayScrollbarOffset.x();
   2328         offsetY = m_cachedOverlayScrollbarOffset.y();
   2329     }
   2330 
   2331     // Move the scrollbar widgets if necessary.  We normally move and resize widgets during layout, but sometimes
   2332     // widgets can move without layout occurring (most notably when you scroll a document that
   2333     // contains fixed positioned elements).
   2334     positionOverflowControls(offsetX, offsetY);
   2335 
   2336     // Now that we're sure the scrollbars are in the right place, paint them.
   2337     if (m_hBar
   2338 #if USE(ACCELERATED_COMPOSITING)
   2339         && !layerForHorizontalScrollbar()
   2340 #endif
   2341               )
   2342         m_hBar->paint(context, damageRect);
   2343     if (m_vBar
   2344 #if USE(ACCELERATED_COMPOSITING)
   2345         && !layerForVerticalScrollbar()
   2346 #endif
   2347               )
   2348         m_vBar->paint(context, damageRect);
   2349 
   2350 #if USE(ACCELERATED_COMPOSITING)
   2351     if (layerForScrollCorner())
   2352         return;
   2353 #endif
   2354 
   2355     // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
   2356     // edge of the box.
   2357     paintScrollCorner(context, offsetX, offsetY, damageRect);
   2358 
   2359     // Paint our resizer last, since it sits on top of the scroll corner.
   2360     paintResizer(context, offsetX, offsetY, damageRect);
   2361 }
   2362 
   2363 void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
   2364 {
   2365     RenderBox* box = renderBox();
   2366     ASSERT(box);
   2367 
   2368     IntRect cornerRect = scrollCornerRect();
   2369     IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height());
   2370     if (!absRect.intersects(damageRect))
   2371         return;
   2372 
   2373     if (context->updatingControlTints()) {
   2374         updateScrollCornerStyle();
   2375         return;
   2376     }
   2377 
   2378     if (m_scrollCorner) {
   2379         m_scrollCorner->paintIntoRect(context, tx, ty, absRect);
   2380         return;
   2381     }
   2382 
   2383     // We don't want to paint white if we have overlay scrollbars, since we need
   2384     // to see what is behind it.
   2385     if (!hasOverlayScrollbars())
   2386         context->fillRect(absRect, Color::white, box->style()->colorSpace());
   2387 }
   2388 
   2389 void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
   2390 {
   2391     if (renderer()->style()->resize() == RESIZE_NONE)
   2392         return;
   2393 
   2394     RenderBox* box = renderBox();
   2395     ASSERT(box);
   2396 
   2397     IntRect cornerRect = resizerCornerRect(this, box->borderBoxRect());
   2398     IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height());
   2399     if (!absRect.intersects(damageRect))
   2400         return;
   2401 
   2402     if (context->updatingControlTints()) {
   2403         updateResizerStyle();
   2404         return;
   2405     }
   2406 
   2407     if (m_resizer) {
   2408         m_resizer->paintIntoRect(context, tx, ty, absRect);
   2409         return;
   2410     }
   2411 
   2412     // Paint the resizer control.
   2413     DEFINE_STATIC_LOCAL(RefPtr<Image>, resizeCornerImage, (Image::loadPlatformResource("textAreaResizeCorner")));
   2414     IntPoint imagePoint(absRect.maxX() - resizeCornerImage->width(), absRect.maxY() - resizeCornerImage->height());
   2415     context->drawImage(resizeCornerImage.get(), box->style()->colorSpace(), imagePoint);
   2416 
   2417     // Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
   2418     // Clipping will exclude the right and bottom edges of this frame.
   2419     if (!hasOverlayScrollbars() && (m_vBar || m_hBar)) {
   2420         context->save();
   2421         context->clip(absRect);
   2422         IntRect largerCorner = absRect;
   2423         largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1));
   2424         context->setStrokeColor(Color(makeRGB(217, 217, 217)), ColorSpaceDeviceRGB);
   2425         context->setStrokeThickness(1.0f);
   2426         context->setFillColor(Color::transparent, ColorSpaceDeviceRGB);
   2427         context->drawRect(largerCorner);
   2428         context->restore();
   2429     }
   2430 }
   2431 
   2432 bool RenderLayer::isPointInResizeControl(const IntPoint& absolutePoint) const
   2433 {
   2434     if (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE)
   2435         return false;
   2436 
   2437     RenderBox* box = renderBox();
   2438     ASSERT(box);
   2439 
   2440     IntPoint localPoint = absoluteToContents(absolutePoint);
   2441 
   2442     IntRect localBounds(0, 0, box->width(), box->height());
   2443     return resizerCornerRect(this, localBounds).contains(localPoint);
   2444 }
   2445 
   2446 bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const IntPoint& localPoint)
   2447 {
   2448     if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
   2449         return false;
   2450 
   2451     RenderBox* box = renderBox();
   2452     ASSERT(box);
   2453 
   2454     IntRect resizeControlRect;
   2455     if (renderer()->style()->resize() != RESIZE_NONE) {
   2456         resizeControlRect = resizerCornerRect(this, box->borderBoxRect());
   2457         if (resizeControlRect.contains(localPoint))
   2458             return true;
   2459     }
   2460 
   2461     int resizeControlSize = max(resizeControlRect.height(), 0);
   2462 
   2463     if (m_vBar) {
   2464         IntRect vBarRect(box->width() - box->borderRight() - m_vBar->width(),
   2465                          box->borderTop(),
   2466                          m_vBar->width(),
   2467                          box->height() - (box->borderTop() + box->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
   2468         if (vBarRect.contains(localPoint)) {
   2469             result.setScrollbar(m_vBar.get());
   2470             return true;
   2471         }
   2472     }
   2473 
   2474     resizeControlSize = max(resizeControlRect.width(), 0);
   2475     if (m_hBar) {
   2476         IntRect hBarRect(box->borderLeft(),
   2477                          box->height() - box->borderBottom() - m_hBar->height(),
   2478                          box->width() - (box->borderLeft() + box->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
   2479                          m_hBar->height());
   2480         if (hBarRect.contains(localPoint)) {
   2481             result.setScrollbar(m_hBar.get());
   2482             return true;
   2483         }
   2484     }
   2485 
   2486     return false;
   2487 }
   2488 
   2489 bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
   2490 {
   2491     return ScrollableArea::scroll(direction, granularity, multiplier);
   2492 }
   2493 
   2494 void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot)
   2495 {
   2496     OverlapTestRequestMap overlapTestRequests;
   2497     paintLayer(this, p, damageRect, paintBehavior, paintingRoot, &overlapTestRequests);
   2498     OverlapTestRequestMap::iterator end = overlapTestRequests.end();
   2499     for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
   2500         it->first->setOverlapTestResult(false);
   2501 }
   2502 
   2503 void RenderLayer::paintOverlayScrollbars(GraphicsContext* p, const IntRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot)
   2504 {
   2505     if (!m_containsDirtyOverlayScrollbars)
   2506         return;
   2507     paintLayer(this, p, damageRect, paintBehavior, paintingRoot, 0, PaintLayerHaveTransparency | PaintLayerTemporaryClipRects
   2508                | PaintLayerPaintingOverlayScrollbars);
   2509     m_containsDirtyOverlayScrollbars = false;
   2510 }
   2511 
   2512 static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
   2513 {
   2514     if (paintDirtyRect == clipRect)
   2515         return;
   2516     p->save();
   2517     p->clip(clipRect);
   2518 }
   2519 
   2520 static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
   2521 {
   2522     if (paintDirtyRect == clipRect)
   2523         return;
   2524     p->restore();
   2525 }
   2526 
   2527 static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)
   2528 {
   2529     Vector<OverlapTestRequestClient*> overlappedRequestClients;
   2530     OverlapTestRequestMap::iterator end = overlapTestRequests.end();
   2531     IntRect boundingBox = layer->boundingBox(rootLayer);
   2532     for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) {
   2533         if (!boundingBox.intersects(it->second))
   2534             continue;
   2535 
   2536         it->first->setOverlapTestResult(true);
   2537         overlappedRequestClients.append(it->first);
   2538     }
   2539     for (size_t i = 0; i < overlappedRequestClients.size(); ++i)
   2540         overlapTestRequests.remove(overlappedRequestClients[i]);
   2541 }
   2542 
   2543 #if USE(ACCELERATED_COMPOSITING)
   2544 static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection)
   2545 {
   2546     return paintingReflection && !layer->has3DTransform();
   2547 }
   2548 #endif
   2549 
   2550 void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
   2551                         const IntRect& paintDirtyRect, PaintBehavior paintBehavior,
   2552                         RenderObject* paintingRoot, OverlapTestRequestMap* overlapTestRequests,
   2553                         PaintLayerFlags paintFlags)
   2554 {
   2555 #if USE(ACCELERATED_COMPOSITING)
   2556     if (isComposited()) {
   2557         // The updatingControlTints() painting pass goes through compositing layers,
   2558         // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
   2559         if (p->updatingControlTints() || (paintBehavior & PaintBehaviorFlattenCompositingLayers))
   2560             paintFlags |= PaintLayerTemporaryClipRects;
   2561         else if (!backing()->paintingGoesToWindow() && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)) {
   2562             // If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
   2563             return;
   2564         }
   2565     }
   2566 #endif
   2567 
   2568     // Avoid painting layers when stylesheets haven't loaded.  This eliminates FOUC.
   2569     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
   2570     // will do a full repaint().
   2571     if (renderer()->document()->didLayoutWithPendingStylesheets() && !renderer()->isRenderView() && !renderer()->isRoot())
   2572         return;
   2573 
   2574     // If this layer is totally invisible then there is nothing to paint.
   2575     if (!renderer()->opacity())
   2576         return;
   2577 
   2578     if (paintsWithTransparency(paintBehavior))
   2579         paintFlags |= PaintLayerHaveTransparency;
   2580 
   2581     // Apply a transform if we have one.  A reflection is considered to be a transform, since it is a flip and a translate.
   2582     if (paintsWithTransform(paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
   2583         TransformationMatrix layerTransform = renderableTransform(paintBehavior);
   2584         // If the transform can't be inverted, then don't paint anything.
   2585         if (!layerTransform.isInvertible())
   2586             return;
   2587 
   2588         // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
   2589         // layer from the parent now.
   2590         if (paintFlags & PaintLayerHaveTransparency)
   2591             parent()->beginTransparencyLayers(p, rootLayer, paintBehavior);
   2592 
   2593         // Make sure the parent's clip rects have been calculated.
   2594         IntRect clipRect = paintDirtyRect;
   2595         if (parent()) {
   2596             clipRect = backgroundClipRect(rootLayer, paintFlags & PaintLayerTemporaryClipRects);
   2597             clipRect.intersect(paintDirtyRect);
   2598         }
   2599 
   2600         // Push the parent coordinate space's clip.
   2601         setClip(p, paintDirtyRect, clipRect);
   2602 
   2603         // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
   2604         // This involves subtracting out the position of the layer in our current coordinate space.
   2605         int x = 0;
   2606         int y = 0;
   2607         convertToLayerCoords(rootLayer, x, y);
   2608         TransformationMatrix transform(layerTransform);
   2609         transform.translateRight(x, y);
   2610 
   2611         // Apply the transform.
   2612         p->save();
   2613         p->concatCTM(transform.toAffineTransform());
   2614 
   2615         // Now do a paint with the root layer shifted to be us.
   2616         paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
   2617 
   2618         p->restore();
   2619 
   2620         // Restore the clip.
   2621         restoreClip(p, paintDirtyRect, clipRect);
   2622 
   2623         return;
   2624     }
   2625 
   2626     PaintLayerFlags localPaintFlags = paintFlags & ~PaintLayerAppliedTransform;
   2627     bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency;
   2628 
   2629     // Paint the reflection first if we have one.
   2630     if (m_reflection && !m_paintingInsideReflection) {
   2631         // Mark that we are now inside replica painting.
   2632         m_paintingInsideReflection = true;
   2633         reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection);
   2634         m_paintingInsideReflection = false;
   2635     }
   2636 
   2637     // Calculate the clip rects we should use.
   2638     IntRect layerBounds, damageRect, clipRectToApply, outlineRect;
   2639     calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, localPaintFlags & PaintLayerTemporaryClipRects);
   2640     int x = layerBounds.x();
   2641     int y = layerBounds.y();
   2642     int tx = x - renderBoxX();
   2643     int ty = y - renderBoxY();
   2644 
   2645     // Ensure our lists are up-to-date.
   2646     updateCompositingAndLayerListsIfNeeded();
   2647 
   2648     bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText;
   2649     bool selectionOnly  = paintBehavior & PaintBehaviorSelectionOnly;
   2650 
   2651     // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
   2652     // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
   2653     // Else, our renderer tree may or may not contain the painting root, so we pass that root along
   2654     // so it will be tested against as we descend through the renderers.
   2655     RenderObject* paintingRootForRenderer = 0;
   2656     if (paintingRoot && !renderer()->isDescendantOf(paintingRoot))
   2657         paintingRootForRenderer = paintingRoot;
   2658 
   2659     if (overlapTestRequests && isSelfPaintingLayer())
   2660         performOverlapTests(*overlapTestRequests, rootLayer, this);
   2661 
   2662     bool paintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
   2663 
   2664     // We want to paint our layer, but only if we intersect the damage rect.
   2665     bool shouldPaint = intersectsDamageRect(layerBounds, damageRect, rootLayer) && m_hasVisibleContent && isSelfPaintingLayer();
   2666     if (shouldPaint && !selectionOnly && !damageRect.isEmpty() && !paintingOverlayScrollbars) {
   2667         // Begin transparency layers lazily now that we know we have to paint something.
   2668         if (haveTransparency)
   2669             beginTransparencyLayers(p, rootLayer, paintBehavior);
   2670 
   2671         // Paint our background first, before painting any child layers.
   2672         // Establish the clip used to paint our background.
   2673         setClip(p, paintDirtyRect, damageRect);
   2674 
   2675         // Paint the background.
   2676         PaintInfo paintInfo(p, damageRect, PaintPhaseBlockBackground, false, paintingRootForRenderer, 0);
   2677         renderer()->paint(paintInfo, tx, ty);
   2678 
   2679         // Restore the clip.
   2680         restoreClip(p, paintDirtyRect, damageRect);
   2681     }
   2682 
   2683     // Now walk the sorted list of children with negative z-indices.
   2684     paintList(m_negZOrderList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
   2685 
   2686     // Now establish the appropriate clip and paint our child RenderObjects.
   2687     if (shouldPaint && !clipRectToApply.isEmpty() && !paintingOverlayScrollbars) {
   2688         // Begin transparency layers lazily now that we know we have to paint something.
   2689         if (haveTransparency)
   2690             beginTransparencyLayers(p, rootLayer, paintBehavior);
   2691 
   2692         // Set up the clip used when painting our children.
   2693         setClip(p, paintDirtyRect, clipRectToApply);
   2694         PaintInfo paintInfo(p, clipRectToApply,
   2695                                           selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds,
   2696                                           forceBlackText, paintingRootForRenderer, 0);
   2697         renderer()->paint(paintInfo, tx, ty);
   2698         if (!selectionOnly) {
   2699             paintInfo.phase = PaintPhaseFloat;
   2700             renderer()->paint(paintInfo, tx, ty);
   2701             paintInfo.phase = PaintPhaseForeground;
   2702             paintInfo.overlapTestRequests = overlapTestRequests;
   2703             renderer()->paint(paintInfo, tx, ty);
   2704             paintInfo.phase = PaintPhaseChildOutlines;
   2705             renderer()->paint(paintInfo, tx, ty);
   2706         }
   2707 
   2708         // Now restore our clip.
   2709         restoreClip(p, paintDirtyRect, clipRectToApply);
   2710     }
   2711 
   2712     if (!outlineRect.isEmpty() && isSelfPaintingLayer() && !paintingOverlayScrollbars) {
   2713         // Paint our own outline
   2714         PaintInfo paintInfo(p, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0);
   2715         setClip(p, paintDirtyRect, outlineRect);
   2716         renderer()->paint(paintInfo, tx, ty);
   2717         restoreClip(p, paintDirtyRect, outlineRect);
   2718     }
   2719 
   2720     // Paint any child layers that have overflow.
   2721     paintList(m_normalFlowList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
   2722 
   2723     // Now walk the sorted list of children with positive z-indices.
   2724     paintList(m_posZOrderList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
   2725 
   2726     if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty() && !paintingOverlayScrollbars) {
   2727         setClip(p, paintDirtyRect, damageRect);
   2728 
   2729         // Paint the mask.
   2730         PaintInfo paintInfo(p, damageRect, PaintPhaseMask, false, paintingRootForRenderer, 0);
   2731         renderer()->paint(paintInfo, tx, ty);
   2732 
   2733         // Restore the clip.
   2734         restoreClip(p, paintDirtyRect, damageRect);
   2735     }
   2736 
   2737     if (paintingOverlayScrollbars) {
   2738         setClip(p, paintDirtyRect, damageRect);
   2739         paintOverflowControls(p, tx, ty, damageRect, true);
   2740         restoreClip(p, paintDirtyRect, damageRect);
   2741     }
   2742 
   2743     // End our transparency layer
   2744     if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) {
   2745         p->endTransparencyLayer();
   2746         p->restore();
   2747         m_usedTransparency = false;
   2748     }
   2749 }
   2750 
   2751 void RenderLayer::paintList(Vector<RenderLayer*>* list, RenderLayer* rootLayer, GraphicsContext* p,
   2752                             const IntRect& paintDirtyRect, PaintBehavior paintBehavior,
   2753                             RenderObject* paintingRoot, OverlapTestRequestMap* overlapTestRequests,
   2754                             PaintLayerFlags paintFlags)
   2755 {
   2756     if (!list)
   2757         return;
   2758 
   2759     for (size_t i = 0; i < list->size(); ++i) {
   2760         RenderLayer* childLayer = list->at(i);
   2761         if (!childLayer->isPaginated())
   2762             childLayer->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, paintFlags);
   2763         else
   2764             paintPaginatedChildLayer(childLayer, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, paintFlags);
   2765     }
   2766 }
   2767 
   2768 void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, GraphicsContext* context,
   2769                                            const IntRect& paintDirtyRect, PaintBehavior paintBehavior,
   2770                                            RenderObject* paintingRoot, OverlapTestRequestMap* overlapTestRequests,
   2771                                            PaintLayerFlags paintFlags)
   2772 {
   2773     // We need to do multiple passes, breaking up our child layer into strips.
   2774     Vector<RenderLayer*> columnLayers;
   2775     RenderLayer* ancestorLayer = isNormalFlowOnly() ? parent() : stackingContext();
   2776     for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
   2777         if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
   2778             columnLayers.append(curr);
   2779         if (curr == ancestorLayer)
   2780             break;
   2781     }
   2782 
   2783     ASSERT(columnLayers.size());
   2784 
   2785     paintChildLayerIntoColumns(childLayer, rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, paintFlags, columnLayers, columnLayers.size() - 1);
   2786 }
   2787 
   2788 void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLayer* rootLayer, GraphicsContext* context,
   2789                                              const IntRect& paintDirtyRect, PaintBehavior paintBehavior,
   2790                                              RenderObject* paintingRoot, OverlapTestRequestMap* overlapTestRequests,
   2791                                              PaintLayerFlags paintFlags, const Vector<RenderLayer*>& columnLayers, size_t colIndex)
   2792 {
   2793     RenderBlock* columnBlock = toRenderBlock(columnLayers[colIndex]->renderer());
   2794 
   2795     ASSERT(columnBlock && columnBlock->hasColumns());
   2796     if (!columnBlock || !columnBlock->hasColumns())
   2797         return;
   2798 
   2799     int layerX = 0;
   2800     int layerY = 0;
   2801     columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
   2802 
   2803     bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
   2804 
   2805     ColumnInfo* colInfo = columnBlock->columnInfo();
   2806     unsigned colCount = columnBlock->columnCount(colInfo);
   2807     int currLogicalTopOffset = 0;
   2808     for (unsigned i = 0; i < colCount; i++) {
   2809         // For each rect, we clip to the rect, and then we adjust our coords.
   2810         IntRect colRect = columnBlock->columnRectAt(colInfo, i);
   2811         columnBlock->flipForWritingMode(colRect);
   2812         int logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
   2813         IntSize offset = isHorizontal ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
   2814 
   2815         colRect.move(layerX, layerY);
   2816 
   2817         IntRect localDirtyRect(paintDirtyRect);
   2818         localDirtyRect.intersect(colRect);
   2819 
   2820         if (!localDirtyRect.isEmpty()) {
   2821             context->save();
   2822 
   2823             // Each strip pushes a clip, since column boxes are specified as being
   2824             // like overflow:hidden.
   2825             context->clip(colRect);
   2826 
   2827             if (!colIndex) {
   2828                 // Apply a translation transform to change where the layer paints.
   2829                 TransformationMatrix oldTransform;
   2830                 bool oldHasTransform = childLayer->transform();
   2831                 if (oldHasTransform)
   2832                     oldTransform = *childLayer->transform();
   2833                 TransformationMatrix newTransform(oldTransform);
   2834                 newTransform.translateRight(offset.width(), offset.height());
   2835 
   2836                 childLayer->m_transform.set(new TransformationMatrix(newTransform));
   2837                 childLayer->paintLayer(rootLayer, context, localDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, paintFlags);
   2838                 if (oldHasTransform)
   2839                     childLayer->m_transform.set(new TransformationMatrix(oldTransform));
   2840                 else
   2841                     childLayer->m_transform.clear();
   2842             } else {
   2843                 // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
   2844                 // This involves subtracting out the position of the layer in our current coordinate space.
   2845                 int childX = 0;
   2846                 int childY = 0;
   2847                 columnLayers[colIndex - 1]->convertToLayerCoords(rootLayer, childX, childY);
   2848                 TransformationMatrix transform;
   2849                 transform.translateRight(childX + offset.width(), childY + offset.height());
   2850 
   2851                 // Apply the transform.
   2852                 context->concatCTM(transform.toAffineTransform());
   2853 
   2854                 // Now do a paint with the root layer shifted to be the next multicol block.
   2855                 paintChildLayerIntoColumns(childLayer, columnLayers[colIndex - 1], context, transform.inverse().mapRect(localDirtyRect), paintBehavior,
   2856                                            paintingRoot, overlapTestRequests, paintFlags,
   2857                                            columnLayers, colIndex - 1);
   2858             }
   2859 
   2860             context->restore();
   2861         }
   2862 
   2863         // Move to the next position.
   2864         int blockDelta = isHorizontal ? colRect.height() : colRect.width();
   2865         if (columnBlock->style()->isFlippedBlocksWritingMode())
   2866             currLogicalTopOffset += blockDelta;
   2867         else
   2868             currLogicalTopOffset -= blockDelta;
   2869     }
   2870 }
   2871 
   2872 static inline IntRect frameVisibleRect(RenderObject* renderer)
   2873 {
   2874     FrameView* frameView = renderer->document()->view();
   2875     if (!frameView)
   2876         return IntRect();
   2877 
   2878     return frameView->visibleContentRect();
   2879 }
   2880 
   2881 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
   2882 {
   2883     renderer()->document()->updateLayout();
   2884 
   2885     IntRect hitTestArea = renderer()->view()->documentRect();
   2886     if (!request.ignoreClipping())
   2887         hitTestArea.intersect(frameVisibleRect(renderer()));
   2888 
   2889     RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, result.point(), false);
   2890     if (!insideLayer) {
   2891         // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
   2892         // return ourselves. We do this so mouse events continue getting delivered after a drag has
   2893         // exited the WebView, and so hit testing over a scrollbar hits the content document.
   2894         if ((request.active() || request.mouseUp()) && renderer()->isRenderView()) {
   2895             renderer()->updateHitTestResult(result, result.point());
   2896             insideLayer = this;
   2897         }
   2898     }
   2899 
   2900     // Now determine if the result is inside an anchor - if the urlElement isn't already set.
   2901     Node* node = result.innerNode();
   2902     if (node && !result.URLElement())
   2903         result.setURLElement(static_cast<Element*>(node->enclosingLinkEventParentOrSelf()));
   2904 
   2905     // Next set up the correct :hover/:active state along the new chain.
   2906     updateHoverActiveState(request, result);
   2907 
   2908     // Now return whether we were inside this layer (this will always be true for the root
   2909     // layer).
   2910     return insideLayer;
   2911 }
   2912 
   2913 Node* RenderLayer::enclosingElement() const
   2914 {
   2915     for (RenderObject* r = renderer(); r; r = r->parent()) {
   2916         if (Node* e = r->node())
   2917             return e;
   2918     }
   2919     ASSERT_NOT_REACHED();
   2920     return 0;
   2921 }
   2922 
   2923 // Compute the z-offset of the point in the transformState.
   2924 // This is effectively projecting a ray normal to the plane of ancestor, finding where that
   2925 // ray intersects target, and computing the z delta between those two points.
   2926 static double computeZOffset(const HitTestingTransformState& transformState)
   2927 {
   2928     // We got an affine transform, so no z-offset
   2929     if (transformState.m_accumulatedTransform.isAffine())
   2930         return 0;
   2931 
   2932     // Flatten the point into the target plane
   2933     FloatPoint targetPoint = transformState.mappedPoint();
   2934 
   2935     // Now map the point back through the transform, which computes Z.
   2936     FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint));
   2937     return backmappedPoint.z();
   2938 }
   2939 
   2940 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
   2941                                         const IntRect& hitTestRect, const IntPoint& hitTestPoint,
   2942                                         const HitTestingTransformState* containerTransformState) const
   2943 {
   2944     RefPtr<HitTestingTransformState> transformState;
   2945     int offsetX = 0;
   2946     int offsetY = 0;
   2947     if (containerTransformState) {
   2948         // If we're already computing transform state, then it's relative to the container (which we know is non-null).
   2949         transformState = HitTestingTransformState::create(*containerTransformState);
   2950         convertToLayerCoords(containerLayer, offsetX, offsetY);
   2951     } else {
   2952         // If this is the first time we need to make transform state, then base it off of hitTestPoint,
   2953         // which is relative to rootLayer.
   2954         transformState = HitTestingTransformState::create(hitTestPoint, FloatQuad(hitTestRect));
   2955         convertToLayerCoords(rootLayer, offsetX, offsetY);
   2956     }
   2957 
   2958     RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0;
   2959     if (renderer()->shouldUseTransformFromContainer(containerRenderer)) {
   2960         TransformationMatrix containerTransform;
   2961         renderer()->getTransformFromContainer(containerRenderer, IntSize(offsetX, offsetY), containerTransform);
   2962         transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform);
   2963     } else {
   2964         transformState->translate(offsetX, offsetY, HitTestingTransformState::AccumulateTransform);
   2965     }
   2966 
   2967     return transformState;
   2968 }
   2969 
   2970 
   2971 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState)
   2972 {
   2973     if (!hitLayer)
   2974         return false;
   2975 
   2976     // The hit layer is depth-sorting with other layers, so just say that it was hit.
   2977     if (canDepthSort)
   2978         return true;
   2979 
   2980     // We need to look at z-depth to decide if this layer was hit.
   2981     if (zOffset) {
   2982         ASSERT(transformState);
   2983         // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
   2984         double childZOffset = computeZOffset(*transformState);
   2985         if (childZOffset > *zOffset) {
   2986             *zOffset = childZOffset;
   2987             return true;
   2988         }
   2989         return false;
   2990     }
   2991 
   2992     return true;
   2993 }
   2994 
   2995 // hitTestPoint and hitTestRect are relative to rootLayer.
   2996 // A 'flattening' layer is one preserves3D() == false.
   2997 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
   2998 // transformState.m_lastPlanarPoint is the hitTestPoint in the plane of the containing flattening layer.
   2999 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
   3000 //
   3001 // If zOffset is non-null (which indicates that the caller wants z offset information),
   3002 //  *zOffset on return is the z offset of the hit point relative to the containing flattening layer.
   3003 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
   3004                                        const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform,
   3005                                        const HitTestingTransformState* transformState, double* zOffset)
   3006 {
   3007     // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
   3008 
   3009     bool useTemporaryClipRects = false;
   3010 #if USE(ACCELERATED_COMPOSITING)
   3011     useTemporaryClipRects = compositor()->inCompositingMode();
   3012 #endif
   3013     useTemporaryClipRects |= renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
   3014 
   3015     IntRect hitTestArea = result.rectForPoint(hitTestPoint);
   3016 
   3017     // Apply a transform if we have one.
   3018     if (transform() && !appliedTransform) {
   3019         // Make sure the parent's clip rects have been calculated.
   3020         if (parent()) {
   3021             IntRect clipRect = backgroundClipRect(rootLayer, useTemporaryClipRects, IncludeOverlayScrollbarSize);
   3022             // Go ahead and test the enclosing clip now.
   3023             if (!clipRect.intersects(hitTestArea))
   3024                 return 0;
   3025         }
   3026 
   3027         // Create a transform state to accumulate this transform.
   3028         RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestPoint, transformState);
   3029 
   3030         // If the transform can't be inverted, then don't hit test this layer at all.
   3031         if (!newTransformState->m_accumulatedTransform.isInvertible())
   3032             return 0;
   3033 
   3034         // Compute the point and the hit test rect in the coords of this layer by using the values
   3035         // from the transformState, which store the point and quad in the coords of the last flattened
   3036         // layer, and the accumulated transform which lets up map through preserve-3d layers.
   3037         //
   3038         // We can't just map hitTestPoint and hitTestRect because they may have been flattened (losing z)
   3039         // by our container.
   3040         IntPoint localPoint = roundedIntPoint(newTransformState->mappedPoint());
   3041         IntRect localHitTestRect;
   3042 #if USE(ACCELERATED_COMPOSITING)
   3043         if (isComposited()) {
   3044             // It doesn't make sense to project hitTestRect into the plane of this layer, so use the same bounds we use for painting.
   3045             localHitTestRect = backing()->compositedBounds();
   3046         } else
   3047 #endif
   3048             localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
   3049 
   3050         // Now do a hit test with the root layer shifted to be us.
   3051         return hitTestLayer(this, containerLayer, request, result, localHitTestRect, localPoint, true, newTransformState.get(), zOffset);
   3052     }
   3053 
   3054     // Ensure our lists and 3d status are up-to-date.
   3055     updateCompositingAndLayerListsIfNeeded();
   3056     update3DTransformedDescendantStatus();
   3057 
   3058     RefPtr<HitTestingTransformState> localTransformState;
   3059     if (appliedTransform) {
   3060         // We computed the correct state in the caller (above code), so just reference it.
   3061         ASSERT(transformState);
   3062         localTransformState = const_cast<HitTestingTransformState*>(transformState);
   3063     } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
   3064         // We need transform state for the first time, or to offset the container state, so create it here.
   3065         localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestPoint, transformState);
   3066     }
   3067 
   3068     // Check for hit test on backface if backface-visibility is 'hidden'
   3069     if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
   3070         TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse();
   3071         // If the z-vector of the matrix is negative, the back is facing towards the viewer.
   3072         if (invertedMatrix.m33() < 0)
   3073             return 0;
   3074     }
   3075 
   3076     RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
   3077     if (localTransformState && !preserves3D()) {
   3078         // Keep a copy of the pre-flattening state, for computing z-offsets for the container
   3079         unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
   3080         // This layer is flattening, so flatten the state passed to descendants.
   3081         localTransformState->flatten();
   3082     }
   3083 
   3084     // Calculate the clip rects we should use.
   3085     IntRect layerBounds;
   3086     IntRect bgRect;
   3087     IntRect fgRect;
   3088     IntRect outlineRect;
   3089     calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, useTemporaryClipRects, IncludeOverlayScrollbarSize);
   3090 
   3091     // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
   3092     // descendants.
   3093     double localZOffset = -numeric_limits<double>::infinity();
   3094     double* zOffsetForDescendantsPtr = 0;
   3095     double* zOffsetForContentsPtr = 0;
   3096 
   3097     bool depthSortDescendants = false;
   3098     if (preserves3D()) {
   3099         depthSortDescendants = true;
   3100         // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
   3101         zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
   3102         zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
   3103     } else if (m_has3DTransformedDescendant) {
   3104         // Flattening layer with 3d children; use a local zOffset pointer to depth-test children and foreground.
   3105         depthSortDescendants = true;
   3106         zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
   3107         zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
   3108     } else if (zOffset) {
   3109         zOffsetForDescendantsPtr = 0;
   3110         // Container needs us to give back a z offset for the hit layer.
   3111         zOffsetForContentsPtr = zOffset;
   3112     }
   3113 
   3114     // This variable tracks which layer the mouse ends up being inside.
   3115     RenderLayer* candidateLayer = 0;
   3116 
   3117     // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
   3118     RenderLayer* hitLayer = hitTestList(m_posZOrderList, rootLayer, request, result, hitTestRect, hitTestPoint,
   3119                                         localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
   3120     if (hitLayer) {
   3121         if (!depthSortDescendants)
   3122             return hitLayer;
   3123         candidateLayer = hitLayer;
   3124     }
   3125 
   3126     // Now check our overflow objects.
   3127     hitLayer = hitTestList(m_normalFlowList, rootLayer, request, result, hitTestRect, hitTestPoint,
   3128                            localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
   3129     if (hitLayer) {
   3130         if (!depthSortDescendants)
   3131             return hitLayer;
   3132         candidateLayer = hitLayer;
   3133     }
   3134 
   3135 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   3136     if (hasOverflowParent()) {
   3137         ClipRects clipRects;
   3138         calculateClipRects(rootLayer, clipRects, useTemporaryClipRects);
   3139         fgRect.intersect(clipRects.hitTestClip());
   3140         bgRect.intersect(clipRects.hitTestClip());
   3141     }
   3142 #endif
   3143     // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
   3144     if (fgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
   3145         // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
   3146         HitTestResult tempResult(result.point(), result.topPadding(), result.rightPadding(), result.bottomPadding(), result.leftPadding());
   3147         if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) &&
   3148             isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
   3149             if (result.isRectBasedTest())
   3150                 result.append(tempResult);
   3151             else
   3152                 result = tempResult;
   3153             if (!depthSortDescendants)
   3154                 return this;
   3155             // Foreground can depth-sort with descendant layers, so keep this as a candidate.
   3156             candidateLayer = this;
   3157         } else if (result.isRectBasedTest())
   3158             result.append(tempResult);
   3159     }
   3160 
   3161     // Now check our negative z-index children.
   3162     hitLayer = hitTestList(m_negZOrderList, rootLayer, request, result, hitTestRect, hitTestPoint,
   3163                                         localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
   3164     if (hitLayer) {
   3165         if (!depthSortDescendants)
   3166             return hitLayer;
   3167         candidateLayer = hitLayer;
   3168     }
   3169 
   3170     // If we found a layer, return. Child layers, and foreground always render in front of background.
   3171     if (candidateLayer)
   3172         return candidateLayer;
   3173 
   3174     if (bgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
   3175         HitTestResult tempResult(result.point(), result.topPadding(), result.rightPadding(), result.bottomPadding(), result.leftPadding());
   3176         if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestSelf) &&
   3177             isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
   3178             if (result.isRectBasedTest())
   3179                 result.append(tempResult);
   3180             else
   3181                 result = tempResult;
   3182             return this;
   3183         } else if (result.isRectBasedTest())
   3184             result.append(tempResult);
   3185     }
   3186 
   3187     return 0;
   3188 }
   3189 
   3190 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const IntRect& layerBounds, const IntPoint& hitTestPoint, HitTestFilter hitTestFilter) const
   3191 {
   3192     if (!renderer()->hitTest(request, result, hitTestPoint,
   3193                             layerBounds.x() - renderBoxX(),
   3194                             layerBounds.y() - renderBoxY(),
   3195                             hitTestFilter)) {
   3196         // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is
   3197         // a rect-based test.
   3198         ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size()));
   3199         return false;
   3200     }
   3201 
   3202     // For positioned generated content, we might still not have a
   3203     // node by the time we get to the layer level, since none of
   3204     // the content in the layer has an element. So just walk up
   3205     // the tree.
   3206     if (!result.innerNode() || !result.innerNonSharedNode()) {
   3207         Node* e = enclosingElement();
   3208         if (!result.innerNode())
   3209             result.setInnerNode(e);
   3210         if (!result.innerNonSharedNode())
   3211             result.setInnerNonSharedNode(e);
   3212     }
   3213 
   3214     return true;
   3215 }
   3216 
   3217 RenderLayer* RenderLayer::hitTestList(Vector<RenderLayer*>* list, RenderLayer* rootLayer,
   3218                                       const HitTestRequest& request, HitTestResult& result,
   3219                                       const IntRect& hitTestRect, const IntPoint& hitTestPoint,
   3220                                       const HitTestingTransformState* transformState,
   3221                                       double* zOffsetForDescendants, double* zOffset,
   3222                                       const HitTestingTransformState* unflattenedTransformState,
   3223                                       bool depthSortDescendants)
   3224 {
   3225     if (!list)
   3226         return 0;
   3227 
   3228     RenderLayer* resultLayer = 0;
   3229     for (int i = list->size() - 1; i >= 0; --i) {
   3230         RenderLayer* childLayer = list->at(i);
   3231         RenderLayer* hitLayer = 0;
   3232         HitTestResult tempResult(result.point(), result.topPadding(), result.rightPadding(), result.bottomPadding(), result.leftPadding());
   3233         if (childLayer->isPaginated())
   3234             hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestPoint, transformState, zOffsetForDescendants);
   3235         else
   3236             hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, transformState, zOffsetForDescendants);
   3237 
   3238         // If it a rect-based test, we can safely append the temporary result since it might had hit
   3239         // nodes but not necesserily had hitLayer set.
   3240         if (result.isRectBasedTest())
   3241             result.append(tempResult);
   3242 
   3243         if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
   3244             resultLayer = hitLayer;
   3245             if (!result.isRectBasedTest())
   3246                 result = tempResult;
   3247             if (!depthSortDescendants)
   3248                 break;
   3249         }
   3250     }
   3251 
   3252     return resultLayer;
   3253 }
   3254 
   3255 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
   3256                                                      const IntRect& hitTestRect, const IntPoint& hitTestPoint, const HitTestingTransformState* transformState, double* zOffset)
   3257 {
   3258     Vector<RenderLayer*> columnLayers;
   3259     RenderLayer* ancestorLayer = isNormalFlowOnly() ? parent() : stackingContext();
   3260     for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
   3261         if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
   3262             columnLayers.append(curr);
   3263         if (curr == ancestorLayer)
   3264             break;
   3265     }
   3266 
   3267     ASSERT(columnLayers.size());
   3268     return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitTestRect, hitTestPoint, transformState, zOffset,
   3269                                     columnLayers, columnLayers.size() - 1);
   3270 }
   3271 
   3272 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
   3273                                                    const IntRect& hitTestRect, const IntPoint& hitTestPoint, const HitTestingTransformState* transformState, double* zOffset,
   3274                                                    const Vector<RenderLayer*>& columnLayers, size_t columnIndex)
   3275 {
   3276     RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer());
   3277 
   3278     ASSERT(columnBlock && columnBlock->hasColumns());
   3279     if (!columnBlock || !columnBlock->hasColumns())
   3280         return 0;
   3281 
   3282     int layerX = 0;
   3283     int layerY = 0;
   3284     columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
   3285 
   3286     ColumnInfo* colInfo = columnBlock->columnInfo();
   3287     int colCount = columnBlock->columnCount(colInfo);
   3288 
   3289     // We have to go backwards from the last column to the first.
   3290     bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
   3291     int logicalLeft = columnBlock->logicalLeftOffsetForContent();
   3292     int currLogicalTopOffset = 0;
   3293     int i;
   3294     for (i = 0; i < colCount; i++) {
   3295         IntRect colRect = columnBlock->columnRectAt(colInfo, i);
   3296         int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
   3297         if (columnBlock->style()->isFlippedBlocksWritingMode())
   3298             currLogicalTopOffset += blockDelta;
   3299         else
   3300             currLogicalTopOffset -= blockDelta;
   3301     }
   3302     for (i = colCount - 1; i >= 0; i--) {
   3303         // For each rect, we clip to the rect, and then we adjust our coords.
   3304         IntRect colRect = columnBlock->columnRectAt(colInfo, i);
   3305         columnBlock->flipForWritingMode(colRect);
   3306         int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
   3307         int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
   3308         if (columnBlock->style()->isFlippedBlocksWritingMode())
   3309             currLogicalTopOffset -= blockDelta;
   3310         else
   3311             currLogicalTopOffset += blockDelta;
   3312         colRect.move(layerX, layerY);
   3313 
   3314         IntRect localClipRect(hitTestRect);
   3315         localClipRect.intersect(colRect);
   3316 
   3317         IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
   3318 
   3319         if (!localClipRect.isEmpty() && localClipRect.intersects(result.rectForPoint(hitTestPoint))) {
   3320             RenderLayer* hitLayer = 0;
   3321             if (!columnIndex) {
   3322                 // Apply a translation transform to change where the layer paints.
   3323                 TransformationMatrix oldTransform;
   3324                 bool oldHasTransform = childLayer->transform();
   3325                 if (oldHasTransform)
   3326                     oldTransform = *childLayer->transform();
   3327                 TransformationMatrix newTransform(oldTransform);
   3328                 newTransform.translateRight(offset.width(), offset.height());
   3329 
   3330                 childLayer->m_transform.set(new TransformationMatrix(newTransform));
   3331                 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestPoint, false, transformState, zOffset);
   3332                 if (oldHasTransform)
   3333                     childLayer->m_transform.set(new TransformationMatrix(oldTransform));
   3334                 else
   3335                     childLayer->m_transform.clear();
   3336             } else {
   3337                 // Adjust the transform such that the renderer's upper left corner will be at (0,0) in user space.
   3338                 // This involves subtracting out the position of the layer in our current coordinate space.
   3339                 RenderLayer* nextLayer = columnLayers[columnIndex - 1];
   3340                 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestPoint, transformState);
   3341                 newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
   3342                 IntPoint localPoint = roundedIntPoint(newTransformState->mappedPoint());
   3343                 IntRect localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
   3344                 newTransformState->flatten();
   3345 
   3346                 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[columnIndex - 1], request, result, localHitTestRect, localPoint,
   3347                                                     newTransformState.get(), zOffset, columnLayers, columnIndex - 1);
   3348             }
   3349 
   3350             if (hitLayer)
   3351                 return hitLayer;
   3352         }
   3353     }
   3354 
   3355     return 0;
   3356 }
   3357 
   3358 void RenderLayer::updateClipRects(const RenderLayer* rootLayer, OverlayScrollbarSizeRelevancy relevancy)
   3359 {
   3360     if (m_clipRects) {
   3361         ASSERT(rootLayer == m_clipRectsRoot);
   3362         return; // We have the correct cached value.
   3363     }
   3364 
   3365     // For transformed layers, the root layer was shifted to be us, so there is no need to
   3366     // examine the parent.  We want to cache clip rects with us as the root.
   3367     RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
   3368     if (parentLayer)
   3369         parentLayer->updateClipRects(rootLayer, relevancy);
   3370 
   3371     ClipRects clipRects;
   3372     calculateClipRects(rootLayer, clipRects, true, relevancy);
   3373 
   3374     if (parentLayer && parentLayer->clipRects() && clipRects == *parentLayer->clipRects())
   3375         m_clipRects = parentLayer->clipRects();
   3376     else
   3377         m_clipRects = new (renderer()->renderArena()) ClipRects(clipRects);
   3378     m_clipRects->ref();
   3379 #ifndef NDEBUG
   3380     m_clipRectsRoot = rootLayer;
   3381 #endif
   3382 }
   3383 
   3384 void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool useCached, OverlayScrollbarSizeRelevancy relevancy) const
   3385 {
   3386     if (!parent()) {
   3387         // The root layer's clip rect is always infinite.
   3388         clipRects.reset(PaintInfo::infiniteRect());
   3389         return;
   3390     }
   3391 
   3392     // For transformed layers, the root layer was shifted to be us, so there is no need to
   3393     // examine the parent.  We want to cache clip rects with us as the root.
   3394     RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
   3395 
   3396     // Ensure that our parent's clip has been calculated so that we can examine the values.
   3397     if (parentLayer) {
   3398         if (useCached && parentLayer->clipRects())
   3399             clipRects = *parentLayer->clipRects();
   3400         else
   3401             parentLayer->calculateClipRects(rootLayer, clipRects);
   3402     }
   3403     else
   3404         clipRects.reset(PaintInfo::infiniteRect());
   3405 
   3406     // A fixed object is essentially the root of its containing block hierarchy, so when
   3407     // we encounter such an object, we reset our clip rects to the fixedClipRect.
   3408     if (renderer()->style()->position() == FixedPosition) {
   3409         clipRects.setPosClipRect(clipRects.fixedClipRect());
   3410         clipRects.setOverflowClipRect(clipRects.fixedClipRect());
   3411         clipRects.setFixed(true);
   3412     }
   3413     else if (renderer()->style()->position() == RelativePosition)
   3414         clipRects.setPosClipRect(clipRects.overflowClipRect());
   3415     else if (renderer()->style()->position() == AbsolutePosition)
   3416         clipRects.setOverflowClipRect(clipRects.posClipRect());
   3417 
   3418     // Update the clip rects that will be passed to child layers.
   3419     if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
   3420         // This layer establishes a clip of some kind.
   3421         int x = 0;
   3422         int y = 0;
   3423         convertToLayerCoords(rootLayer, x, y);
   3424         RenderView* view = renderer()->view();
   3425         ASSERT(view);
   3426         if (view && clipRects.fixed() && rootLayer->renderer() == view) {
   3427             x -= view->frameView()->scrollXForFixedPosition();
   3428             y -= view->frameView()->scrollYForFixedPosition();
   3429         }
   3430 
   3431         if (renderer()->hasOverflowClip()) {
   3432             IntRect newOverflowClip = toRenderBox(renderer())->overflowClipRect(x, y, relevancy);
   3433 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   3434             clipRects.setHitTestClip(intersection(clipRects.fixed() ? clipRects.fixedClipRect()
   3435                     : newOverflowClip, clipRects.hitTestClip()));
   3436             if (hasOverflowScroll()) {
   3437                 RenderBox* box = toRenderBox(renderer());
   3438                 newOverflowClip =
   3439                     IntRect(x + box->borderLeft(), y + box->borderTop(),
   3440                             m_scrollWidth, m_scrollHeight);
   3441             }
   3442 #endif
   3443             clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
   3444             if (renderer()->isPositioned() || renderer()->isRelPositioned())
   3445                 clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
   3446         }
   3447         if (renderer()->hasClip()) {
   3448             IntRect newPosClip = toRenderBox(renderer())->clipRect(x, y);
   3449             clipRects.setPosClipRect(intersection(newPosClip, clipRects.posClipRect()));
   3450             clipRects.setOverflowClipRect(intersection(newPosClip, clipRects.overflowClipRect()));
   3451             clipRects.setFixedClipRect(intersection(newPosClip, clipRects.fixedClipRect()));
   3452         }
   3453     }
   3454 }
   3455 
   3456 void RenderLayer::parentClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
   3457 {
   3458     ASSERT(parent());
   3459     if (temporaryClipRects) {
   3460         parent()->calculateClipRects(rootLayer, clipRects, false, relevancy);
   3461         return;
   3462     }
   3463 
   3464     parent()->updateClipRects(rootLayer, relevancy);
   3465     clipRects = *parent()->clipRects();
   3466 }
   3467 
   3468 IntRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
   3469 {
   3470     IntRect backgroundRect;
   3471     if (parent()) {
   3472         ClipRects parentRects;
   3473         parentClipRects(rootLayer, parentRects, temporaryClipRects, relevancy);
   3474         backgroundRect = renderer()->style()->position() == FixedPosition ? parentRects.fixedClipRect() :
   3475                          (renderer()->isPositioned() ? parentRects.posClipRect() :
   3476                                                        parentRects.overflowClipRect());
   3477         RenderView* view = renderer()->view();
   3478         ASSERT(view);
   3479         if (view && parentRects.fixed() && rootLayer->renderer() == view)
   3480             backgroundRect.move(view->frameView()->scrollXForFixedPosition(), view->frameView()->scrollYForFixedPosition());
   3481     }
   3482     return backgroundRect;
   3483 }
   3484 
   3485 void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds,
   3486                                  IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects,
   3487                                  OverlayScrollbarSizeRelevancy relevancy) const
   3488 {
   3489     if (rootLayer != this && parent()) {
   3490         backgroundRect = backgroundClipRect(rootLayer, temporaryClipRects, relevancy);
   3491         backgroundRect.intersect(paintDirtyRect);
   3492     } else
   3493         backgroundRect = paintDirtyRect;
   3494 
   3495     foregroundRect = backgroundRect;
   3496     outlineRect = backgroundRect;
   3497 
   3498     int x = 0;
   3499     int y = 0;
   3500     convertToLayerCoords(rootLayer, x, y);
   3501     layerBounds = IntRect(x, y, width(), height());
   3502 
   3503     // Update the clip rects that will be passed to child layers.
   3504     if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
   3505         // This layer establishes a clip of some kind.
   3506 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   3507         if (hasOverflowScroll()) {
   3508             // Use the entire foreground rectangle to record the contents.
   3509             RenderBox* box = toRenderBox(renderer());
   3510             foregroundRect =
   3511                 IntRect(x + box->borderLeft(), y + box->borderTop(),
   3512                         m_scrollWidth, m_scrollHeight);
   3513         } else
   3514 #endif
   3515         if (renderer()->hasOverflowClip())
   3516             foregroundRect.intersect(toRenderBox(renderer())->overflowClipRect(x, y, relevancy));
   3517         if (renderer()->hasClip()) {
   3518             // Clip applies to *us* as well, so go ahead and update the damageRect.
   3519             IntRect newPosClip = toRenderBox(renderer())->clipRect(x, y);
   3520             backgroundRect.intersect(newPosClip);
   3521             foregroundRect.intersect(newPosClip);
   3522             outlineRect.intersect(newPosClip);
   3523         }
   3524 
   3525         // If we establish a clip at all, then go ahead and make sure our background
   3526         // rect is intersected with our layer's bounds.
   3527         // FIXME: This could be changed to just use generic visual overflow.
   3528         // See https://bugs.webkit.org/show_bug.cgi?id=37467 for more information.
   3529         if (const ShadowData* boxShadow = renderer()->style()->boxShadow()) {
   3530             IntRect overflow = layerBounds;
   3531             do {
   3532                 if (boxShadow->style() == Normal) {
   3533                     IntRect shadowRect = layerBounds;
   3534                     shadowRect.move(boxShadow->x(), boxShadow->y());
   3535                     shadowRect.inflate(boxShadow->blur() + boxShadow->spread());
   3536                     overflow.unite(shadowRect);
   3537                 }
   3538 
   3539                 boxShadow = boxShadow->next();
   3540             } while (boxShadow);
   3541             backgroundRect.intersect(overflow);
   3542         } else
   3543             backgroundRect.intersect(layerBounds);
   3544     }
   3545 }
   3546 
   3547 IntRect RenderLayer::childrenClipRect() const
   3548 {
   3549     RenderView* renderView = renderer()->view();
   3550     RenderLayer* clippingRootLayer = clippingRoot();
   3551     IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
   3552     calculateRects(clippingRootLayer, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
   3553     return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect)).enclosingBoundingBox();
   3554 }
   3555 
   3556 IntRect RenderLayer::selfClipRect() const
   3557 {
   3558     RenderView* renderView = renderer()->view();
   3559     RenderLayer* clippingRootLayer = clippingRoot();
   3560     IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
   3561     calculateRects(clippingRootLayer, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
   3562     return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect)).enclosingBoundingBox();
   3563 }
   3564 
   3565 void RenderLayer::addBlockSelectionGapsBounds(const IntRect& bounds)
   3566 {
   3567     m_blockSelectionGapsBounds.unite(bounds);
   3568 }
   3569 
   3570 void RenderLayer::clearBlockSelectionGapsBounds()
   3571 {
   3572     m_blockSelectionGapsBounds = IntRect();
   3573     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
   3574         child->clearBlockSelectionGapsBounds();
   3575 }
   3576 
   3577 void RenderLayer::repaintBlockSelectionGaps()
   3578 {
   3579     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
   3580         child->repaintBlockSelectionGaps();
   3581 
   3582     if (m_blockSelectionGapsBounds.isEmpty())
   3583         return;
   3584 
   3585     IntRect rect = m_blockSelectionGapsBounds;
   3586     rect.move(-scrolledContentOffset());
   3587     if (renderer()->hasOverflowClip())
   3588         rect.intersect(toRenderBox(renderer())->overflowClipRect(0, 0));
   3589     if (renderer()->hasClip())
   3590         rect.intersect(toRenderBox(renderer())->clipRect(0, 0));
   3591     if (!rect.isEmpty())
   3592         renderer()->repaintRectangle(rect);
   3593 }
   3594 
   3595 bool RenderLayer::intersectsDamageRect(const IntRect& layerBounds, const IntRect& damageRect, const RenderLayer* rootLayer) const
   3596 {
   3597     // Always examine the canvas and the root.
   3598     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
   3599     // paints the root's background.
   3600     if (renderer()->isRenderView() || renderer()->isRoot())
   3601         return true;
   3602 
   3603     // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
   3604     // can go ahead and return true.
   3605     RenderView* view = renderer()->view();
   3606     ASSERT(view);
   3607     if (view && !renderer()->isRenderInline()) {
   3608         IntRect b = layerBounds;
   3609         b.inflate(view->maximalOutlineSize());
   3610         if (b.intersects(damageRect))
   3611             return true;
   3612     }
   3613 
   3614     // Otherwise we need to compute the bounding box of this single layer and see if it intersects
   3615     // the damage rect.
   3616     return boundingBox(rootLayer).intersects(damageRect);
   3617 }
   3618 
   3619 IntRect RenderLayer::localBoundingBox() const
   3620 {
   3621     // There are three special cases we need to consider.
   3622     // (1) Inline Flows.  For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
   3623     // inline.  In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the
   3624     // line boxes of all three lines (including overflow on those lines).
   3625     // (2) Left/Top Overflow.  The width/height of layers already includes right/bottom overflow.  However, in the case of left/top
   3626     // overflow, we have to create a bounding box that will extend to include this overflow.
   3627     // (3) Floats.  When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats
   3628     // as part of our bounding box.  We do this because we are the responsible layer for both hit testing and painting those
   3629     // floats.
   3630     IntRect result;
   3631     if (renderer()->isRenderInline())
   3632         result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
   3633     else if (renderer()->isTableRow()) {
   3634         // Our bounding box is just the union of all of our cells' border/overflow rects.
   3635         for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
   3636             if (child->isTableCell()) {
   3637                 IntRect bbox = toRenderBox(child)->borderBoxRect();
   3638                 result.unite(bbox);
   3639                 IntRect overflowRect = renderBox()->visualOverflowRect();
   3640                 if (bbox != overflowRect)
   3641                     result.unite(overflowRect);
   3642             }
   3643         }
   3644     } else {
   3645         RenderBox* box = renderBox();
   3646         ASSERT(box);
   3647         if (box->hasMask())
   3648             result = box->maskClipRect();
   3649         else {
   3650             IntRect bbox = box->borderBoxRect();
   3651             result = bbox;
   3652             IntRect overflowRect = box->visualOverflowRect();
   3653             if (bbox != overflowRect)
   3654                 result.unite(overflowRect);
   3655         }
   3656     }
   3657 
   3658     RenderView* view = renderer()->view();
   3659     ASSERT(view);
   3660     if (view)
   3661         result.inflate(view->maximalOutlineSize()); // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
   3662 
   3663     return result;
   3664 }
   3665 
   3666 IntRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer) const
   3667 {
   3668     IntRect result = localBoundingBox();
   3669     if (renderer()->isBox())
   3670         renderBox()->flipForWritingMode(result);
   3671     else
   3672         renderer()->containingBlock()->flipForWritingMode(result);
   3673     int deltaX = 0, deltaY = 0;
   3674     convertToLayerCoords(ancestorLayer, deltaX, deltaY);
   3675     result.move(deltaX, deltaY);
   3676     return result;
   3677 }
   3678 
   3679 IntRect RenderLayer::absoluteBoundingBox() const
   3680 {
   3681     return boundingBox(root());
   3682 }
   3683 
   3684 void RenderLayer::clearClipRectsIncludingDescendants()
   3685 {
   3686     if (!m_clipRects)
   3687         return;
   3688 
   3689     clearClipRects();
   3690 
   3691     for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
   3692         l->clearClipRectsIncludingDescendants();
   3693 }
   3694 
   3695 void RenderLayer::clearClipRects()
   3696 {
   3697     if (m_clipRects) {
   3698         m_clipRects->deref(renderer()->renderArena());
   3699         m_clipRects = 0;
   3700 #ifndef NDEBUG
   3701         m_clipRectsRoot = 0;
   3702 #endif
   3703     }
   3704 }
   3705 
   3706 #if USE(ACCELERATED_COMPOSITING)
   3707 RenderLayerBacking* RenderLayer::ensureBacking()
   3708 {
   3709     if (!m_backing)
   3710         m_backing.set(new RenderLayerBacking(this));
   3711     return m_backing.get();
   3712 }
   3713 
   3714 void RenderLayer::clearBacking()
   3715 {
   3716     m_backing.clear();
   3717 }
   3718 
   3719 bool RenderLayer::hasCompositedMask() const
   3720 {
   3721     return m_backing && m_backing->hasMaskLayer();
   3722 }
   3723 
   3724 GraphicsLayer* RenderLayer::layerForHorizontalScrollbar() const
   3725 {
   3726     return m_backing ? m_backing->layerForHorizontalScrollbar() : 0;
   3727 }
   3728 
   3729 GraphicsLayer* RenderLayer::layerForVerticalScrollbar() const
   3730 {
   3731     return m_backing ? m_backing->layerForVerticalScrollbar() : 0;
   3732 }
   3733 
   3734 GraphicsLayer* RenderLayer::layerForScrollCorner() const
   3735 {
   3736     return m_backing ? m_backing->layerForScrollCorner() : 0;
   3737 }
   3738 #endif
   3739 
   3740 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
   3741 {
   3742 #if USE(ACCELERATED_COMPOSITING)
   3743     bool paintsToWindow = !isComposited() || backing()->paintingGoesToWindow();
   3744 #else
   3745     bool paintsToWindow = true;
   3746 #endif
   3747     return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || paintsToWindow);
   3748 }
   3749 
   3750 void RenderLayer::setParent(RenderLayer* parent)
   3751 {
   3752     if (parent == m_parent)
   3753         return;
   3754 
   3755 #if USE(ACCELERATED_COMPOSITING)
   3756     if (m_parent && !renderer()->documentBeingDestroyed())
   3757         compositor()->layerWillBeRemoved(m_parent, this);
   3758 #endif
   3759 
   3760     m_parent = parent;
   3761 
   3762 #if USE(ACCELERATED_COMPOSITING)
   3763     if (m_parent && !renderer()->documentBeingDestroyed())
   3764         compositor()->layerWasAdded(m_parent, this);
   3765 #endif
   3766 }
   3767 
   3768 static RenderObject* commonAncestor(RenderObject* obj1, RenderObject* obj2)
   3769 {
   3770     if (!obj1 || !obj2)
   3771         return 0;
   3772 
   3773     for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor())
   3774         for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor())
   3775             if (currObj1 == currObj2)
   3776                 return currObj1;
   3777 
   3778     return 0;
   3779 }
   3780 
   3781 void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestResult& result)
   3782 {
   3783     // We don't update :hover/:active state when the result is marked as readOnly.
   3784     if (request.readOnly())
   3785         return;
   3786 
   3787     Document* doc = renderer()->document();
   3788 
   3789     Node* activeNode = doc->activeNode();
   3790     if (activeNode && !request.active()) {
   3791         // We are clearing the :active chain because the mouse has been released.
   3792         for (RenderObject* curr = activeNode->renderer(); curr; curr = curr->parent()) {
   3793             if (curr->node() && !curr->isText())
   3794                 curr->node()->clearInActiveChain();
   3795         }
   3796         doc->setActiveNode(0);
   3797     } else {
   3798         Node* newActiveNode = result.innerNode();
   3799         if (!activeNode && newActiveNode && request.active()) {
   3800             // We are setting the :active chain and freezing it. If future moves happen, they
   3801             // will need to reference this chain.
   3802             for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
   3803                 if (curr->node() && !curr->isText()) {
   3804                     curr->node()->setInActiveChain();
   3805                 }
   3806             }
   3807             doc->setActiveNode(newActiveNode);
   3808         }
   3809     }
   3810 
   3811     // If the mouse is down and if this is a mouse move event, we want to restrict changes in
   3812     // :hover/:active to only apply to elements that are in the :active chain that we froze
   3813     // at the time the mouse went down.
   3814     bool mustBeInActiveChain = request.active() && request.mouseMove();
   3815 
   3816     // Check to see if the hovered node has changed.  If not, then we don't need to
   3817     // do anything.
   3818     RefPtr<Node> oldHoverNode = doc->hoverNode();
   3819     Node* newHoverNode = result.innerNode();
   3820 
   3821     // Update our current hover node.
   3822     doc->setHoverNode(newHoverNode);
   3823 
   3824     // We have two different objects.  Fetch their renderers.
   3825     RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0;
   3826     RenderObject* newHoverObj = newHoverNode ? newHoverNode->renderer() : 0;
   3827 
   3828     // Locate the common ancestor render object for the two renderers.
   3829     RenderObject* ancestor = commonAncestor(oldHoverObj, newHoverObj);
   3830 
   3831     Vector<RefPtr<Node>, 32> nodesToRemoveFromChain;
   3832     Vector<RefPtr<Node>, 32> nodesToAddToChain;
   3833 
   3834     if (oldHoverObj != newHoverObj) {
   3835         // The old hover path only needs to be cleared up to (and not including) the common ancestor;
   3836         for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
   3837             if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
   3838                 nodesToRemoveFromChain.append(curr->node());
   3839         }
   3840     }
   3841 
   3842     // Now set the hover state for our new object up to the root.
   3843     for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
   3844         if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
   3845             nodesToAddToChain.append(curr->node());
   3846     }
   3847 
   3848     size_t removeCount = nodesToRemoveFromChain.size();
   3849     for (size_t i = 0; i < removeCount; ++i) {
   3850         nodesToRemoveFromChain[i]->setActive(false);
   3851         nodesToRemoveFromChain[i]->setHovered(false);
   3852     }
   3853 
   3854     size_t addCount = nodesToAddToChain.size();
   3855     for (size_t i = 0; i < addCount; ++i) {
   3856         nodesToAddToChain[i]->setActive(request.active());
   3857         nodesToAddToChain[i]->setHovered(true);
   3858     }
   3859 }
   3860 
   3861 // Helper for the sorting of layers by z-index.
   3862 static inline bool compareZIndex(RenderLayer* first, RenderLayer* second)
   3863 {
   3864     return first->zIndex() < second->zIndex();
   3865 }
   3866 
   3867 void RenderLayer::dirtyZOrderLists()
   3868 {
   3869     if (m_posZOrderList)
   3870         m_posZOrderList->clear();
   3871     if (m_negZOrderList)
   3872         m_negZOrderList->clear();
   3873     m_zOrderListsDirty = true;
   3874 
   3875 #if USE(ACCELERATED_COMPOSITING)
   3876     if (!renderer()->documentBeingDestroyed())
   3877         compositor()->setCompositingLayersNeedRebuild();
   3878 #endif
   3879 }
   3880 
   3881 void RenderLayer::dirtyStackingContextZOrderLists()
   3882 {
   3883     RenderLayer* sc = stackingContext();
   3884     if (sc)
   3885         sc->dirtyZOrderLists();
   3886 }
   3887 
   3888 void RenderLayer::dirtyNormalFlowList()
   3889 {
   3890     if (m_normalFlowList)
   3891         m_normalFlowList->clear();
   3892     m_normalFlowListDirty = true;
   3893 
   3894 #if USE(ACCELERATED_COMPOSITING)
   3895     if (!renderer()->documentBeingDestroyed())
   3896         compositor()->setCompositingLayersNeedRebuild();
   3897 #endif
   3898 }
   3899 
   3900 void RenderLayer::updateZOrderLists()
   3901 {
   3902     if (!isStackingContext() || !m_zOrderListsDirty)
   3903         return;
   3904 
   3905     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
   3906         if (!m_reflection || reflectionLayer() != child)
   3907             child->collectLayers(m_posZOrderList, m_negZOrderList);
   3908 
   3909     // Sort the two lists.
   3910     if (m_posZOrderList)
   3911         std::stable_sort(m_posZOrderList->begin(), m_posZOrderList->end(), compareZIndex);
   3912 
   3913     if (m_negZOrderList)
   3914         std::stable_sort(m_negZOrderList->begin(), m_negZOrderList->end(), compareZIndex);
   3915 
   3916     m_zOrderListsDirty = false;
   3917 }
   3918 
   3919 void RenderLayer::updateNormalFlowList()
   3920 {
   3921     if (!m_normalFlowListDirty)
   3922         return;
   3923 
   3924     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
   3925         // Ignore non-overflow layers and reflections.
   3926         if (child->isNormalFlowOnly() && (!m_reflection || reflectionLayer() != child)) {
   3927             if (!m_normalFlowList)
   3928                 m_normalFlowList = new Vector<RenderLayer*>;
   3929             m_normalFlowList->append(child);
   3930         }
   3931     }
   3932 
   3933     m_normalFlowListDirty = false;
   3934 }
   3935 
   3936 void RenderLayer::collectLayers(Vector<RenderLayer*>*& posBuffer, Vector<RenderLayer*>*& negBuffer)
   3937 {
   3938     updateVisibilityStatus();
   3939 
   3940     // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
   3941     if ((m_hasVisibleContent || (m_hasVisibleDescendant && isStackingContext())) && !isNormalFlowOnly()) {
   3942         // Determine which buffer the child should be in.
   3943         Vector<RenderLayer*>*& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
   3944 
   3945         // Create the buffer if it doesn't exist yet.
   3946         if (!buffer)
   3947             buffer = new Vector<RenderLayer*>;
   3948 
   3949         // Append ourselves at the end of the appropriate buffer.
   3950         buffer->append(this);
   3951     }
   3952 
   3953     // Recur into our children to collect more layers, but only if we don't establish
   3954     // a stacking context.
   3955     if (m_hasVisibleDescendant && !isStackingContext()) {
   3956         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
   3957             // Ignore reflections.
   3958             if (!m_reflection || reflectionLayer() != child)
   3959                 child->collectLayers(posBuffer, negBuffer);
   3960         }
   3961     }
   3962 }
   3963 
   3964 void RenderLayer::updateLayerListsIfNeeded()
   3965 {
   3966     updateZOrderLists();
   3967     updateNormalFlowList();
   3968 }
   3969 
   3970 void RenderLayer::updateCompositingAndLayerListsIfNeeded()
   3971 {
   3972 #if USE(ACCELERATED_COMPOSITING)
   3973     if (compositor()->inCompositingMode()) {
   3974         if ((isStackingContext() && m_zOrderListsDirty) || m_normalFlowListDirty)
   3975             compositor()->updateCompositingLayers(CompositingUpdateOnPaitingOrHitTest, this);
   3976         return;
   3977     }
   3978 #endif
   3979     updateLayerListsIfNeeded();
   3980 }
   3981 
   3982 void RenderLayer::repaintIncludingDescendants()
   3983 {
   3984     renderer()->repaint();
   3985     for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
   3986         curr->repaintIncludingDescendants();
   3987 }
   3988 
   3989 #if USE(ACCELERATED_COMPOSITING)
   3990 void RenderLayer::setBackingNeedsRepaint()
   3991 {
   3992     ASSERT(isComposited());
   3993     if (backing()->paintingGoesToWindow()) {
   3994         // If we're trying to repaint the placeholder document layer, propagate the
   3995         // repaint to the native view system.
   3996         RenderView* view = renderer()->view();
   3997         if (view)
   3998             view->repaintViewRectangle(absoluteBoundingBox());
   3999     } else
   4000         backing()->setContentsNeedDisplay();
   4001 }
   4002 
   4003 void RenderLayer::setBackingNeedsRepaintInRect(const IntRect& r)
   4004 {
   4005     ASSERT(isComposited());
   4006     if (backing()->paintingGoesToWindow()) {
   4007         // If we're trying to repaint the placeholder document layer, propagate the
   4008         // repaint to the native view system.
   4009         IntRect absRect(r);
   4010         int x = 0;
   4011         int y = 0;
   4012         convertToLayerCoords(root(), x, y);
   4013         absRect.move(x, y);
   4014 
   4015         RenderView* view = renderer()->view();
   4016         if (view)
   4017             view->repaintViewRectangle(absRect);
   4018     } else
   4019         backing()->setContentsNeedDisplayInRect(r);
   4020 }
   4021 
   4022 // Since we're only painting non-composited layers, we know that they all share the same repaintContainer.
   4023 void RenderLayer::repaintIncludingNonCompositingDescendants(RenderBoxModelObject* repaintContainer)
   4024 {
   4025     renderer()->repaintUsingContainer(repaintContainer, renderer()->clippedOverflowRectForRepaint(repaintContainer));
   4026 
   4027     for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling()) {
   4028         if (!curr->isComposited())
   4029             curr->repaintIncludingNonCompositingDescendants(repaintContainer);
   4030     }
   4031 }
   4032 #endif
   4033 
   4034 bool RenderLayer::shouldBeNormalFlowOnly() const
   4035 {
   4036     return (renderer()->hasOverflowClip()
   4037                 || renderer()->hasReflection()
   4038                 || renderer()->hasMask()
   4039                 || renderer()->isVideo()
   4040                 || renderer()->isEmbeddedObject()
   4041                 || renderer()->isApplet()
   4042                 || renderer()->isRenderIFrame()
   4043                 || renderer()->style()->specifiesColumns())
   4044             && !renderer()->isPositioned()
   4045             && !renderer()->isRelPositioned()
   4046             && !renderer()->hasTransform()
   4047             && !isTransparent();
   4048 }
   4049 
   4050 bool RenderLayer::isSelfPaintingLayer() const
   4051 {
   4052 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   4053     if (hasOverflowScroll())
   4054         return true;
   4055 #endif
   4056     return !isNormalFlowOnly()
   4057         || renderer()->hasReflection()
   4058         || renderer()->hasMask()
   4059         || renderer()->isTableRow()
   4060         || renderer()->isVideo()
   4061         || renderer()->isEmbeddedObject()
   4062         || renderer()->isApplet()
   4063         || renderer()->isRenderIFrame();
   4064 }
   4065 
   4066 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
   4067 {
   4068     bool isNormalFlowOnly = shouldBeNormalFlowOnly();
   4069     if (isNormalFlowOnly != m_isNormalFlowOnly) {
   4070         m_isNormalFlowOnly = isNormalFlowOnly;
   4071         RenderLayer* p = parent();
   4072         if (p)
   4073             p->dirtyNormalFlowList();
   4074         dirtyStackingContextZOrderLists();
   4075     }
   4076 
   4077     if (renderer()->style()->overflowX() == OMARQUEE && renderer()->style()->marqueeBehavior() != MNONE && renderer()->isBox()) {
   4078         if (!m_marquee)
   4079             m_marquee = new RenderMarquee(this);
   4080         m_marquee->updateMarqueeStyle();
   4081     }
   4082     else if (m_marquee) {
   4083         delete m_marquee;
   4084         m_marquee = 0;
   4085     }
   4086 
   4087     if (!hasReflection() && m_reflection)
   4088         removeReflection();
   4089     else if (hasReflection()) {
   4090         if (!m_reflection)
   4091             createReflection();
   4092         updateReflectionStyle();
   4093     }
   4094 
   4095     // FIXME: Need to detect a swap from custom to native scrollbars (and vice versa).
   4096     if (m_hBar)
   4097         m_hBar->styleChanged();
   4098     if (m_vBar)
   4099         m_vBar->styleChanged();
   4100 
   4101     updateScrollCornerStyle();
   4102     updateResizerStyle();
   4103 
   4104 #if USE(ACCELERATED_COMPOSITING)
   4105     updateTransform();
   4106 
   4107     if (compositor()->updateLayerCompositingState(this))
   4108         compositor()->setCompositingLayersNeedRebuild();
   4109     else if (m_backing)
   4110         m_backing->updateGraphicsLayerGeometry();
   4111     else if (oldStyle && oldStyle->overflowX() != renderer()->style()->overflowX()) {
   4112         if (stackingContext()->hasCompositingDescendant())
   4113             compositor()->setCompositingLayersNeedRebuild();
   4114     }
   4115 
   4116     if (m_backing && diff >= StyleDifferenceRepaint)
   4117         m_backing->setContentsNeedDisplay();
   4118 #else
   4119     UNUSED_PARAM(diff);
   4120 #endif
   4121 }
   4122 
   4123 void RenderLayer::updateScrollCornerStyle()
   4124 {
   4125     RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
   4126     RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, actualRenderer->style()) : 0;
   4127     if (corner) {
   4128         if (!m_scrollCorner) {
   4129             m_scrollCorner = new (renderer()->renderArena()) RenderScrollbarPart(renderer()->document());
   4130             m_scrollCorner->setParent(renderer());
   4131         }
   4132         m_scrollCorner->setStyle(corner.release());
   4133     } else if (m_scrollCorner) {
   4134         m_scrollCorner->destroy();
   4135         m_scrollCorner = 0;
   4136     }
   4137 }
   4138 
   4139 void RenderLayer::updateResizerStyle()
   4140 {
   4141     RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
   4142     RefPtr<RenderStyle> resizer = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RESIZER, actualRenderer->style()) : 0;
   4143     if (resizer) {
   4144         if (!m_resizer) {
   4145             m_resizer = new (renderer()->renderArena()) RenderScrollbarPart(renderer()->document());
   4146             m_resizer->setParent(renderer());
   4147         }
   4148         m_resizer->setStyle(resizer.release());
   4149     } else if (m_resizer) {
   4150         m_resizer->destroy();
   4151         m_resizer = 0;
   4152     }
   4153 }
   4154 
   4155 RenderLayer* RenderLayer::reflectionLayer() const
   4156 {
   4157     return m_reflection ? m_reflection->layer() : 0;
   4158 }
   4159 
   4160 void RenderLayer::createReflection()
   4161 {
   4162     ASSERT(!m_reflection);
   4163     m_reflection = new (renderer()->renderArena()) RenderReplica(renderer()->document());
   4164     m_reflection->setParent(renderer()); // We create a 1-way connection.
   4165 }
   4166 
   4167 void RenderLayer::removeReflection()
   4168 {
   4169     if (!m_reflection->documentBeingDestroyed())
   4170         m_reflection->removeLayers(this);
   4171 
   4172     m_reflection->setParent(0);
   4173     m_reflection->destroy();
   4174     m_reflection = 0;
   4175 }
   4176 
   4177 void RenderLayer::updateReflectionStyle()
   4178 {
   4179     RefPtr<RenderStyle> newStyle = RenderStyle::create();
   4180     newStyle->inheritFrom(renderer()->style());
   4181 
   4182     // Map in our transform.
   4183     TransformOperations transform;
   4184     switch (renderer()->style()->boxReflect()->direction()) {
   4185         case ReflectionBelow:
   4186             transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed), Length(100., Percent), TransformOperation::TRANSLATE));
   4187             transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed), renderer()->style()->boxReflect()->offset(), TransformOperation::TRANSLATE));
   4188             transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::SCALE));
   4189             break;
   4190         case ReflectionAbove:
   4191             transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::SCALE));
   4192             transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed), Length(100., Percent), TransformOperation::TRANSLATE));
   4193             transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed), renderer()->style()->boxReflect()->offset(), TransformOperation::TRANSLATE));
   4194             break;
   4195         case ReflectionRight:
   4196             transform.operations().append(TranslateTransformOperation::create(Length(100., Percent), Length(0, Fixed), TransformOperation::TRANSLATE));
   4197             transform.operations().append(TranslateTransformOperation::create(renderer()->style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::TRANSLATE));
   4198             transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::SCALE));
   4199             break;
   4200         case ReflectionLeft:
   4201             transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::SCALE));
   4202             transform.operations().append(TranslateTransformOperation::create(Length(100., Percent), Length(0, Fixed), TransformOperation::TRANSLATE));
   4203             transform.operations().append(TranslateTransformOperation::create(renderer()->style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::TRANSLATE));
   4204             break;
   4205     }
   4206     newStyle->setTransform(transform);
   4207 
   4208     // Map in our mask.
   4209     newStyle->setMaskBoxImage(renderer()->style()->boxReflect()->mask());
   4210 
   4211     m_reflection->setStyle(newStyle.release());
   4212 }
   4213 
   4214 void RenderLayer::updateContentsScale(float scale)
   4215 {
   4216 #if USE(ACCELERATED_COMPOSITING)
   4217     if (m_backing)
   4218         m_backing->updateContentsScale(scale);
   4219 #endif
   4220 }
   4221 
   4222 } // namespace WebCore
   4223 
   4224 #ifndef NDEBUG
   4225 void showLayerTree(const WebCore::RenderLayer* layer)
   4226 {
   4227     if (!layer)
   4228         return;
   4229 
   4230     if (WebCore::Frame* frame = layer->renderer()->frame()) {
   4231         WTF::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass | WebCore::RenderAsTextDontUpdateLayout | WebCore::RenderAsTextShowLayoutState);
   4232         fprintf(stderr, "%s\n", output.utf8().data());
   4233     }
   4234 }
   4235 
   4236 void showLayerTree(const WebCore::RenderObject* renderer)
   4237 {
   4238     if (!renderer)
   4239         return;
   4240     showLayerTree(renderer->enclosingLayer());
   4241 }
   4242 #endif
   4243