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