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