• 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