webengine/osswebengine/WebCore/rendering/RenderLayer.cpp
changeset 0 dd21522fd290
child 62 c711bdda59f4
child 68 92a765b5b3e7
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  * Copyright (C) 2006, 2007 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 "Document.h"
       
    49 #include "EventHandler.h"
       
    50 #include "EventNames.h"
       
    51 #include "FloatRect.h"
       
    52 #include "Frame.h"
       
    53 #include "FrameView.h"
       
    54 #include "FrameTree.h"
       
    55 #include "GraphicsContext.h"
       
    56 #include "HTMLMarqueeElement.h"
       
    57 #include "HTMLNames.h"
       
    58 #include "HitTestRequest.h"
       
    59 #include "HitTestResult.h"
       
    60 #include "OverflowEvent.h"
       
    61 #include "PlatformMouseEvent.h"
       
    62 #include "PlatformScrollBar.h" 
       
    63 #include "RenderArena.h"
       
    64 #include "RenderInline.h"
       
    65 #include "RenderTheme.h"
       
    66 #include "RenderView.h"
       
    67 #include "SelectionController.h"
       
    68 
       
    69 #if ENABLE(SVG)
       
    70 #include "SVGNames.h"
       
    71 #endif
       
    72 
       
    73 #define MIN_INTERSECT_FOR_REVEAL 32
       
    74 
       
    75 using namespace std;
       
    76 
       
    77 namespace WebCore {
       
    78 
       
    79 using namespace EventNames;
       
    80 using namespace HTMLNames;
       
    81 
       
    82 #ifndef NDEBUG
       
    83 static bool inRenderLayerDestroy;
       
    84 #endif
       
    85 
       
    86 const RenderLayer::ScrollAlignment RenderLayer::gAlignCenterIfNeeded = { RenderLayer::noScroll, RenderLayer::alignCenter, RenderLayer::alignToClosestEdge };
       
    87 const RenderLayer::ScrollAlignment RenderLayer::gAlignToEdgeIfNeeded = { RenderLayer::noScroll, RenderLayer::alignToClosestEdge, RenderLayer::alignToClosestEdge };
       
    88 const RenderLayer::ScrollAlignment RenderLayer::gAlignCenterAlways = { RenderLayer::alignCenter, RenderLayer::alignCenter, RenderLayer::alignCenter };
       
    89 const RenderLayer::ScrollAlignment RenderLayer::gAlignTopAlways = { RenderLayer::alignTop, RenderLayer::alignTop, RenderLayer::alignTop };
       
    90 const RenderLayer::ScrollAlignment RenderLayer::gAlignBottomAlways = { RenderLayer::alignBottom, RenderLayer::alignBottom, RenderLayer::alignBottom };
       
    91 
       
    92 const int MinimumWidthWhileResizing = 100;
       
    93 const int MinimumHeightWhileResizing = 40;
       
    94 
       
    95 void* ClipRects::operator new(size_t sz, RenderArena* renderArena) throw()
       
    96 {
       
    97     return renderArena->allocate(sz);
       
    98 }
       
    99 
       
   100 void ClipRects::operator delete(void* ptr, size_t sz)
       
   101 {
       
   102     // Stash size where destroy can find it.
       
   103     *(size_t *)ptr = sz;
       
   104 }
       
   105 
       
   106 void ClipRects::destroy(RenderArena* renderArena)
       
   107 {
       
   108     delete this;
       
   109     
       
   110     // Recover the size left there for us by operator delete and free the memory.
       
   111     renderArena->free(*(size_t *)this, this);
       
   112 }
       
   113 
       
   114 RenderLayer::RenderLayer(RenderObject* object)
       
   115     : m_object(object)
       
   116     , m_parent(0)
       
   117     , m_previous(0)
       
   118     , m_next(0)
       
   119     , m_first(0)
       
   120     , m_last(0)
       
   121     , m_relX(0)
       
   122     , m_relY(0)
       
   123     , m_x(0)
       
   124     , m_y(0)
       
   125     , m_width(0)
       
   126     , m_height(0)
       
   127     , m_scrollX(0)
       
   128     , m_scrollY(0)
       
   129     , m_scrollOriginX(0)
       
   130     , m_scrollLeftOverflow(0)
       
   131     , m_scrollWidth(0)
       
   132     , m_scrollHeight(0)
       
   133     , m_inResizeMode(false)
       
   134     , m_posZOrderList(0)
       
   135     , m_negZOrderList(0)
       
   136     , m_overflowList(0)
       
   137     , m_clipRects(0) 
       
   138     , m_scrollDimensionsDirty(true)
       
   139     , m_zOrderListsDirty(true)
       
   140     , m_overflowListDirty(true)
       
   141     , m_isOverflowOnly(shouldBeOverflowOnly())
       
   142     , m_usedTransparency(false)
       
   143     , m_inOverflowRelayout(false)
       
   144     , m_needsFullRepaint(false)
       
   145     , m_overflowStatusDirty(true)
       
   146     , m_visibleContentStatusDirty(true)
       
   147     , m_hasVisibleContent(false)
       
   148     , m_visibleDescendantStatusDirty(false)
       
   149     , m_hasVisibleDescendant(false)
       
   150     , m_marquee(0)
       
   151     , m_staticX(0)
       
   152     , m_staticY(0)
       
   153 {
       
   154     if (!object->firstChild() && object->style()) {
       
   155         m_visibleContentStatusDirty = false;
       
   156         m_hasVisibleContent = object->style()->visibility() == VISIBLE;
       
   157     }
       
   158 }
       
   159 
       
   160 RenderLayer::~RenderLayer()
       
   161 {
       
   162     destroyScrollbar(HorizontalScrollbar);
       
   163     destroyScrollbar(VerticalScrollbar);
       
   164 
       
   165     // Child layers will be deleted by their corresponding render objects, so
       
   166     // we don't need to delete them ourselves.
       
   167 
       
   168     delete m_posZOrderList;
       
   169     delete m_negZOrderList;
       
   170     delete m_overflowList;
       
   171     delete m_marquee;
       
   172     
       
   173     // Make sure we have no lingering clip rects.
       
   174     ASSERT(!m_clipRects);
       
   175 }
       
   176 
       
   177 void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
       
   178 {
       
   179     if (doFullRepaint) {
       
   180         m_object->repaint();
       
   181         checkForRepaint = doFullRepaint = false;
       
   182     }
       
   183     
       
   184     updateLayerPosition(); // For relpositioned layers or non-positioned layers,
       
   185                            // we need to keep in sync, since we may have shifted relative
       
   186                            // to our parent layer.
       
   187 
       
   188     positionOverflowControls();
       
   189 
       
   190     updateVisibilityStatus();
       
   191         
       
   192     if (m_hasVisibleContent) {
       
   193         RenderView* view = m_object->view();
       
   194         ASSERT(view);
       
   195         // FIXME: Optimize using LayoutState and remove the disableLayoutState() call
       
   196         // from updateScrollInfoAfterLayout().
       
   197         ASSERT(!view->layoutState());
       
   198 
       
   199         IntRect newRect = m_object->absoluteClippedOverflowRect();
       
   200         IntRect newOutlineBox = m_object->absoluteOutlineBox();
       
   201         if (checkForRepaint) {
       
   202             if (view && !view->printing()) {
       
   203                 if (m_needsFullRepaint) {
       
   204                     view->repaintViewRectangle(m_repaintRect);
       
   205                     if (newRect != m_repaintRect)
       
   206                         view->repaintViewRectangle(newRect);
       
   207                 } else
       
   208                     m_object->repaintAfterLayoutIfNeeded(m_repaintRect, m_outlineBox);
       
   209             }
       
   210         }
       
   211         m_repaintRect = newRect;
       
   212         m_outlineBox = newOutlineBox;
       
   213     } else {
       
   214         m_repaintRect = IntRect();
       
   215         m_outlineBox = IntRect();
       
   216     }
       
   217 
       
   218     m_needsFullRepaint = false;
       
   219     
       
   220     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
       
   221         child->updateLayerPositions(doFullRepaint, checkForRepaint);
       
   222         
       
   223     // With all our children positioned, now update our marquee if we need to.
       
   224     if (m_marquee)
       
   225         m_marquee->updateMarqueePosition();
       
   226 }
       
   227 
       
   228 void RenderLayer::setHasVisibleContent(bool b) 
       
   229 { 
       
   230     if (m_hasVisibleContent == b && !m_visibleContentStatusDirty)
       
   231         return;
       
   232     m_visibleContentStatusDirty = false; 
       
   233     m_hasVisibleContent = b;
       
   234     if (m_hasVisibleContent) {
       
   235         m_repaintRect = renderer()->absoluteClippedOverflowRect();
       
   236         m_outlineBox = renderer()->absoluteOutlineBox();
       
   237     }
       
   238     if (parent())
       
   239         parent()->childVisibilityChanged(m_hasVisibleContent);
       
   240 }
       
   241 
       
   242 void RenderLayer::dirtyVisibleContentStatus() 
       
   243 { 
       
   244     m_visibleContentStatusDirty = true; 
       
   245     if (parent())
       
   246         parent()->dirtyVisibleDescendantStatus();
       
   247 }
       
   248 
       
   249 void RenderLayer::childVisibilityChanged(bool newVisibility) 
       
   250 { 
       
   251     if (m_hasVisibleDescendant == newVisibility || m_visibleDescendantStatusDirty)
       
   252         return;
       
   253     if (newVisibility) {
       
   254         RenderLayer* l = this;
       
   255         while (l && !l->m_visibleDescendantStatusDirty && !l->m_hasVisibleDescendant) {
       
   256             l->m_hasVisibleDescendant = true;
       
   257             l = l->parent();
       
   258         }
       
   259     } else 
       
   260         dirtyVisibleDescendantStatus();
       
   261 }
       
   262 
       
   263 void RenderLayer::dirtyVisibleDescendantStatus()
       
   264 {
       
   265     RenderLayer* l = this;
       
   266     while (l && !l->m_visibleDescendantStatusDirty) {
       
   267         l->m_visibleDescendantStatusDirty = true;
       
   268         l = l->parent();
       
   269     }
       
   270 }
       
   271 
       
   272 void RenderLayer::updateVisibilityStatus()
       
   273 {
       
   274     if (m_visibleDescendantStatusDirty) {
       
   275         m_hasVisibleDescendant = false;
       
   276         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
       
   277             child->updateVisibilityStatus();        
       
   278             if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
       
   279                 m_hasVisibleDescendant = true;
       
   280                 break;
       
   281             }
       
   282         }
       
   283         m_visibleDescendantStatusDirty = false;
       
   284     }
       
   285 
       
   286     if (m_visibleContentStatusDirty) {
       
   287         if (m_object->style()->visibility() == VISIBLE)
       
   288             m_hasVisibleContent = true;
       
   289         else {
       
   290             // layer may be hidden but still have some visible content, check for this
       
   291             m_hasVisibleContent = false;
       
   292             RenderObject* r = m_object->firstChild();
       
   293             while (r) {
       
   294                 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
       
   295                     m_hasVisibleContent = true;
       
   296                     break;
       
   297                 }
       
   298                 if (r->firstChild() && !r->hasLayer())
       
   299                     r = r->firstChild();
       
   300                 else if (r->nextSibling())
       
   301                     r = r->nextSibling();
       
   302                 else {
       
   303                     do {
       
   304                         r = r->parent();
       
   305                         if (r==m_object)
       
   306                             r = 0;
       
   307                     } while (r && !r->nextSibling());
       
   308                     if (r)
       
   309                         r = r->nextSibling();
       
   310                 }
       
   311             }
       
   312         }    
       
   313         m_visibleContentStatusDirty = false; 
       
   314     }
       
   315 }
       
   316 
       
   317 void RenderLayer::updateLayerPosition()
       
   318 {
       
   319     // Clear our cached clip rect information.
       
   320     clearClipRect();
       
   321 
       
   322     int x = m_object->xPos();
       
   323     int y = m_object->yPos() - m_object->borderTopExtra();
       
   324 
       
   325     if (!m_object->isPositioned() && m_object->parent()) {
       
   326         // We must adjust our position by walking up the render tree looking for the
       
   327         // nearest enclosing object with a layer.
       
   328         RenderObject* curr = m_object->parent();
       
   329         while (curr && !curr->hasLayer()) {
       
   330             if (!curr->isTableRow()) {
       
   331                 // Rows and cells share the same coordinate space (that of the section).
       
   332                 // Omit them when computing our xpos/ypos.
       
   333                 x += curr->xPos();
       
   334                 y += curr->yPos();
       
   335             }
       
   336             curr = curr->parent();
       
   337         }
       
   338         y += curr->borderTopExtra();
       
   339         if (curr->isTableRow()) {
       
   340             // Put ourselves into the row coordinate space.
       
   341             x -= curr->xPos();
       
   342             y -= curr->yPos();
       
   343         }
       
   344     }
       
   345 
       
   346     m_relX = m_relY = 0;
       
   347     if (m_object->isRelPositioned()) {
       
   348         m_relX = static_cast<RenderBox*>(m_object)->relativePositionOffsetX();
       
   349         m_relY = static_cast<RenderBox*>(m_object)->relativePositionOffsetY();
       
   350         x += m_relX; y += m_relY;
       
   351     }
       
   352     
       
   353     // Subtract our parent's scroll offset.
       
   354     if (m_object->isPositioned() && enclosingPositionedAncestor()) {
       
   355         RenderLayer* positionedParent = enclosingPositionedAncestor();
       
   356 
       
   357         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
       
   358         positionedParent->subtractScrollOffset(x, y);
       
   359         
       
   360         if (m_object->isPositioned()) {
       
   361             IntSize offset = static_cast<RenderBox*>(m_object)->offsetForPositionedInContainer(positionedParent->renderer());
       
   362             x += offset.width();
       
   363             y += offset.height();
       
   364         }
       
   365     } else if (parent())
       
   366         parent()->subtractScrollOffset(x, y);
       
   367     
       
   368     setPos(x,y);
       
   369 
       
   370     setWidth(m_object->width());
       
   371     setHeight(m_object->height() + m_object->borderTopExtra() + m_object->borderBottomExtra());
       
   372 
       
   373     if (!m_object->hasOverflowClip()) {
       
   374         if (m_object->overflowWidth() > m_object->width())
       
   375             setWidth(m_object->overflowWidth());
       
   376         if (m_object->overflowHeight() > m_object->height())
       
   377             setHeight(m_object->overflowHeight());
       
   378     }
       
   379 }
       
   380 
       
   381 RenderLayer *RenderLayer::stackingContext() const
       
   382 {
       
   383     RenderLayer* curr = parent();
       
   384     for ( ; curr && !curr->m_object->isRenderView() && !curr->m_object->isRoot() &&
       
   385           curr->m_object->style()->hasAutoZIndex();
       
   386           curr = curr->parent());
       
   387     return curr;
       
   388 }
       
   389 
       
   390 RenderLayer*
       
   391 RenderLayer::enclosingPositionedAncestor() const
       
   392 {
       
   393     RenderLayer* curr = parent();
       
   394     for ( ; curr && !curr->m_object->isRenderView() && !curr->m_object->isRoot() &&
       
   395          !curr->m_object->isPositioned() && !curr->m_object->isRelPositioned();
       
   396          curr = curr->parent());
       
   397          
       
   398     return curr;
       
   399 }
       
   400 
       
   401 bool
       
   402 RenderLayer::isTransparent() const
       
   403 {
       
   404 #if ENABLE(SVG)
       
   405     if (m_object->node()->namespaceURI() == SVGNames::svgNamespaceURI)
       
   406         return false;
       
   407 #endif
       
   408     return m_object->isTransparent();
       
   409 }
       
   410 
       
   411 RenderLayer*
       
   412 RenderLayer::transparentAncestor()
       
   413 {
       
   414     RenderLayer* curr = parent();
       
   415     for ( ; curr && !curr->isTransparent(); curr = curr->parent());
       
   416     return curr;
       
   417 }
       
   418 
       
   419 static IntRect transparencyClipBox(RenderLayer* l)
       
   420 {
       
   421     // FIXME: Although this completely ignores clipping, we ultimately intersect with the
       
   422     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
       
   423     // would be better to respect clips.
       
   424     IntRect clipRect = l->absoluteBoundingBox();
       
   425     
       
   426     // Note: we don't have to walk z-order lists since transparent elements always establish
       
   427     // a stacking context.  This means we can just walk the layer tree directly. 
       
   428     for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling())
       
   429         clipRect.unite(transparencyClipBox(curr));
       
   430     
       
   431     return clipRect;
       
   432 }
       
   433 
       
   434 void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const IntRect& paintDirtyRect)
       
   435 {
       
   436     if (p->paintingDisabled() || (isTransparent() && m_usedTransparency))
       
   437         return;
       
   438     
       
   439     RenderLayer* ancestor = transparentAncestor();
       
   440     if (ancestor)
       
   441         ancestor->beginTransparencyLayers(p, paintDirtyRect);
       
   442     
       
   443     if (isTransparent()) {
       
   444         m_usedTransparency = true;
       
   445         IntRect clipRect = transparencyClipBox(this);
       
   446         clipRect.intersect(paintDirtyRect);
       
   447         p->save();
       
   448         p->clip(clipRect);
       
   449         p->beginTransparencyLayer(renderer()->opacity());
       
   450     }
       
   451 }
       
   452 
       
   453 void* RenderLayer::operator new(size_t sz, RenderArena* renderArena) throw()
       
   454 {
       
   455     return renderArena->allocate(sz);
       
   456 }
       
   457 
       
   458 void RenderLayer::operator delete(void* ptr, size_t sz)
       
   459 {
       
   460     ASSERT(inRenderLayerDestroy);
       
   461     
       
   462     // Stash size where destroy can find it.
       
   463     *(size_t *)ptr = sz;
       
   464 }
       
   465 
       
   466 void RenderLayer::destroy(RenderArena* renderArena)
       
   467 {
       
   468 #ifndef NDEBUG
       
   469     inRenderLayerDestroy = true;
       
   470 #endif
       
   471     delete this;
       
   472 #ifndef NDEBUG
       
   473     inRenderLayerDestroy = false;
       
   474 #endif
       
   475     
       
   476     // Recover the size left there for us by operator delete and free the memory.
       
   477     renderArena->free(*(size_t *)this, this);
       
   478 }
       
   479 
       
   480 void RenderLayer::addChild(RenderLayer *child, RenderLayer* beforeChild)
       
   481 {
       
   482     RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
       
   483     if (prevSibling) {
       
   484         child->setPreviousSibling(prevSibling);
       
   485         prevSibling->setNextSibling(child);
       
   486     }
       
   487     else
       
   488         setFirstChild(child);
       
   489 
       
   490     if (beforeChild) {
       
   491         beforeChild->setPreviousSibling(child);
       
   492         child->setNextSibling(beforeChild);
       
   493     }
       
   494     else
       
   495         setLastChild(child);
       
   496    
       
   497     child->setParent(this);
       
   498 
       
   499     if (child->isOverflowOnly())
       
   500         dirtyOverflowList();
       
   501     else {
       
   502         // Dirty the z-order list in which we are contained.  The stackingContext() can be null in the
       
   503         // case where we're building up generated content layers.  This is ok, since the lists will start
       
   504         // off dirty in that case anyway.
       
   505         RenderLayer* stackingContext = child->stackingContext();
       
   506         if (stackingContext)
       
   507             stackingContext->dirtyZOrderLists();
       
   508     }
       
   509     
       
   510     child->updateVisibilityStatus();
       
   511     if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
       
   512         childVisibilityChanged(true);
       
   513 }
       
   514 
       
   515 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
       
   516 {
       
   517     // remove the child
       
   518     if (oldChild->previousSibling())
       
   519         oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
       
   520     if (oldChild->nextSibling())
       
   521         oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
       
   522 
       
   523     if (m_first == oldChild)
       
   524         m_first = oldChild->nextSibling();
       
   525     if (m_last == oldChild)
       
   526         m_last = oldChild->previousSibling();
       
   527 
       
   528     if (oldChild->isOverflowOnly())
       
   529         dirtyOverflowList();
       
   530     else { 
       
   531         // Dirty the z-order list in which we are contained.  When called via the
       
   532         // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
       
   533         // from the main layer tree, so we need to null-check the |stackingContext| value.
       
   534         RenderLayer* stackingContext = oldChild->stackingContext();
       
   535         if (stackingContext)
       
   536             stackingContext->dirtyZOrderLists();
       
   537     }
       
   538 
       
   539     oldChild->setPreviousSibling(0);
       
   540     oldChild->setNextSibling(0);
       
   541     oldChild->setParent(0);
       
   542     
       
   543     oldChild->updateVisibilityStatus();
       
   544     if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
       
   545         childVisibilityChanged(false);
       
   546     
       
   547     return oldChild;
       
   548 }
       
   549 
       
   550 void RenderLayer::removeOnlyThisLayer()
       
   551 {
       
   552     if (!m_parent)
       
   553         return;
       
   554     
       
   555     // Dirty the clip rects.
       
   556     clearClipRects();
       
   557 
       
   558     // Remove us from the parent.
       
   559     RenderLayer* parent = m_parent;
       
   560     RenderLayer* nextSib = nextSibling();
       
   561     parent->removeChild(this);
       
   562     
       
   563     // Now walk our kids and reattach them to our parent.
       
   564     RenderLayer* current = m_first;
       
   565     while (current) {
       
   566         RenderLayer* next = current->nextSibling();
       
   567         removeChild(current);
       
   568         parent->addChild(current, nextSib);
       
   569         current->updateLayerPositions();
       
   570         current = next;
       
   571     }
       
   572     
       
   573     destroy(renderer()->renderArena());
       
   574 }
       
   575 
       
   576 void RenderLayer::insertOnlyThisLayer()
       
   577 {
       
   578     if (!m_parent && renderer()->parent()) {
       
   579         // We need to connect ourselves when our renderer() has a parent.
       
   580         // Find our enclosingLayer and add ourselves.
       
   581         RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
       
   582         if (parentLayer)
       
   583             parentLayer->addChild(this, 
       
   584                                   renderer()->parent()->findNextLayer(parentLayer, renderer()));
       
   585     }
       
   586     
       
   587     // Remove all descendant layers from the hierarchy and add them to the new position.
       
   588     for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())
       
   589         curr->moveLayers(m_parent, this);
       
   590         
       
   591     // Clear out all the clip rects.
       
   592     clearClipRects();
       
   593 }
       
   594 
       
   595 void 
       
   596 RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const
       
   597 {
       
   598     if (ancestorLayer == this)
       
   599         return;
       
   600         
       
   601     if (m_object->style()->position() == FixedPosition) {
       
   602         // Add in the offset of the view.  We can obtain this by calling
       
   603         // absolutePosition() on the RenderView.
       
   604         int xOff, yOff;
       
   605         m_object->absolutePosition(xOff, yOff, true);
       
   606         x += xOff;
       
   607         y += yOff;
       
   608         return;
       
   609     }
       
   610  
       
   611     RenderLayer* parentLayer;
       
   612     if (m_object->style()->position() == AbsolutePosition)
       
   613         parentLayer = enclosingPositionedAncestor();
       
   614     else
       
   615         parentLayer = parent();
       
   616     
       
   617     if (!parentLayer) return;
       
   618     
       
   619     parentLayer->convertToLayerCoords(ancestorLayer, x, y);
       
   620 
       
   621     x += xPos();
       
   622     y += yPos();
       
   623 }
       
   624 
       
   625 void
       
   626 RenderLayer::scrollOffset(int& x, int& y)
       
   627 {
       
   628     x += scrollXOffset() + m_scrollLeftOverflow;
       
   629     y += scrollYOffset();
       
   630 }
       
   631 
       
   632 void
       
   633 RenderLayer::subtractScrollOffset(int& x, int& y)
       
   634 {
       
   635     x -= scrollXOffset() + m_scrollLeftOverflow;
       
   636     y -= scrollYOffset();
       
   637 }
       
   638 
       
   639 void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint)
       
   640 {
       
   641     if (renderer()->style()->overflowX() != OMARQUEE) {
       
   642         if (x < 0) x = 0;
       
   643         if (y < 0) y = 0;
       
   644     
       
   645         // Call the scrollWidth/Height functions so that the dimensions will be computed if they need
       
   646         // to be (for overflow:hidden blocks).
       
   647         int maxX = scrollWidth() - m_object->clientWidth();
       
   648         int maxY = scrollHeight() - m_object->clientHeight();
       
   649         
       
   650         if (x > maxX) x = maxX;
       
   651         if (y > maxY) y = maxY;
       
   652     }
       
   653     
       
   654     // FIXME: Eventually, we will want to perform a blit.  For now never
       
   655     // blit, since the check for blitting is going to be very
       
   656     // complicated (since it will involve testing whether our layer
       
   657     // is either occluded by another layer or clipped by an enclosing
       
   658     // layer or contains fixed backgrounds, etc.).
       
   659     m_scrollX = x - m_scrollOriginX;
       
   660     m_scrollY = y;
       
   661 
       
   662     // Update the positions of our child layers.
       
   663     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
       
   664         child->updateLayerPositions(false, false);
       
   665     
       
   666     RenderView* view = renderer()->view();
       
   667     
       
   668     // We should have a RenderView if we're trying to scroll.
       
   669     ASSERT(view);
       
   670     if (view) {
       
   671         // Update dashboard regions, scrolling may change the clip of a
       
   672         // particular region.
       
   673         view->frameView()->updateDashboardRegions();
       
   674 
       
   675         view->updateWidgetPositions();
       
   676     }
       
   677 
       
   678     // Just schedule a full repaint of our object.
       
   679     if (repaint)
       
   680         m_object->repaint();
       
   681     
       
   682     if (updateScrollbars) {
       
   683         if (m_hBar)
       
   684             m_hBar->setValue(scrollXOffset());
       
   685         if (m_vBar)
       
   686             m_vBar->setValue(m_scrollY);
       
   687     }
       
   688 
       
   689     // Schedule the scroll DOM event.
       
   690     if (view)
       
   691         if (FrameView* frameView = view->frameView())
       
   692             frameView->scheduleEvent(new Event(scrollEvent, true, false), EventTargetNodeCast(renderer()->element()), true);
       
   693 }
       
   694 
       
   695 void RenderLayer::scrollRectToVisible(const IntRect &rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
       
   696 {
       
   697     RenderLayer* parentLayer = 0;
       
   698     IntRect newRect = rect;
       
   699     int xOffset = 0, yOffset = 0;
       
   700 
       
   701     // We may end up propagating a scroll event. It is important that we suspend events until 
       
   702     // the end of the function since they could delete the layer or the layer's m_object.
       
   703     FrameView* frameView = m_object->document()->view();
       
   704     if (frameView)
       
   705         frameView->pauseScheduledEvents();
       
   706 
       
   707     bool restrictedByLineClamp = false;
       
   708     if (m_object->parent()) {
       
   709         parentLayer = m_object->parent()->enclosingLayer();
       
   710         restrictedByLineClamp = m_object->parent()->style()->lineClamp() >= 0;
       
   711     }
       
   712 
       
   713     if (m_object->hasOverflowClip() && !restrictedByLineClamp) {
       
   714         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
       
   715         // This will prevent us from revealing text hidden by the slider in Safari RSS.
       
   716         int x, y;
       
   717         m_object->absolutePosition(x, y);
       
   718         x += m_object->borderLeft();
       
   719         y += m_object->borderTop();
       
   720 
       
   721         IntRect layerBounds = IntRect(x + scrollXOffset(), y + scrollYOffset(), m_object->clientWidth(), m_object->clientHeight());
       
   722         IntRect exposeRect = IntRect(rect.x() + scrollXOffset(), rect.y() + scrollYOffset(), rect.width(), rect.height());
       
   723         IntRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
       
   724         
       
   725         xOffset = r.x() - x;
       
   726         yOffset = r.y() - y;
       
   727         // Adjust offsets if they're outside of the allowable range.
       
   728         xOffset = max(0, min(scrollWidth() - layerBounds.width(), xOffset));
       
   729         yOffset = max(0, min(scrollHeight() - layerBounds.height(), yOffset));
       
   730         
       
   731         if (xOffset != scrollXOffset() || yOffset != scrollYOffset()) {
       
   732             int diffX = scrollXOffset();
       
   733             int diffY = scrollYOffset();
       
   734             scrollToOffset(xOffset, yOffset);
       
   735             diffX = scrollXOffset() - diffX;
       
   736             diffY = scrollYOffset() - diffY;
       
   737             newRect.setX(rect.x() - diffX);
       
   738             newRect.setY(rect.y() - diffY);
       
   739         }
       
   740     } else if (!parentLayer) {
       
   741         if (frameView) {
       
   742             if (m_object->document() && m_object->document()->ownerElement() && m_object->document()->ownerElement()->renderer()) {
       
   743                 IntRect viewRect = enclosingIntRect(frameView->visibleContentRect());
       
   744                 IntRect r = getRectToExpose(viewRect, rect, alignX, alignY);
       
   745                 
       
   746                 xOffset = r.x();
       
   747                 yOffset = r.y();
       
   748                 // Adjust offsets if they're outside of the allowable range.
       
   749                 xOffset = max(0, min(frameView->contentsWidth(), xOffset));
       
   750                 yOffset = max(0, min(frameView->contentsHeight(), yOffset));
       
   751 
       
   752                 frameView->setContentsPos(xOffset, yOffset);
       
   753                 parentLayer = m_object->document()->ownerElement()->renderer()->enclosingLayer();
       
   754                 newRect.setX(rect.x() - frameView->contentsX() + frameView->x());
       
   755                 newRect.setY(rect.y() - frameView->contentsY() + frameView->y());
       
   756             } else {
       
   757                 IntRect viewRect = enclosingIntRect(frameView->visibleContentRectConsideringExternalScrollers());
       
   758                 IntRect r = getRectToExpose(viewRect, rect, alignX, alignY);
       
   759                 
       
   760                 // If this is the outermost view that RenderLayer needs to scroll, then we should scroll the view recursively
       
   761                 // Other apps, like Mail, rely on this feature.
       
   762                 frameView->scrollRectIntoViewRecursively(r);
       
   763             }
       
   764         }
       
   765     }
       
   766     
       
   767     if (parentLayer)
       
   768         parentLayer->scrollRectToVisible(newRect, alignX, alignY);
       
   769 
       
   770     if (frameView)
       
   771         frameView->resumeScheduledEvents();
       
   772 }
       
   773 
       
   774 IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
       
   775 {
       
   776     // Determine the appropriate X behavior.
       
   777     ScrollBehavior scrollX;
       
   778     IntRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
       
   779     int intersectWidth = intersection(visibleRect, exposeRectX).width();
       
   780     if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
       
   781         // If the rectangle is fully visible, use the specified visible behavior.
       
   782         // If the rectangle is partially visible, but over a certain threshold,
       
   783         // then treat it as fully visible to avoid unnecessary horizontal scrolling
       
   784         scrollX = getVisibleBehavior(alignX);
       
   785     else if (intersectWidth == visibleRect.width()) {
       
   786         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
       
   787         scrollX = getVisibleBehavior(alignX);
       
   788         if (scrollX == alignCenter)
       
   789             scrollX = noScroll;
       
   790     } else if (intersectWidth > 0)
       
   791         // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
       
   792         scrollX = getPartialBehavior(alignX);
       
   793     else
       
   794         scrollX = getHiddenBehavior(alignX);
       
   795     // If we're trying to align to the closest edge, and the exposeRect is further right
       
   796     // than the visibleRect, and not bigger than the visible area, then align with the right.
       
   797     if (scrollX == alignToClosestEdge && exposeRect.right() > visibleRect.right() && exposeRect.width() < visibleRect.width())
       
   798         scrollX = alignRight;
       
   799 
       
   800     // Given the X behavior, compute the X coordinate.
       
   801     int x;
       
   802     if (scrollX == noScroll) 
       
   803         x = visibleRect.x();
       
   804     else if (scrollX == alignRight)
       
   805         x = exposeRect.right() - visibleRect.width();
       
   806     else if (scrollX == alignCenter)
       
   807         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
       
   808     else
       
   809         x = exposeRect.x();
       
   810 
       
   811     // Determine the appropriate Y behavior.
       
   812     ScrollBehavior scrollY;
       
   813     IntRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
       
   814     int intersectHeight = intersection(visibleRect, exposeRectY).height();
       
   815     if (intersectHeight == exposeRect.height())
       
   816         // If the rectangle is fully visible, use the specified visible behavior.
       
   817         scrollY = getVisibleBehavior(alignY);
       
   818     else if (intersectHeight == visibleRect.height()) {
       
   819         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
       
   820         scrollY = getVisibleBehavior(alignY);
       
   821         if (scrollY == alignCenter)
       
   822             scrollY = noScroll;
       
   823     } else if (intersectHeight > 0)
       
   824         // If the rectangle is partially visible, use the specified partial behavior
       
   825         scrollY = getPartialBehavior(alignY);
       
   826     else
       
   827         scrollY = getHiddenBehavior(alignY);
       
   828     // If we're trying to align to the closest edge, and the exposeRect is further down
       
   829     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
       
   830     if (scrollY == alignToClosestEdge && exposeRect.bottom() > visibleRect.bottom() && exposeRect.height() < visibleRect.height())
       
   831         scrollY = alignBottom;
       
   832 
       
   833     // Given the Y behavior, compute the Y coordinate.
       
   834     int y;
       
   835     if (scrollY == noScroll) 
       
   836         y = visibleRect.y();
       
   837     else if (scrollY == alignBottom)
       
   838         y = exposeRect.bottom() - visibleRect.height();
       
   839     else if (scrollY == alignCenter)
       
   840         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
       
   841     else
       
   842         y = exposeRect.y();
       
   843 
       
   844     return IntRect(IntPoint(x, y), visibleRect.size());
       
   845 }
       
   846 
       
   847 void RenderLayer::autoscroll()
       
   848 {
       
   849     Frame* frame = renderer()->document()->frame();
       
   850     if (!frame)
       
   851         return;
       
   852 
       
   853     FrameView* frameView = frame->view();
       
   854     if (!frameView)
       
   855         return;
       
   856 
       
   857     frame->eventHandler()->updateSelectionForMouseDrag();
       
   858 
       
   859     IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->currentMousePosition());
       
   860     scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), gAlignToEdgeIfNeeded, gAlignToEdgeIfNeeded);    
       
   861 }
       
   862 
       
   863 void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset)
       
   864 {
       
   865     if (!inResizeMode() || !m_object->hasOverflowClip())
       
   866         return;
       
   867 
       
   868     // Set the width and height of the shadow ancestor node if there is one.
       
   869     // This is necessary for textarea elements since the resizable layer is in the shadow content.
       
   870     Element* element = static_cast<Element*>(m_object->node()->shadowAncestorNode());
       
   871     RenderBox* renderer = static_cast<RenderBox*>(element->renderer());
       
   872 
       
   873     EResize resize = renderer->style()->resize();
       
   874     if (resize == RESIZE_NONE)
       
   875         return;
       
   876 
       
   877     Document* document = element->document();
       
   878     if (!document->frame()->eventHandler()->mousePressed())
       
   879         return;
       
   880 
       
   881     IntSize newOffset = offsetFromResizeCorner(document->view()->windowToContents(evt.pos()));
       
   882 
       
   883     IntSize currentSize = IntSize(renderer->width(), renderer->height());
       
   884 
       
   885     IntSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
       
   886     element->setMinimumSizeForResizing(minimumSize);
       
   887 
       
   888     IntSize difference = (currentSize + newOffset - oldOffset).expandedTo(minimumSize) - currentSize;
       
   889 
       
   890     CSSStyleDeclaration* style = element->style();
       
   891     bool isBoxSizingBorder = renderer->style()->boxSizing() == BORDER_BOX;
       
   892 
       
   893     ExceptionCode ec;
       
   894 
       
   895     if (difference.width()) {
       
   896         if (element && element->isControl()) {
       
   897             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
       
   898             style->setProperty(CSS_PROP_MARGIN_LEFT, String::number(renderer->marginLeft()) + "px", false, ec);
       
   899             style->setProperty(CSS_PROP_MARGIN_RIGHT, String::number(renderer->marginRight()) + "px", false, ec);
       
   900         }
       
   901         int baseWidth = renderer->width() - (isBoxSizingBorder ? 0
       
   902             : renderer->borderLeft() + renderer->paddingLeft() + renderer->borderRight() + renderer->paddingRight());
       
   903         style->setProperty(CSS_PROP_WIDTH, String::number(baseWidth + difference.width()) + "px", false, ec);
       
   904     }
       
   905 
       
   906     if (difference.height()) {
       
   907         if (element && element->isControl()) {
       
   908             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
       
   909             style->setProperty(CSS_PROP_MARGIN_TOP, String::number(renderer->marginTop()) + "px", false, ec);
       
   910             style->setProperty(CSS_PROP_MARGIN_BOTTOM, String::number(renderer->marginBottom()) + "px", false, ec);
       
   911         }
       
   912         int baseHeight = renderer->height() - (isBoxSizingBorder ? 0
       
   913             : renderer->borderTop() + renderer->paddingTop() + renderer->borderBottom() + renderer->paddingBottom());
       
   914         style->setProperty(CSS_PROP_HEIGHT, String::number(baseHeight + difference.height()) + "px", false, ec);
       
   915     }
       
   916 
       
   917     document->updateLayout();
       
   918 
       
   919     // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
       
   920 }
       
   921 
       
   922 PlatformScrollbar* RenderLayer::horizontalScrollbarWidget() const
       
   923 {
       
   924     if (m_hBar && m_hBar->isWidget())
       
   925         return static_cast<PlatformScrollbar*>(m_hBar.get());
       
   926     return 0;
       
   927 }
       
   928 
       
   929 PlatformScrollbar* RenderLayer::verticalScrollbarWidget() const
       
   930 {
       
   931     if (m_vBar && m_vBar->isWidget())
       
   932         return static_cast<PlatformScrollbar*>(m_vBar.get());
       
   933     return 0;
       
   934 }
       
   935 
       
   936 void RenderLayer::valueChanged(Scrollbar*)
       
   937 {
       
   938     // Update scroll position from scrollbars.
       
   939 
       
   940     bool needUpdate = false;
       
   941     int newX = scrollXOffset();
       
   942     int newY = m_scrollY;
       
   943     
       
   944     if (m_hBar) {
       
   945         newX = m_hBar->value();
       
   946         if (newX != scrollXOffset())
       
   947            needUpdate = true;
       
   948     }
       
   949 
       
   950     if (m_vBar) {
       
   951         newY = m_vBar->value();
       
   952         if (newY != m_scrollY)
       
   953            needUpdate = true;
       
   954     }
       
   955 
       
   956     if (needUpdate)
       
   957         scrollToOffset(newX, newY, false);
       
   958 }
       
   959 
       
   960 IntRect RenderLayer::windowClipRect() const
       
   961 {
       
   962     RenderView* view = renderer()->view();
       
   963     ASSERT(view);
       
   964     FrameView* frameView = view->frameView();
       
   965     if (!frameView)
       
   966         return IntRect();
       
   967     return frameView->windowClipRectForLayer(this, false);
       
   968 }
       
   969 
       
   970 PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
       
   971 {
       
   972     if (Scrollbar::hasPlatformScrollbars()) {
       
   973         RefPtr<PlatformScrollbar> widget = new PlatformScrollbar(this, orientation, RegularScrollbar);
       
   974         m_object->document()->view()->addChild(widget.get());
       
   975         return widget.release();
       
   976     }
       
   977     
       
   978     // FIXME: Create scrollbars using the engine.
       
   979     return 0;
       
   980 }
       
   981 
       
   982 void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
       
   983 {
       
   984     RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
       
   985     if (scrollbar) {
       
   986         if (scrollbar->isWidget())
       
   987             static_cast<PlatformScrollbar*>(scrollbar.get())->removeFromParent();
       
   988 
       
   989         // FIXME: Destroy the engine scrollbar.
       
   990         scrollbar = 0;
       
   991     }
       
   992 }
       
   993 
       
   994 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
       
   995 {
       
   996     if (hasScrollbar == (m_hBar != 0))
       
   997         return;
       
   998 
       
   999     if (hasScrollbar)
       
  1000         m_hBar = createScrollbar(HorizontalScrollbar);
       
  1001     else
       
  1002         destroyScrollbar(HorizontalScrollbar);
       
  1003 
       
  1004     // Force an update since we know the scrollbars have changed things.
       
  1005     if (m_object->document()->hasDashboardRegions())
       
  1006         m_object->document()->setDashboardRegionsDirty(true);
       
  1007 }
       
  1008 
       
  1009 void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
       
  1010 {
       
  1011     if (hasScrollbar == (m_vBar != 0))
       
  1012         return;
       
  1013 
       
  1014     if (hasScrollbar)
       
  1015         m_vBar = createScrollbar(VerticalScrollbar);
       
  1016     else
       
  1017         destroyScrollbar(VerticalScrollbar);
       
  1018 
       
  1019     // Force an update since we know the scrollbars have changed things.
       
  1020     if (m_object->document()->hasDashboardRegions())
       
  1021         m_object->document()->setDashboardRegionsDirty(true);
       
  1022 }
       
  1023 
       
  1024 int RenderLayer::verticalScrollbarWidth() const
       
  1025 {
       
  1026     if (!m_vBar)
       
  1027         return 0;
       
  1028     return m_vBar->width();
       
  1029 }
       
  1030 
       
  1031 int RenderLayer::horizontalScrollbarHeight() const
       
  1032 {
       
  1033     if (!m_hBar)
       
  1034         return 0;
       
  1035     return m_hBar->height();
       
  1036 }
       
  1037 
       
  1038 IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& p) const
       
  1039 {
       
  1040     // Currently the resize corner is always the bottom right corner
       
  1041     int x = width();
       
  1042     int y = height();
       
  1043     convertToLayerCoords(root(), x, y);
       
  1044     return p - IntPoint(x, y);
       
  1045 }
       
  1046 
       
  1047 static IntRect scrollCornerRect(RenderObject* renderer, const IntRect& absBounds)
       
  1048 {
       
  1049     int resizerWidth = PlatformScrollbar::verticalScrollbarWidth();
       
  1050     int resizerHeight = PlatformScrollbar::horizontalScrollbarHeight();
       
  1051     return IntRect(absBounds.right() - resizerWidth - renderer->style()->borderRightWidth(), 
       
  1052                    absBounds.bottom() - resizerHeight - renderer->style()->borderBottomWidth(), resizerWidth, resizerHeight);
       
  1053 }
       
  1054 
       
  1055 void RenderLayer::positionOverflowControls()
       
  1056 {
       
  1057     if (!m_hBar && !m_vBar && (!m_object->hasOverflowClip() || m_object->style()->resize() == RESIZE_NONE))
       
  1058         return;
       
  1059     
       
  1060     int x = 0;
       
  1061     int y = 0;
       
  1062     convertToLayerCoords(root(), x, y);
       
  1063     IntRect absBounds(x, y, m_object->width(), m_object->height());
       
  1064     
       
  1065     IntRect resizeControlRect;
       
  1066     if (m_object->style()->resize() != RESIZE_NONE)
       
  1067         resizeControlRect = scrollCornerRect(m_object, absBounds);
       
  1068     
       
  1069     int resizeControlSize = max(resizeControlRect.height(), 0);
       
  1070     if (m_vBar)
       
  1071         m_vBar->setRect(IntRect(absBounds.right() - m_object->borderRight() - m_vBar->width(),
       
  1072                                 absBounds.y() + m_object->borderTop(),
       
  1073                                 m_vBar->width(),
       
  1074                                 absBounds.height() - (m_object->borderTop() + m_object->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize)));
       
  1075 
       
  1076     resizeControlSize = max(resizeControlRect.width(), 0);
       
  1077     if (m_hBar)
       
  1078         m_hBar->setRect(IntRect(absBounds.x() + m_object->borderLeft(),
       
  1079                                 absBounds.bottom() - m_object->borderBottom() - m_hBar->height(),
       
  1080                                 absBounds.width() - (m_object->borderLeft() + m_object->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
       
  1081                                 m_hBar->height()));
       
  1082 }
       
  1083 
       
  1084 int RenderLayer::scrollWidth()
       
  1085 {
       
  1086     if (m_scrollDimensionsDirty)
       
  1087         computeScrollDimensions();
       
  1088     return m_scrollWidth;
       
  1089 }
       
  1090 
       
  1091 int RenderLayer::scrollHeight()
       
  1092 {
       
  1093     if (m_scrollDimensionsDirty)
       
  1094         computeScrollDimensions();
       
  1095     return m_scrollHeight;
       
  1096 }
       
  1097 
       
  1098 void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
       
  1099 {
       
  1100     m_scrollDimensionsDirty = false;
       
  1101     
       
  1102     bool ltr = m_object->style()->direction() == LTR;
       
  1103 
       
  1104     int clientWidth = m_object->clientWidth();
       
  1105     int clientHeight = m_object->clientHeight();
       
  1106 
       
  1107     m_scrollLeftOverflow = ltr ? 0 : min(0, m_object->leftmostPosition(true, false) - m_object->borderLeft());
       
  1108 
       
  1109     int rightPos = ltr ?
       
  1110                     m_object->rightmostPosition(true, false) - m_object->borderLeft() :
       
  1111                     clientWidth - m_scrollLeftOverflow;
       
  1112     int bottomPos = m_object->lowestPosition(true, false) - m_object->borderTop();
       
  1113 
       
  1114     m_scrollWidth = max(rightPos, clientWidth);
       
  1115     m_scrollHeight = max(bottomPos, clientHeight);
       
  1116     
       
  1117     m_scrollOriginX = ltr ? 0 : m_scrollWidth - clientWidth;
       
  1118 
       
  1119     if (needHBar)
       
  1120         *needHBar = rightPos > clientWidth;
       
  1121     if (needVBar)
       
  1122         *needVBar = bottomPos > clientHeight;
       
  1123 }
       
  1124 
       
  1125 void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
       
  1126 {
       
  1127     if (m_overflowStatusDirty) {
       
  1128         m_horizontalOverflow = horizontalOverflow;
       
  1129         m_verticalOverflow = verticalOverflow;
       
  1130         m_overflowStatusDirty = false;
       
  1131         
       
  1132         return;
       
  1133     }
       
  1134     
       
  1135     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
       
  1136     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
       
  1137     
       
  1138     if (horizontalOverflowChanged || verticalOverflowChanged) {
       
  1139         m_horizontalOverflow = horizontalOverflow;
       
  1140         m_verticalOverflow = verticalOverflow;
       
  1141         
       
  1142         if (FrameView* frameView = m_object->document()->view())
       
  1143             frameView->scheduleEvent(new OverflowEvent(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow),
       
  1144             EventTargetNodeCast(m_object->element()), true);
       
  1145     }
       
  1146 }
       
  1147 
       
  1148 void
       
  1149 RenderLayer::updateScrollInfoAfterLayout()
       
  1150 {
       
  1151     m_scrollDimensionsDirty = true;
       
  1152 
       
  1153     bool horizontalOverflow, verticalOverflow;
       
  1154     computeScrollDimensions(&horizontalOverflow, &verticalOverflow);
       
  1155 
       
  1156     if (m_object->style()->overflowX() != OMARQUEE) {
       
  1157         // Layout may cause us to be in an invalid scroll position.  In this case we need
       
  1158         // to pull our scroll offsets back to the max (or push them up to the min).
       
  1159         int newX = max(0, min(scrollXOffset(), scrollWidth() - m_object->clientWidth()));
       
  1160         int newY = max(0, min(m_scrollY, scrollHeight() - m_object->clientHeight()));
       
  1161         if (newX != scrollXOffset() || newY != m_scrollY) {
       
  1162             RenderView* view = m_object->view();
       
  1163             ASSERT(view);
       
  1164             // scrollToOffset() may call updateLayerPositions(), which doesn't work
       
  1165             // with LayoutState.
       
  1166             // FIXME: Remove the disableLayoutState/enableLayoutState if the above changes.
       
  1167             if (view)
       
  1168                 view->disableLayoutState();
       
  1169             scrollToOffset(newX, newY);
       
  1170             if (view)
       
  1171                 view->enableLayoutState();
       
  1172         }
       
  1173     }
       
  1174 
       
  1175     bool haveHorizontalBar = m_hBar;
       
  1176     bool haveVerticalBar = m_vBar;
       
  1177     
       
  1178     // overflow:scroll should just enable/disable.
       
  1179     if (m_object->style()->overflowX() == OSCROLL)
       
  1180         m_hBar->setEnabled(horizontalOverflow);
       
  1181     if (m_object->style()->overflowY() == OSCROLL)
       
  1182         m_vBar->setEnabled(verticalOverflow);
       
  1183 
       
  1184     // A dynamic change from a scrolling overflow to overflow:hidden means we need to get rid of any
       
  1185     // scrollbars that may be present.
       
  1186     if (m_object->style()->overflowX() == OHIDDEN && haveHorizontalBar)
       
  1187         setHasHorizontalScrollbar(false);
       
  1188     if (m_object->style()->overflowY() == OHIDDEN && haveVerticalBar)
       
  1189         setHasVerticalScrollbar(false);
       
  1190     
       
  1191     // overflow:auto may need to lay out again if scrollbars got added/removed.
       
  1192     bool scrollbarsChanged = (m_object->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow) || 
       
  1193                              (m_object->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow);    
       
  1194     if (scrollbarsChanged) {
       
  1195         if (m_object->hasAutoHorizontalScrollbar())
       
  1196             setHasHorizontalScrollbar(horizontalOverflow);
       
  1197         if (m_object->hasAutoVerticalScrollbar())
       
  1198             setHasVerticalScrollbar(verticalOverflow);
       
  1199 
       
  1200         // Force an update since we know the scrollbars have changed things.
       
  1201         if (m_object->document()->hasDashboardRegions())
       
  1202             m_object->document()->setDashboardRegionsDirty(true);
       
  1203 
       
  1204         m_object->repaint();
       
  1205 
       
  1206         if (m_object->style()->overflowX() == OAUTO || m_object->style()->overflowY() == OAUTO) {
       
  1207             if (!m_inOverflowRelayout) {
       
  1208                 // Our proprietary overflow: overlay value doesn't trigger a layout.
       
  1209                 m_inOverflowRelayout = true;
       
  1210                 m_object->setNeedsLayout(true);
       
  1211                 if (m_object->isRenderBlock())
       
  1212                     static_cast<RenderBlock*>(m_object)->layoutBlock(true);
       
  1213                 else
       
  1214                     m_object->layout();
       
  1215                 m_inOverflowRelayout = false;
       
  1216             }
       
  1217         }
       
  1218     }
       
  1219     
       
  1220     // If overflow:scroll is turned into overflow:auto a bar might still be disabled (Bug 11985).
       
  1221     if (m_hBar && m_object->hasAutoHorizontalScrollbar())
       
  1222         m_hBar->setEnabled(true);
       
  1223     if (m_vBar && m_object->hasAutoVerticalScrollbar())
       
  1224         m_vBar->setEnabled(true);
       
  1225 
       
  1226     // Set up the range (and page step/line step).
       
  1227     if (m_hBar) {
       
  1228         int clientWidth = m_object->clientWidth();
       
  1229         int pageStep = (clientWidth-PAGE_KEEP);
       
  1230         if (pageStep < 0) pageStep = clientWidth;
       
  1231         m_hBar->setSteps(LINE_STEP, pageStep);
       
  1232         m_hBar->setProportion(clientWidth, m_scrollWidth);
       
  1233         m_hBar->setValue(scrollXOffset());
       
  1234     }
       
  1235     if (m_vBar) {
       
  1236         int clientHeight = m_object->clientHeight();
       
  1237         int pageStep = (clientHeight-PAGE_KEEP);
       
  1238         if (pageStep < 0) pageStep = clientHeight;
       
  1239         m_vBar->setSteps(LINE_STEP, pageStep);
       
  1240         m_vBar->setProportion(clientHeight, m_scrollHeight);
       
  1241         m_object->repaintRectangle(IntRect(m_object->borderLeft() + m_object->clientWidth(),
       
  1242                                    m_object->borderTop(), verticalScrollbarWidth(), 
       
  1243                                    m_object->height() - m_object->borderTop() - m_object->borderBottom()));
       
  1244     }
       
  1245  
       
  1246     if (m_object->element() && m_object->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
       
  1247         updateOverflowStatus(horizontalOverflow, verticalOverflow);
       
  1248 }
       
  1249 
       
  1250 void RenderLayer::paintOverflowControls(GraphicsContext* p, int tx, int ty, const IntRect& damageRect)
       
  1251 {
       
  1252     // Don't do anything if we have no overflow.
       
  1253     if (!m_object->hasOverflowClip())
       
  1254         return;
       
  1255     
       
  1256     // Move the scrollbar widgets if necessary.  We normally move and resize widgets during layout, but sometimes
       
  1257     // widgets can move without layout occurring (most notably when you scroll a document that
       
  1258     // contains fixed positioned elements).
       
  1259     positionOverflowControls();
       
  1260 
       
  1261     // Now that we're sure the scrollbars are in the right place, paint them.
       
  1262     if (m_hBar)
       
  1263         m_hBar->paint(p, damageRect);
       
  1264     if (m_vBar)
       
  1265         m_vBar->paint(p, damageRect);
       
  1266     
       
  1267     // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
       
  1268     // edge of the box.
       
  1269     IntRect paddingBox(m_object->xPos() + m_object->borderLeft() + tx, 
       
  1270                        m_object->yPos() + m_object->borderTop() + ty, 
       
  1271                        m_object->width() - m_object->borderLeft() - m_object->borderRight(),
       
  1272                        m_object->height() - m_object->borderTop() - m_object->borderBottom());
       
  1273     IntRect hCorner;
       
  1274     if (m_hBar && paddingBox.width() - m_hBar->width() > 0) {
       
  1275         hCorner = IntRect(paddingBox.x() + m_hBar->width(),
       
  1276                           paddingBox.y() + paddingBox.height() - m_hBar->height(),
       
  1277                           paddingBox.width() - m_hBar->width(),
       
  1278                           m_hBar->height());
       
  1279         if (hCorner.intersects(damageRect))
       
  1280             p->fillRect(hCorner, Color::white);
       
  1281     }
       
  1282     if (m_vBar && paddingBox.height() - m_vBar->height() > 0) {
       
  1283         IntRect vCorner(paddingBox.x() + paddingBox.width() - m_vBar->width(),
       
  1284                         paddingBox.y() + m_vBar->height(),
       
  1285                         m_vBar->width(),
       
  1286                         paddingBox.height() - m_vBar->height());
       
  1287         if (vCorner != hCorner && vCorner.intersects(damageRect))
       
  1288             p->fillRect(vCorner, Color::white);
       
  1289     }
       
  1290 
       
  1291     if (m_object->style()->resize() != RESIZE_NONE)  {
       
  1292         IntRect absBounds(m_object->xPos() + tx, m_object->yPos() + ty, m_object->width(), m_object->height());
       
  1293         IntRect scrollCorner = scrollCornerRect(m_object, absBounds);
       
  1294         if (!scrollCorner.intersects(damageRect))
       
  1295             return;
       
  1296 
       
  1297         // Paint the resizer control.
       
  1298         static Image* resizeCornerImage;
       
  1299         if (!resizeCornerImage)
       
  1300             resizeCornerImage = Image::loadPlatformResource("textAreaResizeCorner");
       
  1301         IntPoint imagePoint(scrollCorner.right() - resizeCornerImage->width(), scrollCorner.bottom() - resizeCornerImage->height());
       
  1302         p->drawImage(resizeCornerImage, imagePoint);
       
  1303 
       
  1304         // Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
       
  1305         // Clipping will exclude the right and bottom edges of this frame.
       
  1306         if (m_hBar || m_vBar) {
       
  1307             p->save();
       
  1308             scrollCorner.setSize(IntSize(scrollCorner.width() + 1, scrollCorner.height() + 1));
       
  1309             p->setStrokeColor(Color(makeRGB(217, 217, 217)));
       
  1310             p->setStrokeThickness(1.0f);
       
  1311             p->setFillColor(Color::transparent);
       
  1312             p->drawRect(scrollCorner);
       
  1313             p->restore();
       
  1314         }
       
  1315     }
       
  1316 }
       
  1317 
       
  1318 bool RenderLayer::isPointInResizeControl(const IntPoint& point)
       
  1319 {
       
  1320     if (!m_object->hasOverflowClip() || m_object->style()->resize() == RESIZE_NONE)
       
  1321         return false;
       
  1322     
       
  1323     int x = 0;
       
  1324     int y = 0;
       
  1325     convertToLayerCoords(root(), x, y);
       
  1326     IntRect absBounds(x, y, m_object->width(), m_object->height());
       
  1327     return scrollCornerRect(m_object, absBounds).contains(point);
       
  1328 }
       
  1329     
       
  1330 bool RenderLayer::hitTestOverflowControls(HitTestResult& result)
       
  1331 {
       
  1332     if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
       
  1333         return false;
       
  1334 
       
  1335     int x = 0;
       
  1336     int y = 0;
       
  1337     convertToLayerCoords(root(), x, y);
       
  1338     IntRect absBounds(x, y, renderer()->width(), renderer()->height());
       
  1339     
       
  1340     IntRect resizeControlRect;
       
  1341     if (renderer()->style()->resize() != RESIZE_NONE) {
       
  1342         resizeControlRect = scrollCornerRect(renderer(), absBounds);
       
  1343         if (resizeControlRect.contains(result.point()))
       
  1344             return true;
       
  1345     }
       
  1346 
       
  1347     int resizeControlSize = max(resizeControlRect.height(), 0);
       
  1348 
       
  1349     if (m_vBar) {
       
  1350         IntRect vBarRect(absBounds.right() - renderer()->borderRight() - m_vBar->width(), absBounds.y() + renderer()->borderTop(), m_vBar->width(), absBounds.height() - (renderer()->borderTop() + renderer()->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
       
  1351         if (vBarRect.contains(result.point())) {
       
  1352             result.setScrollbar(verticalScrollbarWidget());
       
  1353             return true;
       
  1354         }
       
  1355     }
       
  1356 
       
  1357     resizeControlSize = max(resizeControlRect.width(), 0);
       
  1358     if (m_hBar) {
       
  1359         IntRect hBarRect(absBounds.x() + renderer()->borderLeft(), absBounds.bottom() - renderer()->borderBottom() - m_hBar->height(), absBounds.width() - (renderer()->borderLeft() + renderer()->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize), m_hBar->height());
       
  1360         if (hBarRect.contains(result.point())) {
       
  1361             result.setScrollbar(horizontalScrollbarWidget());
       
  1362             return true;
       
  1363         }
       
  1364     }
       
  1365 
       
  1366     return false;
       
  1367 }
       
  1368 
       
  1369 bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
       
  1370 {
       
  1371     bool didHorizontalScroll = false;
       
  1372     bool didVerticalScroll = false;
       
  1373     
       
  1374     if (m_hBar) {
       
  1375         if (granularity == ScrollByDocument) {
       
  1376             // Special-case for the ScrollByDocument granularity. A document scroll can only be up 
       
  1377             // or down and in both cases the horizontal bar goes all the way to the left.
       
  1378             didHorizontalScroll = m_hBar->scroll(ScrollLeft, ScrollByDocument, multiplier);
       
  1379         } else
       
  1380             didHorizontalScroll = m_hBar->scroll(direction, granularity, multiplier);
       
  1381     }
       
  1382 
       
  1383     if (m_vBar)
       
  1384         didVerticalScroll = m_vBar->scroll(direction, granularity, multiplier);
       
  1385 
       
  1386     return (didHorizontalScroll || didVerticalScroll);
       
  1387 }
       
  1388 
       
  1389 void
       
  1390 RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintRestriction paintRestriction, RenderObject *paintingRoot)
       
  1391 {
       
  1392     paintLayer(this, p, damageRect, false, paintRestriction, paintingRoot);
       
  1393 }
       
  1394 
       
  1395 static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
       
  1396 {
       
  1397     // Work around bugs in focus ring clipping on Mac.
       
  1398     p->setFocusRingClip(clipRect);
       
  1399     if (paintDirtyRect == clipRect)
       
  1400         return;
       
  1401     p->save();
       
  1402     p->clip(clipRect);
       
  1403 }
       
  1404 
       
  1405 static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
       
  1406 {
       
  1407     // Work around bugs in focus ring clipping on Mac.
       
  1408     p->clearFocusRingClip();
       
  1409     if (paintDirtyRect == clipRect)
       
  1410         return;
       
  1411     p->restore();
       
  1412 }
       
  1413 
       
  1414 void
       
  1415 RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
       
  1416                         const IntRect& paintDirtyRect, bool haveTransparency, PaintRestriction paintRestriction,
       
  1417                         RenderObject *paintingRoot)
       
  1418 {
       
  1419     // Avoid painting layers when stylesheets haven't loaded.  This eliminates FOUC.
       
  1420     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
       
  1421     // will do a full repaint().
       
  1422     if (renderer()->document()->didLayoutWithPendingStylesheets() && !renderer()->isRenderView() && !renderer()->isRoot())
       
  1423         return;
       
  1424     
       
  1425     // Calculate the clip rects we should use.
       
  1426     IntRect layerBounds, damageRect, clipRectToApply, outlineRect;
       
  1427     calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
       
  1428     int x = layerBounds.x();
       
  1429     int y = layerBounds.y();
       
  1430     int tx = x - renderer()->xPos();
       
  1431     int ty = y - renderer()->yPos() + renderer()->borderTopExtra();
       
  1432                              
       
  1433     // Ensure our lists are up-to-date.
       
  1434     updateZOrderLists();
       
  1435     updateOverflowList();
       
  1436 
       
  1437     // If this layer is totally invisible then there is nothing to paint.
       
  1438     if (!m_object->opacity())
       
  1439         return;
       
  1440         
       
  1441     bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText;
       
  1442     bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText;
       
  1443 
       
  1444     if (isTransparent())
       
  1445         haveTransparency = true;
       
  1446 
       
  1447     // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
       
  1448     // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
       
  1449     // Else, our renderer tree may or may not contain the painting root, so we pass that root along
       
  1450     // so it will be tested against as we decend through the renderers.
       
  1451     RenderObject *paintingRootForRenderer = 0;
       
  1452     if (paintingRoot && !m_object->isDescendantOf(paintingRoot))
       
  1453         paintingRootForRenderer = paintingRoot;
       
  1454     
       
  1455     // We want to paint our layer, but only if we intersect the damage rect.
       
  1456     bool shouldPaint = intersectsDamageRect(layerBounds, damageRect) && m_hasVisibleContent;
       
  1457     if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
       
  1458         // Begin transparency layers lazily now that we know we have to paint something.
       
  1459         if (haveTransparency)
       
  1460             beginTransparencyLayers(p, paintDirtyRect);
       
  1461         
       
  1462         // Paint our background first, before painting any child layers.
       
  1463         // Establish the clip used to paint our background.
       
  1464         setClip(p, paintDirtyRect, damageRect);
       
  1465 
       
  1466         // Paint the background.
       
  1467         RenderObject::PaintInfo paintInfo(p, damageRect, PaintPhaseBlockBackground, false, paintingRootForRenderer, 0);
       
  1468         renderer()->paint(paintInfo, tx, ty);
       
  1469 
       
  1470         // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
       
  1471         // z-index.  We paint after we painted the background/border, so that the scrollbars will
       
  1472         // sit above the background/border.
       
  1473         paintOverflowControls(p, tx, ty, damageRect);
       
  1474         
       
  1475         // Restore the clip.
       
  1476         restoreClip(p, paintDirtyRect, damageRect);
       
  1477     }
       
  1478 
       
  1479     // Now walk the sorted list of children with negative z-indices.
       
  1480     if (m_negZOrderList)
       
  1481         for (Vector<RenderLayer*>::iterator it = m_negZOrderList->begin(); it != m_negZOrderList->end(); ++it)
       
  1482             it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
       
  1483     
       
  1484     // Now establish the appropriate clip and paint our child RenderObjects.
       
  1485     if (shouldPaint && !clipRectToApply.isEmpty()) {
       
  1486         // Begin transparency layers lazily now that we know we have to paint something.
       
  1487         if (haveTransparency)
       
  1488             beginTransparencyLayers(p, paintDirtyRect);
       
  1489 
       
  1490         // Set up the clip used when painting our children.
       
  1491         setClip(p, paintDirtyRect, clipRectToApply);
       
  1492         RenderObject::PaintInfo paintInfo(p, clipRectToApply, 
       
  1493                                           selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds,
       
  1494                                           forceBlackText, paintingRootForRenderer, 0);
       
  1495         renderer()->paint(paintInfo, tx, ty);
       
  1496         if (!selectionOnly) {
       
  1497             paintInfo.phase = PaintPhaseFloat;
       
  1498             renderer()->paint(paintInfo, tx, ty);
       
  1499             paintInfo.phase = PaintPhaseForeground;
       
  1500             renderer()->paint(paintInfo, tx, ty);
       
  1501             paintInfo.phase = PaintPhaseChildOutlines;
       
  1502             renderer()->paint(paintInfo, tx, ty);
       
  1503         }
       
  1504 
       
  1505         // Now restore our clip.
       
  1506         restoreClip(p, paintDirtyRect, clipRectToApply);
       
  1507     }
       
  1508     
       
  1509     if (!outlineRect.isEmpty()) {
       
  1510         // Paint our own outline
       
  1511         RenderObject::PaintInfo paintInfo(p, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0);
       
  1512         setClip(p, paintDirtyRect, outlineRect);
       
  1513         renderer()->paint(paintInfo, tx, ty);
       
  1514         restoreClip(p, paintDirtyRect, outlineRect);
       
  1515     }
       
  1516     
       
  1517     // Paint any child layers that have overflow.
       
  1518     if (m_overflowList)
       
  1519         for (Vector<RenderLayer*>::iterator it = m_overflowList->begin(); it != m_overflowList->end(); ++it)
       
  1520             it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
       
  1521     
       
  1522     // Now walk the sorted list of children with positive z-indices.
       
  1523     if (m_posZOrderList)
       
  1524         for (Vector<RenderLayer*>::iterator it = m_posZOrderList->begin(); it != m_posZOrderList->end(); ++it)
       
  1525             it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
       
  1526     
       
  1527     // End our transparency layer
       
  1528     if (isTransparent() && m_usedTransparency) {
       
  1529         p->endTransparencyLayer();
       
  1530         p->restore();
       
  1531         m_usedTransparency = false;
       
  1532     }
       
  1533 }
       
  1534 
       
  1535 static inline IntRect frameVisibleRect(RenderObject* renderer)
       
  1536 {
       
  1537     FrameView* frameView = renderer->document()->view();
       
  1538     if (!frameView)
       
  1539         return IntRect();
       
  1540 
       
  1541     return enclosingIntRect(frameView->visibleContentRect());
       
  1542 }
       
  1543 
       
  1544 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
       
  1545 {
       
  1546     renderer()->document()->updateLayout();
       
  1547     
       
  1548     IntRect boundsRect(m_x, m_y, width(), height());
       
  1549     boundsRect.intersect(frameVisibleRect(renderer()));
       
  1550 
       
  1551     RenderLayer* insideLayer = hitTestLayer(this, request, result, boundsRect);
       
  1552 
       
  1553     // Now determine if the result is inside an anchor; make sure an image map wins if
       
  1554     // it already set URLElement and only use the innermost.
       
  1555     Node* node = result.innerNode();
       
  1556     while (node) {
       
  1557         // for imagemaps, URLElement is the associated area element not the image itself
       
  1558         if (node->isLink() && !result.URLElement() && !node->hasTagName(imgTag))
       
  1559             result.setURLElement(static_cast<Element*>(node));
       
  1560         node = node->parentNode();
       
  1561     }
       
  1562 
       
  1563     // Next set up the correct :hover/:active state along the new chain.
       
  1564     updateHoverActiveState(request, result);
       
  1565     
       
  1566     // Now return whether we were inside this layer (this will always be true for the root
       
  1567     // layer).
       
  1568     return insideLayer;
       
  1569 }
       
  1570 
       
  1571 Node* RenderLayer::enclosingElement() const
       
  1572 {
       
  1573     for (RenderObject* r = renderer(); r; r = r->parent()) {
       
  1574         if (Node* e = r->element())
       
  1575             return e;
       
  1576     }
       
  1577     ASSERT_NOT_REACHED();
       
  1578     return 0;
       
  1579 }
       
  1580 
       
  1581 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequest& request,
       
  1582     HitTestResult& result, const IntRect& hitTestRect)
       
  1583 {
       
  1584     // Calculate the clip rects we should use.
       
  1585     IntRect layerBounds;
       
  1586     IntRect bgRect;
       
  1587     IntRect fgRect;
       
  1588     IntRect outlineRect;
       
  1589     calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect, outlineRect);
       
  1590     
       
  1591     // Ensure our lists are up-to-date.
       
  1592     updateZOrderLists();
       
  1593     updateOverflowList();
       
  1594 
       
  1595     // This variable tracks which layer the mouse ends up being inside.  The minute we find an insideLayer,
       
  1596     // we are done and can return it.
       
  1597     RenderLayer* insideLayer = 0;
       
  1598     
       
  1599     // Begin by walking our list of positive layers from highest z-index down to the lowest
       
  1600     // z-index.
       
  1601     if (m_posZOrderList) {
       
  1602         for (int i = m_posZOrderList->size() - 1; i >= 0; --i) {
       
  1603             insideLayer = m_posZOrderList->at(i)->hitTestLayer(rootLayer, request, result, hitTestRect);
       
  1604             if (insideLayer)
       
  1605                 return insideLayer;
       
  1606         }
       
  1607     }
       
  1608 
       
  1609     // Now check our overflow objects.
       
  1610     if (m_overflowList) {
       
  1611         for (int i = m_overflowList->size() - 1; i >= 0; --i) {
       
  1612             insideLayer = m_overflowList->at(i)->hitTestLayer(rootLayer, request, result, hitTestRect);
       
  1613             if (insideLayer)
       
  1614                 return insideLayer;
       
  1615         }
       
  1616     }
       
  1617 
       
  1618     // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
       
  1619     if (fgRect.contains(result.point()) && 
       
  1620         renderer()->hitTest(request, result, result.point().x(), result.point().y(),
       
  1621                             layerBounds.x() - renderer()->xPos(),
       
  1622                             layerBounds.y() - renderer()->yPos() + m_object->borderTopExtra(), 
       
  1623                             HitTestDescendants)) {
       
  1624         // For positioned generated content, we might still not have a
       
  1625         // node by the time we get to the layer level, since none of
       
  1626         // the content in the layer has an element. So just walk up
       
  1627         // the tree.
       
  1628         if (!result.innerNode() || !result.innerNonSharedNode()) {
       
  1629             Node* e = enclosingElement();
       
  1630             if (!result.innerNode())
       
  1631                 result.setInnerNode(e);
       
  1632             if (!result.innerNonSharedNode())
       
  1633                 result.setInnerNonSharedNode(e);
       
  1634         }
       
  1635 
       
  1636         return this;
       
  1637     }
       
  1638         
       
  1639     // Now check our negative z-index children.
       
  1640     if (m_negZOrderList) {
       
  1641         for (int i = m_negZOrderList->size() - 1; i >= 0; --i) {
       
  1642             insideLayer = m_negZOrderList->at(i)->hitTestLayer(rootLayer, request, result, hitTestRect);
       
  1643             if (insideLayer)
       
  1644                 return insideLayer;
       
  1645         }
       
  1646     }
       
  1647 
       
  1648     // Next we want to see if the mouse is inside this layer but not any of its children.
       
  1649     if (bgRect.contains(result.point()) &&
       
  1650         renderer()->hitTest(request, result, result.point().x(), result.point().y(),
       
  1651                             layerBounds.x() - renderer()->xPos(),
       
  1652                             layerBounds.y() - renderer()->yPos() + m_object->borderTopExtra(),
       
  1653                             HitTestSelf)) {
       
  1654         if (!result.innerNode() || !result.innerNonSharedNode()) {
       
  1655             Node* e = enclosingElement();
       
  1656             if (!result.innerNode())
       
  1657                 result.setInnerNode(e);
       
  1658             if (!result.innerNonSharedNode())
       
  1659                 result.setInnerNonSharedNode(e);
       
  1660         }
       
  1661 
       
  1662         return this;
       
  1663     }
       
  1664 
       
  1665     // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, 
       
  1666     // return ourselves. We do this so mouse events continue getting delivered after a drag has 
       
  1667     // exited the WebView, and so hit testing over a scrollbar hits the content document.
       
  1668     if ((request.active || request.mouseUp) && renderer()->isRenderView()) {
       
  1669         renderer()->updateHitTestResult(result, result.point());
       
  1670         return this;
       
  1671     }
       
  1672 
       
  1673     return 0;
       
  1674 }
       
  1675 
       
  1676 void RenderLayer::calculateClipRects(const RenderLayer* rootLayer)
       
  1677 {
       
  1678     if (m_clipRects)
       
  1679         return; // We have the correct cached value.
       
  1680 
       
  1681     if (!parent()) {
       
  1682         // The root layer's clip rect is always just its dimensions.
       
  1683         m_clipRects = new (m_object->renderArena()) ClipRects(IntRect(0,0,width(),height()));
       
  1684         m_clipRects->ref();
       
  1685         return;
       
  1686     }
       
  1687 
       
  1688     // Ensure that our parent's clip has been calculated so that we can examine the values.
       
  1689     parent()->calculateClipRects(rootLayer);
       
  1690 
       
  1691     // Set up our three rects to initially match the parent rects.
       
  1692     IntRect posClipRect(parent()->clipRects()->posClipRect());
       
  1693     IntRect overflowClipRect(parent()->clipRects()->overflowClipRect());
       
  1694     IntRect fixedClipRect(parent()->clipRects()->fixedClipRect());
       
  1695     bool fixed = parent()->clipRects()->fixed();
       
  1696 
       
  1697     // A fixed object is essentially the root of its containing block hierarchy, so when
       
  1698     // we encounter such an object, we reset our clip rects to the fixedClipRect.
       
  1699     if (m_object->style()->position() == FixedPosition) {
       
  1700         posClipRect = fixedClipRect;
       
  1701         overflowClipRect = fixedClipRect;
       
  1702         fixed = true;
       
  1703     }
       
  1704     else if (m_object->style()->position() == RelativePosition)
       
  1705         posClipRect = overflowClipRect;
       
  1706     else if (m_object->style()->position() == AbsolutePosition)
       
  1707         overflowClipRect = posClipRect;
       
  1708     
       
  1709     // Update the clip rects that will be passed to child layers.
       
  1710     if (m_object->hasOverflowClip() || m_object->hasClip()) {
       
  1711         // This layer establishes a clip of some kind.
       
  1712         int x = 0;
       
  1713         int y = 0;
       
  1714         convertToLayerCoords(rootLayer, x, y);
       
  1715         RenderView* view = renderer()->view();
       
  1716         ASSERT(view);
       
  1717         if (view && fixed) {
       
  1718             x -= view->frameView()->contentsX();
       
  1719             y -= view->frameView()->contentsY();
       
  1720         }
       
  1721         
       
  1722         if (m_object->hasOverflowClip()) {
       
  1723             IntRect newOverflowClip = m_object->getOverflowClipRect(x,y);
       
  1724             overflowClipRect.intersect(newOverflowClip);
       
  1725             if (m_object->isPositioned() || m_object->isRelPositioned())
       
  1726                 posClipRect.intersect(newOverflowClip);
       
  1727         }
       
  1728         if (m_object->hasClip()) {
       
  1729             IntRect newPosClip = m_object->getClipRect(x,y);
       
  1730             posClipRect.intersect(newPosClip);
       
  1731             overflowClipRect.intersect(newPosClip);
       
  1732             fixedClipRect.intersect(newPosClip);
       
  1733         }
       
  1734     }
       
  1735     
       
  1736     // If our clip rects match our parent's clip, then we can just share its data structure and
       
  1737     // ref count.
       
  1738     if (fixed == parent()->clipRects()->fixed() &&
       
  1739         posClipRect == parent()->clipRects()->posClipRect() &&
       
  1740         overflowClipRect == parent()->clipRects()->overflowClipRect() &&
       
  1741         fixedClipRect == parent()->clipRects()->fixedClipRect())
       
  1742         m_clipRects = parent()->clipRects();
       
  1743     else
       
  1744         m_clipRects = new (m_object->renderArena()) ClipRects(overflowClipRect, fixedClipRect, posClipRect, fixed);
       
  1745     m_clipRects->ref();
       
  1746 }
       
  1747 
       
  1748 void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds,
       
  1749                                  IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect) const
       
  1750 {
       
  1751     if (parent()) {
       
  1752         parent()->calculateClipRects(rootLayer);
       
  1753 
       
  1754         backgroundRect = m_object->style()->position() == FixedPosition ? parent()->clipRects()->fixedClipRect() :
       
  1755                          (m_object->isPositioned() ? parent()->clipRects()->posClipRect() : 
       
  1756                                                      parent()->clipRects()->overflowClipRect());
       
  1757         RenderView* view = renderer()->view();
       
  1758         ASSERT(view);
       
  1759         if (view && parent()->clipRects()->fixed())
       
  1760             backgroundRect.move(view->frameView()->contentsX(), view->frameView()->contentsY());
       
  1761 
       
  1762         backgroundRect.intersect(paintDirtyRect);
       
  1763     } else
       
  1764         backgroundRect = paintDirtyRect;
       
  1765     foregroundRect = backgroundRect;
       
  1766     outlineRect = backgroundRect;
       
  1767     
       
  1768     int x = 0;
       
  1769     int y = 0;
       
  1770     convertToLayerCoords(rootLayer, x, y);
       
  1771     layerBounds = IntRect(x,y,width(),height());
       
  1772     
       
  1773     // Update the clip rects that will be passed to child layers.
       
  1774     if (m_object->hasOverflowClip() || m_object->hasClip()) {
       
  1775         // This layer establishes a clip of some kind.
       
  1776         if (m_object->hasOverflowClip())
       
  1777             foregroundRect.intersect(m_object->getOverflowClipRect(x,y));
       
  1778         if (m_object->hasClip()) {
       
  1779             // Clip applies to *us* as well, so go ahead and update the damageRect.
       
  1780             IntRect newPosClip = m_object->getClipRect(x,y);
       
  1781             backgroundRect.intersect(newPosClip);
       
  1782             foregroundRect.intersect(newPosClip);
       
  1783             outlineRect.intersect(newPosClip);
       
  1784         }
       
  1785 
       
  1786         // If we establish a clip at all, then go ahead and make sure our background
       
  1787         // rect is intersected with our layer's bounds.
       
  1788         if (ShadowData* boxShadow = renderer()->style()->boxShadow()) {
       
  1789             IntRect shadowRect = layerBounds;
       
  1790             shadowRect.move(boxShadow->x, boxShadow->y);
       
  1791             shadowRect.inflate(boxShadow->blur);
       
  1792             shadowRect.unite(layerBounds);
       
  1793             backgroundRect.intersect(shadowRect);
       
  1794         } else
       
  1795             backgroundRect.intersect(layerBounds);
       
  1796     }
       
  1797 }
       
  1798 
       
  1799 IntRect RenderLayer::childrenClipRect() const
       
  1800 {
       
  1801     RenderLayer* rootLayer = renderer()->document()->renderer()->layer();
       
  1802     IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
       
  1803     calculateRects(rootLayer, rootLayer->absoluteBoundingBox(), layerBounds, backgroundRect, foregroundRect, outlineRect);
       
  1804     return foregroundRect;
       
  1805 }
       
  1806 
       
  1807 IntRect RenderLayer::selfClipRect() const
       
  1808 {
       
  1809     RenderLayer* rootLayer = renderer()->document()->renderer()->layer();
       
  1810     IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
       
  1811     calculateRects(rootLayer, rootLayer->absoluteBoundingBox(), layerBounds, backgroundRect, foregroundRect, outlineRect);
       
  1812     return backgroundRect;
       
  1813 }
       
  1814 
       
  1815 bool RenderLayer::intersectsDamageRect(const IntRect& layerBounds, const IntRect& damageRect) const
       
  1816 {
       
  1817     // Always examine the canvas and the root.
       
  1818     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
       
  1819     // paints the root's background.
       
  1820     if (renderer()->isRenderView() || renderer()->isRoot())
       
  1821         return true;
       
  1822 
       
  1823     // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we 
       
  1824     // can go ahead and return true.
       
  1825     RenderView* view = renderer()->view();
       
  1826     ASSERT(view);
       
  1827     if (view && !renderer()->isInlineFlow()) {
       
  1828         IntRect b = layerBounds;
       
  1829         b.inflate(view->maximalOutlineSize());
       
  1830         if (b.intersects(damageRect))
       
  1831             return true;
       
  1832     }
       
  1833         
       
  1834     // Otherwise we need to compute the bounding box of this single layer and see if it intersects
       
  1835     // the damage rect.
       
  1836     return absoluteBoundingBox().intersects(damageRect);
       
  1837 }
       
  1838 
       
  1839 IntRect RenderLayer::absoluteBoundingBox() const
       
  1840 {
       
  1841     // There are three special cases we need to consider.
       
  1842     // (1) Inline Flows.  For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
       
  1843     // inline.  In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the root
       
  1844     // line boxes of all three lines (including overflow on those lines).
       
  1845     // (2) Left/Top Overflow.  The width/height of layers already includes right/bottom overflow.  However, in the case of left/top
       
  1846     // overflow, we have to create a bounding box that will extend to include this overflow.
       
  1847     // (3) Floats.  When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats
       
  1848     // as part of our bounding box.  We do this because we are the responsible layer for both hit testing and painting those
       
  1849     // floats.
       
  1850     IntRect result;
       
  1851     if (renderer()->isInlineFlow()) {
       
  1852         // Go from our first line box to our last line box.
       
  1853         RenderInline* inlineFlow = static_cast<RenderInline*>(renderer());
       
  1854         InlineFlowBox* firstBox = inlineFlow->firstLineBox();
       
  1855         if (!firstBox)
       
  1856             return result;
       
  1857         int top = firstBox->root()->topOverflow();
       
  1858         int bottom = inlineFlow->lastLineBox()->root()->bottomOverflow();
       
  1859         int left = firstBox->xPos();
       
  1860         for (InlineRunBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
       
  1861             left = min(left, curr->xPos());
       
  1862         result = IntRect(m_x + left, m_y + (top - renderer()->yPos()), width(), bottom - top);
       
  1863     } else if (renderer()->isTableRow()) {
       
  1864         // Our bounding box is just the union of all of our cells' border/overflow rects.
       
  1865         for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
       
  1866             if (child->isTableCell()) {
       
  1867                 IntRect bbox = child->borderBox();
       
  1868                 bbox.move(0, child->borderTopExtra());
       
  1869                 result.unite(bbox);
       
  1870                 IntRect overflowRect = renderer()->overflowRect(false);
       
  1871                 overflowRect.move(0, child->borderTopExtra());
       
  1872                 if (bbox != overflowRect)
       
  1873                     result.unite(overflowRect);
       
  1874             }
       
  1875         }
       
  1876         result.move(m_x, m_y);
       
  1877     } else {
       
  1878         IntRect bbox = renderer()->borderBox();
       
  1879         result = bbox;
       
  1880         IntRect overflowRect = renderer()->overflowRect(false);
       
  1881         if (bbox != overflowRect)
       
  1882             result.unite(overflowRect);
       
  1883         
       
  1884         // We have to adjust the x/y of this result so that it is in the coordinate space of the layer.
       
  1885         // We also have to add in borderTopExtra here, since borderBox(), in order to play well with methods like
       
  1886         // floatRect that deal with child content, uses an origin of (0,0) that is at the child content box (so
       
  1887         // border box returns a y coord of -borderTopExtra().  The layer, however, uses the outer box.  This is all
       
  1888         // really confusing.
       
  1889         result.move(m_x, m_y + renderer()->borderTopExtra());
       
  1890     }
       
  1891     
       
  1892     // Convert the bounding box to an absolute position.  We can do this easily by looking at the delta
       
  1893     // between the bounding box's xpos and our layer's xpos and then applying that to the absolute layerBounds
       
  1894     // passed in.
       
  1895     int absX = 0, absY = 0;
       
  1896     convertToLayerCoords(root(), absX, absY);
       
  1897     result.move(absX - m_x, absY - m_y);
       
  1898     RenderView* view = renderer()->view();
       
  1899     ASSERT(view);
       
  1900     if (view)
       
  1901         result.inflate(view->maximalOutlineSize());
       
  1902     return result;
       
  1903 }
       
  1904 
       
  1905 void RenderLayer::clearClipRects()
       
  1906 {
       
  1907     if (!m_clipRects)
       
  1908         return;
       
  1909 
       
  1910     clearClipRect();
       
  1911     
       
  1912     for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
       
  1913         l->clearClipRects();
       
  1914 }
       
  1915 
       
  1916 void RenderLayer::clearClipRect()
       
  1917 {
       
  1918     if (m_clipRects) {
       
  1919         m_clipRects->deref(m_object->renderArena());
       
  1920         m_clipRects = 0;
       
  1921     }
       
  1922 }
       
  1923 
       
  1924 static RenderObject* commonAncestor(RenderObject* obj1, RenderObject* obj2)
       
  1925 {
       
  1926     if (!obj1 || !obj2)
       
  1927         return 0;
       
  1928 
       
  1929     for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor())
       
  1930         for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor())
       
  1931             if (currObj1 == currObj2)
       
  1932                 return currObj1;
       
  1933 
       
  1934     return 0;
       
  1935 }
       
  1936 
       
  1937 void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestResult& result)
       
  1938 {
       
  1939     // We don't update :hover/:active state when the result is marked as readonly.
       
  1940     if (request.readonly)
       
  1941         return;
       
  1942 
       
  1943     Document* doc = renderer()->document();
       
  1944 
       
  1945     Node* activeNode = doc->activeNode();
       
  1946     if (activeNode && !request.active) {
       
  1947         // We are clearing the :active chain because the mouse has been released.
       
  1948         for (RenderObject* curr = activeNode->renderer(); curr; curr = curr->parent()) {
       
  1949             if (curr->element() && !curr->isText())
       
  1950                 curr->element()->setInActiveChain(false);
       
  1951         }
       
  1952         doc->setActiveNode(0);
       
  1953     } else {
       
  1954         Node* newActiveNode = result.innerNode();
       
  1955         if (!activeNode && newActiveNode && request.active) {
       
  1956             // We are setting the :active chain and freezing it. If future moves happen, they
       
  1957             // will need to reference this chain.
       
  1958             for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
       
  1959                 if (curr->element() && !curr->isText()) {
       
  1960                     curr->element()->setInActiveChain(true);
       
  1961                 }
       
  1962             }
       
  1963             doc->setActiveNode(newActiveNode);
       
  1964         }
       
  1965     }
       
  1966 
       
  1967     // If the mouse is down and if this is a mouse move event, we want to restrict changes in 
       
  1968     // :hover/:active to only apply to elements that are in the :active chain that we froze
       
  1969     // at the time the mouse went down.
       
  1970     bool mustBeInActiveChain = request.active && request.mouseMove;
       
  1971 
       
  1972     // Check to see if the hovered node has changed.  If not, then we don't need to
       
  1973     // do anything.  
       
  1974     RefPtr<Node> oldHoverNode = doc->hoverNode();
       
  1975     Node* newHoverNode = result.innerNode();
       
  1976 
       
  1977     // Update our current hover node.
       
  1978     doc->setHoverNode(newHoverNode);
       
  1979 
       
  1980     // We have two different objects.  Fetch their renderers.
       
  1981     RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0;
       
  1982     RenderObject* newHoverObj = newHoverNode ? newHoverNode->renderer() : 0;
       
  1983     
       
  1984     // Locate the common ancestor render object for the two renderers.
       
  1985     RenderObject* ancestor = commonAncestor(oldHoverObj, newHoverObj);
       
  1986 
       
  1987     if (oldHoverObj != newHoverObj) {
       
  1988         // The old hover path only needs to be cleared up to (and not including) the common ancestor;
       
  1989         for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
       
  1990             if (curr->element() && !curr->isText() && (!mustBeInActiveChain || curr->element()->inActiveChain())) {
       
  1991                 curr->element()->setActive(false);
       
  1992                 curr->element()->setHovered(false);
       
  1993             }
       
  1994         }
       
  1995     }
       
  1996 
       
  1997     // Now set the hover state for our new object up to the root.
       
  1998     for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
       
  1999         if (curr->element() && !curr->isText() && (!mustBeInActiveChain || curr->element()->inActiveChain())) {
       
  2000             curr->element()->setActive(request.active);
       
  2001             curr->element()->setHovered(true);
       
  2002         }
       
  2003     }
       
  2004 }
       
  2005 
       
  2006 // Helper for the sorting of layers by z-index.
       
  2007 static inline bool compareZIndex(RenderLayer* first, RenderLayer* second)
       
  2008 {
       
  2009     return first->zIndex() < second->zIndex();
       
  2010 }
       
  2011 
       
  2012 void RenderLayer::dirtyZOrderLists()
       
  2013 {
       
  2014     if (m_posZOrderList)
       
  2015         m_posZOrderList->clear();
       
  2016     if (m_negZOrderList)
       
  2017         m_negZOrderList->clear();
       
  2018     m_zOrderListsDirty = true;
       
  2019 }
       
  2020 
       
  2021 void RenderLayer::dirtyOverflowList()
       
  2022 {
       
  2023     if (m_overflowList)
       
  2024         m_overflowList->clear();
       
  2025     m_overflowListDirty = true;
       
  2026 }
       
  2027 
       
  2028 void RenderLayer::updateZOrderLists()
       
  2029 {
       
  2030     if (!isStackingContext() || !m_zOrderListsDirty)
       
  2031         return;
       
  2032         
       
  2033     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
       
  2034         child->collectLayers(m_posZOrderList, m_negZOrderList);
       
  2035 
       
  2036     // Sort the two lists.
       
  2037     if (m_posZOrderList)
       
  2038         std::stable_sort(m_posZOrderList->begin(), m_posZOrderList->end(), compareZIndex);
       
  2039     if (m_negZOrderList)
       
  2040         std::stable_sort(m_negZOrderList->begin(), m_negZOrderList->end(), compareZIndex);
       
  2041 
       
  2042     m_zOrderListsDirty = false;
       
  2043 }
       
  2044 
       
  2045 void RenderLayer::updateOverflowList()
       
  2046 {
       
  2047     if (!m_overflowListDirty)
       
  2048         return;
       
  2049         
       
  2050     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
       
  2051         if (child->isOverflowOnly()) {
       
  2052             if (!m_overflowList)
       
  2053                 m_overflowList = new Vector<RenderLayer*>;
       
  2054             m_overflowList->append(child);
       
  2055         }
       
  2056     }
       
  2057     
       
  2058     m_overflowListDirty = false;
       
  2059 }
       
  2060 
       
  2061 void RenderLayer::collectLayers(Vector<RenderLayer*>*& posBuffer, Vector<RenderLayer*>*& negBuffer)
       
  2062 {
       
  2063     updateVisibilityStatus();
       
  2064         
       
  2065     // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
       
  2066     if (m_hasVisibleContent && !isOverflowOnly()) {
       
  2067         // Determine which buffer the child should be in.
       
  2068         Vector<RenderLayer*>*& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
       
  2069 
       
  2070         // Create the buffer if it doesn't exist yet.
       
  2071         if (!buffer)
       
  2072             buffer = new Vector<RenderLayer*>;
       
  2073         
       
  2074         // Append ourselves at the end of the appropriate buffer.
       
  2075         buffer->append(this);
       
  2076     }
       
  2077 
       
  2078     // Recur into our children to collect more layers, but only if we don't establish
       
  2079     // a stacking context.
       
  2080     if (m_hasVisibleDescendant && !isStackingContext())
       
  2081         for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
       
  2082             child->collectLayers(posBuffer, negBuffer);
       
  2083 }
       
  2084 
       
  2085 void RenderLayer::repaintIncludingDescendants()
       
  2086 {
       
  2087     m_object->repaint();
       
  2088     for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
       
  2089         curr->repaintIncludingDescendants();
       
  2090 }
       
  2091 
       
  2092 bool RenderLayer::shouldBeOverflowOnly() const
       
  2093 {
       
  2094     return renderer()->hasOverflowClip() && 
       
  2095            !renderer()->isPositioned() &&
       
  2096            !renderer()->isRelPositioned() &&
       
  2097            !isTransparent();
       
  2098 }
       
  2099 
       
  2100 void RenderLayer::styleChanged()
       
  2101 {
       
  2102     bool isOverflowOnly = shouldBeOverflowOnly();
       
  2103     if (isOverflowOnly != m_isOverflowOnly) {
       
  2104         m_isOverflowOnly = isOverflowOnly;
       
  2105         RenderLayer* p = parent();
       
  2106         RenderLayer* sc = stackingContext();
       
  2107         if (p)
       
  2108             p->dirtyOverflowList();
       
  2109         if (sc)
       
  2110             sc->dirtyZOrderLists();
       
  2111     }
       
  2112 
       
  2113     if (m_object->style()->overflowX() == OMARQUEE && m_object->style()->marqueeBehavior() != MNONE) {
       
  2114         if (!m_marquee)
       
  2115             m_marquee = new Marquee(this);
       
  2116         m_marquee->updateMarqueeStyle();
       
  2117     }
       
  2118     else if (m_marquee) {
       
  2119         delete m_marquee;
       
  2120         m_marquee = 0;
       
  2121     }
       
  2122 }
       
  2123 
       
  2124 void RenderLayer::suspendMarquees()
       
  2125 {
       
  2126     if (m_marquee)
       
  2127         m_marquee->suspend();
       
  2128     
       
  2129     for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
       
  2130         curr->suspendMarquees();
       
  2131 }
       
  2132 
       
  2133 // --------------------------------------------------------------------------
       
  2134 // Marquee implementation
       
  2135 
       
  2136 Marquee::Marquee(RenderLayer* l)
       
  2137     : m_layer(l), m_currentLoop(0)
       
  2138     , m_totalLoops(0)
       
  2139     , m_timer(this, &Marquee::timerFired)
       
  2140     , m_start(0), m_end(0), m_speed(0), m_reset(false)
       
  2141     , m_suspended(false), m_stopped(false), m_direction(MAUTO)
       
  2142 {
       
  2143 }
       
  2144 
       
  2145 int Marquee::marqueeSpeed() const
       
  2146 {
       
  2147     int result = m_layer->renderer()->style()->marqueeSpeed();
       
  2148     Node* elt = m_layer->renderer()->element();
       
  2149     if (elt && elt->hasTagName(marqueeTag)) {
       
  2150         HTMLMarqueeElement* marqueeElt = static_cast<HTMLMarqueeElement*>(elt);
       
  2151         result = max(result, marqueeElt->minimumDelay());
       
  2152     }
       
  2153     return result;
       
  2154 }
       
  2155 
       
  2156 EMarqueeDirection Marquee::direction() const
       
  2157 {
       
  2158     // FIXME: Support the CSS3 "auto" value for determining the direction of the marquee.
       
  2159     // For now just map MAUTO to MBACKWARD
       
  2160     EMarqueeDirection result = m_layer->renderer()->style()->marqueeDirection();
       
  2161     TextDirection dir = m_layer->renderer()->style()->direction();
       
  2162     if (result == MAUTO)
       
  2163         result = MBACKWARD;
       
  2164     if (result == MFORWARD)
       
  2165         result = (dir == LTR) ? MRIGHT : MLEFT;
       
  2166     if (result == MBACKWARD)
       
  2167         result = (dir == LTR) ? MLEFT : MRIGHT;
       
  2168     
       
  2169     // Now we have the real direction.  Next we check to see if the increment is negative.
       
  2170     // If so, then we reverse the direction.
       
  2171     Length increment = m_layer->renderer()->style()->marqueeIncrement();
       
  2172     if (increment.isNegative())
       
  2173         result = static_cast<EMarqueeDirection>(-result);
       
  2174     
       
  2175     return result;
       
  2176 }
       
  2177 
       
  2178 bool Marquee::isHorizontal() const
       
  2179 {
       
  2180     return direction() == MLEFT || direction() == MRIGHT;
       
  2181 }
       
  2182 
       
  2183 int Marquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge)
       
  2184 {
       
  2185     RenderObject* o = m_layer->renderer();
       
  2186     RenderStyle* s = o->style();
       
  2187     if (isHorizontal()) {
       
  2188         bool ltr = s->direction() == LTR;
       
  2189         int clientWidth = o->clientWidth();
       
  2190         int contentWidth = ltr ? o->rightmostPosition(true, false) : o->leftmostPosition(true, false);
       
  2191         if (ltr)
       
  2192             contentWidth += (o->paddingRight() - o->borderLeft());
       
  2193         else {
       
  2194             contentWidth = o->width() - contentWidth;
       
  2195             contentWidth += (o->paddingLeft() - o->borderRight());
       
  2196         }
       
  2197         if (dir == MRIGHT) {
       
  2198             if (stopAtContentEdge)
       
  2199                 return max(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));
       
  2200             else
       
  2201                 return ltr ? contentWidth : clientWidth;
       
  2202         }
       
  2203         else {
       
  2204             if (stopAtContentEdge)
       
  2205                 return min(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));
       
  2206             else
       
  2207                 return ltr ? -clientWidth : -contentWidth;
       
  2208         }
       
  2209     }
       
  2210     else {
       
  2211         int contentHeight = m_layer->renderer()->lowestPosition(true, false) - 
       
  2212                             m_layer->renderer()->borderTop() + m_layer->renderer()->paddingBottom();
       
  2213         int clientHeight = m_layer->renderer()->clientHeight();
       
  2214         if (dir == MUP) {
       
  2215             if (stopAtContentEdge)
       
  2216                  return min(contentHeight - clientHeight, 0);
       
  2217             else
       
  2218                 return -clientHeight;
       
  2219         }
       
  2220         else {
       
  2221             if (stopAtContentEdge)
       
  2222                 return max(contentHeight - clientHeight, 0);
       
  2223             else 
       
  2224                 return contentHeight;
       
  2225         }
       
  2226     }    
       
  2227 }
       
  2228 
       
  2229 void Marquee::start()
       
  2230 {
       
  2231     if (m_timer.isActive() || m_layer->renderer()->style()->marqueeIncrement().isZero())
       
  2232         return;
       
  2233 
       
  2234     // We may end up propagating a scroll event. It is important that we suspend events until 
       
  2235     // the end of the function since they could delete the layer, including the marquee.
       
  2236     FrameView* frameView = m_layer->renderer()->document()->view();
       
  2237     if (frameView)
       
  2238         frameView->pauseScheduledEvents();
       
  2239 
       
  2240     if (!m_suspended && !m_stopped) {
       
  2241         if (isHorizontal())
       
  2242             m_layer->scrollToOffset(m_start, 0, false, false);
       
  2243         else
       
  2244             m_layer->scrollToOffset(0, m_start, false, false);
       
  2245     }
       
  2246     else {
       
  2247         m_suspended = false;
       
  2248         m_stopped = false;
       
  2249     }
       
  2250 
       
  2251     m_timer.startRepeating(speed() * 0.001);
       
  2252 
       
  2253     if (frameView)
       
  2254         frameView->resumeScheduledEvents();
       
  2255 }
       
  2256 
       
  2257 void Marquee::suspend()
       
  2258 {
       
  2259     m_timer.stop();
       
  2260     m_suspended = true;
       
  2261 }
       
  2262 
       
  2263 void Marquee::stop()
       
  2264 {
       
  2265     m_timer.stop();
       
  2266     m_stopped = true;
       
  2267 }
       
  2268 
       
  2269 void Marquee::updateMarqueePosition()
       
  2270 {
       
  2271     bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops);
       
  2272     
       
  2273 #if PLATFORM(SYMBIAN)
       
  2274     // wap-marquee requests loop 0 as inactive marquee
       
  2275     if (m_totalLoops == 0 && m_layer->renderer()->style()->display() == WAP_MARQUEE)
       
  2276         activate = false;
       
  2277 #endif
       
  2278 
       
  2279     if (activate) {
       
  2280         EMarqueeBehavior behavior = m_layer->renderer()->style()->marqueeBehavior();
       
  2281         m_start = computePosition(direction(), behavior == MALTERNATE);
       
  2282         m_end = computePosition(reverseDirection(), behavior == MALTERNATE || behavior == MSLIDE);
       
  2283         if (!m_stopped)
       
  2284             start();
       
  2285     }
       
  2286 }
       
  2287 
       
  2288 void Marquee::updateMarqueeStyle()
       
  2289 {
       
  2290     RenderStyle* s = m_layer->renderer()->style();
       
  2291     
       
  2292     if (m_direction != s->marqueeDirection() || (m_totalLoops != s->marqueeLoopCount() && m_currentLoop >= m_totalLoops))
       
  2293         m_currentLoop = 0; // When direction changes or our loopCount is a smaller number than our current loop, reset our loop.
       
  2294     
       
  2295     m_totalLoops = s->marqueeLoopCount();
       
  2296     m_direction = s->marqueeDirection();
       
  2297     
       
  2298     if (m_layer->renderer()->isHTMLMarquee()) {
       
  2299         // Hack for WinIE.  In WinIE, a value of 0 or lower for the loop count for SLIDE means to only do
       
  2300         // one loop.
       
  2301         if (m_totalLoops <= 0 && s->marqueeBehavior() == MSLIDE)
       
  2302             m_totalLoops = 1;
       
  2303         
       
  2304         // Hack alert: Set the white-space value to nowrap for horizontal marquees with inline children, thus ensuring
       
  2305         // all the text ends up on one line by default.  Limit this hack to the <marquee> element to emulate
       
  2306         // WinIE's behavior.  Someone using CSS3 can use white-space: nowrap on their own to get this effect.
       
  2307         // Second hack alert: Set the text-align back to auto.  WinIE completely ignores text-align on the
       
  2308         // marquee element.
       
  2309         // FIXME: Bring these up with the CSS WG.
       
  2310         if (isHorizontal() && m_layer->renderer()->childrenInline()) {
       
  2311             s->setWhiteSpace(NOWRAP);
       
  2312             s->setTextAlign(TAAUTO);
       
  2313         }
       
  2314     }
       
  2315     
       
  2316     // Marquee height hack!! Make sure that, if it is a horizontal marquee, the height attribute is overridden 
       
  2317     // if it is smaller than the font size. If it is a vertical marquee and height is not specified, we default
       
  2318     // to a marquee of 200px.
       
  2319     if (isHorizontal()) {
       
  2320         if (s->height().isFixed() && s->height().value() < s->fontSize())
       
  2321             s->setHeight(Length(s->fontSize(),Fixed));
       
  2322     } else if (s->height().isAuto())  //vertical marquee with no specified height
       
  2323         s->setHeight(Length(200, Fixed)); 
       
  2324    
       
  2325     if (speed() != marqueeSpeed()) {
       
  2326         m_speed = marqueeSpeed();
       
  2327         if (m_timer.isActive())
       
  2328             m_timer.startRepeating(speed() * 0.001);
       
  2329     }
       
  2330     
       
  2331     // Check the loop count to see if we should now stop.
       
  2332     bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops);
       
  2333     if (activate && !m_timer.isActive())
       
  2334         m_layer->renderer()->setNeedsLayout(true);
       
  2335     else if (!activate && m_timer.isActive())
       
  2336         m_timer.stop();
       
  2337 }
       
  2338 
       
  2339 void Marquee::timerFired(Timer<Marquee>*)
       
  2340 {
       
  2341     if (m_layer->renderer()->needsLayout())
       
  2342         return;
       
  2343     
       
  2344     if (m_reset) {
       
  2345         m_reset = false;
       
  2346         if (isHorizontal())
       
  2347             m_layer->scrollToXOffset(m_start);
       
  2348         else
       
  2349             m_layer->scrollToYOffset(m_start);
       
  2350         return;
       
  2351     }
       
  2352     
       
  2353     RenderStyle* s = m_layer->renderer()->style();
       
  2354     
       
  2355     int endPoint = m_end;
       
  2356     int range = m_end - m_start;
       
  2357     int newPos;
       
  2358     if (range == 0)
       
  2359         newPos = m_end;
       
  2360     else {  
       
  2361         bool addIncrement = direction() == MUP || direction() == MLEFT;
       
  2362         bool isReversed = s->marqueeBehavior() == MALTERNATE && m_currentLoop % 2;
       
  2363         if (isReversed) {
       
  2364             // We're going in the reverse direction.
       
  2365             endPoint = m_start;
       
  2366             range = -range;
       
  2367             addIncrement = !addIncrement;
       
  2368         }
       
  2369         bool positive = range > 0;
       
  2370         int clientSize = (isHorizontal() ? m_layer->renderer()->clientWidth() : m_layer->renderer()->clientHeight());
       
  2371         int increment = max(1, abs(m_layer->renderer()->style()->marqueeIncrement().calcValue(clientSize)));
       
  2372         int currentPos = (isHorizontal() ? m_layer->scrollXOffset() : m_layer->scrollYOffset());
       
  2373         newPos =  currentPos + (addIncrement ? increment : -increment);
       
  2374         if (positive)
       
  2375             newPos = min(newPos, endPoint);
       
  2376         else
       
  2377             newPos = max(newPos, endPoint);
       
  2378     }
       
  2379 
       
  2380     if (newPos == endPoint) {
       
  2381         m_currentLoop++;
       
  2382         if (m_totalLoops > 0 && m_currentLoop >= m_totalLoops)
       
  2383             m_timer.stop();
       
  2384         else if (s->marqueeBehavior() != MALTERNATE)
       
  2385             m_reset = true;
       
  2386     }
       
  2387     
       
  2388     if (isHorizontal())
       
  2389         m_layer->scrollToXOffset(newPos);
       
  2390     else
       
  2391         m_layer->scrollToYOffset(newPos);
       
  2392 /* HLUU-7D3SDH: This special handling here is not compatible with 3.2 and 3.1 behavior. 
       
  2393 #if PLATFORM(SYMBIAN)
       
  2394     if( m_totalLoops>0 && m_currentLoop >= m_totalLoops ) {
       
  2395         // -wap-marquee requires "the element MUST be rendered as if the 'display' property was set
       
  2396         // to block" after looping
       
  2397         if(s->display() == WAP_MARQUEE) {
       
  2398             s->setDisplay(BLOCK);
       
  2399             s->setOverflowX(OVISIBLE);
       
  2400             m_layer->renderer()->setHasOverflowClip( false );
       
  2401             m_layer->styleChanged();
       
  2402         }
       
  2403     }
       
  2404 #endif
       
  2405 */
       
  2406 }
       
  2407 
       
  2408 } // namespace WebCore