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