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
107using namespace std;
108
109namespace WebCore {
110
111using namespace HTMLNames;
112
113const int MinimumWidthWhileResizing = 100;
114const int MinimumHeightWhileResizing = 40;
115
116void* ClipRects::operator new(size_t sz, RenderArena* renderArena) throw()
117{
118    return renderArena->allocate(sz);
119}
120
121void ClipRects::operator delete(void* ptr, size_t sz)
122{
123    // Stash size where destroy can find it.
124    *(size_t *)ptr = sz;
125}
126
127void 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
135RenderLayer::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
211RenderLayer::~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)
249RenderLayerCompositor* RenderLayer::compositor() const
250{
251    ASSERT(renderer()->view());
252    return renderer()->view()->compositor();
253}
254
255void 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
266bool RenderLayer::hasAcceleratedCompositing() const
267{
268#if USE(ACCELERATED_COMPOSITING)
269    return compositor()->hasAcceleratedCompositing();
270#else
271    return false;
272#endif
273}
274
275bool RenderLayer::canRender3DTransforms() const
276{
277#if USE(ACCELERATED_COMPOSITING)
278    return compositor()->canRender3DTransforms();
279#else
280    return false;
281#endif
282}
283
284void 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
398IntRect 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
406void RenderLayer::computeRepaintRects()
407{
408    RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
409    m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
410    m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer);
411}
412
413void 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
429void 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
456TransformationMatrix 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
474TransformationMatrix 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
488static 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
510void 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
534void 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
556void RenderLayer::dirtyVisibleContentStatus()
557{
558    m_visibleContentStatusDirty = true;
559    if (parent())
560        parent()->dirtyVisibleDescendantStatus();
561}
562
563void 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
577void 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
586void 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
631void 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.
646bool 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
675void 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
750TransformationMatrix 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
780FloatPoint 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
792RenderLayer* 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
809static inline bool isPositionedContainer(RenderLayer* layer)
810{
811    RenderObject* o = layer->renderer();
812    return o->isRenderView() || o->isPositioned() || o->isRelPositioned() || layer->hasTransform();
813}
814
815static inline bool isFixedPositionedContainer(RenderLayer* layer)
816{
817    RenderObject* o = layer->renderer();
818    return o->isRenderView() || layer->hasTransform();
819}
820
821RenderLayer* RenderLayer::enclosingPositionedAncestor() const
822{
823    RenderLayer* curr = parent();
824    while (curr && !isPositionedContainer(curr))
825        curr = curr->parent();
826
827    return curr;
828}
829
830RenderLayer* 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
839static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
840{
841    return layer->isNormalFlowOnly() ? layer->parent() : layer->stackingContext();
842}
843
844#if USE(ACCELERATED_COMPOSITING)
845RenderLayer* 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
859RenderLayer* 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
885IntPoint 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
891bool RenderLayer::requiresSlowRepaints() const
892{
893    if (isTransparent() || hasReflection() || hasTransform())
894        return true;
895    if (!parent())
896        return false;
897    return parent()->requiresSlowRepaints();
898}
899
900bool 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
909RenderLayer* 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
923static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* rootLayer, PaintBehavior paintBehavior);
924
925static 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
952static 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
979void 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
1001void* RenderLayer::operator new(size_t sz, RenderArena* renderArena) throw()
1002{
1003    return renderArena->allocate(sz);
1004}
1005
1006void RenderLayer::operator delete(void* ptr, size_t sz)
1007{
1008    // Stash size where destroy can find it.
1009    *(size_t *)ptr = sz;
1010}
1011
1012void 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
1020void 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
1058RenderLayer* 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
1096void 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
1134void 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
1153void
1154RenderLayer::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
1250static 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
1264void 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
1290void 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
1330void RenderLayer::scrollToOffset(int x, int y)
1331{
1332    ScrollableArea::scrollToOffsetWithoutAnimation(IntPoint(x, y));
1333}
1334
1335void 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
1458void 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
1545IntRect 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
1618void 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
1636void 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
1701int 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
1707void RenderLayer::setScrollOffset(const IntPoint& offset)
1708{
1709    scrollTo(offset.x(), offset.y());
1710}
1711
1712int 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
1721bool RenderLayer::isActive() const
1722{
1723    Page* page = renderer()->frame()->page();
1724    return page && page->focusController()->isActive();
1725}
1726
1727static 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
1751IntRect 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
1765static 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
1773IntRect 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
1784bool RenderLayer::isScrollCornerVisible() const
1785{
1786    ASSERT(renderer()->isBox());
1787    return !scrollCornerRect().isEmpty();
1788}
1789
1790IntRect 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
1802IntRect 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
1813IntPoint 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
1824IntPoint 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
1836IntSize RenderLayer::contentsSize() const
1837{
1838    return IntSize(const_cast<RenderLayer*>(this)->scrollWidth(), const_cast<RenderLayer*>(this)->scrollHeight());
1839}
1840
1841int RenderLayer::visibleHeight() const
1842{
1843    return m_height;
1844}
1845
1846int RenderLayer::visibleWidth() const
1847{
1848    return m_width;
1849}
1850
1851bool RenderLayer::shouldSuspendScrollAnimations() const
1852{
1853    RenderView* view = renderer()->view();
1854    if (!view)
1855        return true;
1856    return view->frameView()->shouldSuspendScrollAnimations();
1857}
1858
1859IntPoint RenderLayer::currentMousePosition() const
1860{
1861    return renderer()->frame() ? renderer()->frame()->eventHandler()->currentMousePosition() : IntPoint();
1862}
1863
1864IntSize 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
1878void 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
1903void 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
1917PassRefPtr<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
1935void 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
1954void 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
1977void 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
2000int 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
2007int 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
2014IntSize 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
2022bool RenderLayer::hasOverflowControls() const
2023{
2024    return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
2025}
2026#if ENABLE(ANDROID_OVERFLOW_SCROLL)
2027bool 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
2036void 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.
2093void RenderLayer::setWidth(int w)
2094{
2095    if (m_width != w) {
2096        m_scrollDimensionsDirty = true;
2097        m_width = w;
2098    }
2099}
2100
2101void RenderLayer::setHeight(int h)
2102{
2103    if (m_height != h) {
2104        m_scrollDimensionsDirty = true;
2105        m_height = h;
2106    }
2107}
2108#endif
2109
2110int RenderLayer::scrollWidth()
2111{
2112    if (m_scrollDimensionsDirty)
2113        computeScrollDimensions();
2114    return m_scrollWidth;
2115}
2116
2117int RenderLayer::scrollHeight()
2118{
2119    if (m_scrollDimensionsDirty)
2120        computeScrollDimensions();
2121    return m_scrollHeight;
2122}
2123
2124int RenderLayer::overflowTop() const
2125{
2126    RenderBox* box = renderBox();
2127    IntRect overflowRect(box->layoutOverflowRect());
2128    box->flipForWritingMode(overflowRect);
2129    return overflowRect.y();
2130}
2131
2132int RenderLayer::overflowBottom() const
2133{
2134    RenderBox* box = renderBox();
2135    IntRect overflowRect(box->layoutOverflowRect());
2136    box->flipForWritingMode(overflowRect);
2137    return overflowRect.maxY();
2138}
2139
2140int RenderLayer::overflowLeft() const
2141{
2142    RenderBox* box = renderBox();
2143    IntRect overflowRect(box->layoutOverflowRect());
2144    box->flipForWritingMode(overflowRect);
2145    return overflowRect.x();
2146}
2147
2148int RenderLayer::overflowRight() const
2149{
2150    RenderBox* box = renderBox();
2151    IntRect overflowRect(box->layoutOverflowRect());
2152    box->flipForWritingMode(overflowRect);
2153    return overflowRect.maxX();
2154}
2155
2156void 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
2177void 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
2200void 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
2326void 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
2385void 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
2411void 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
2454bool 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
2468bool 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
2511bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
2512{
2513    return ScrollableArea::scroll(direction, granularity, multiplier);
2514}
2515
2516void 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
2525void 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
2534static 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
2542static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
2543{
2544    if (paintDirtyRect == clipRect)
2545        return;
2546    p->restore();
2547}
2548
2549static 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)
2566static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection)
2567{
2568    return paintingReflection && !layer->has3DTransform();
2569}
2570#endif
2571
2572void 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
2773void 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
2790void 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
2810void 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
2894static 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
2903bool 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
2935Node* 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.
2948static 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
2962PassRefPtr<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
2993static 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.
3025RenderLayer* 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
3204bool 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
3231RenderLayer* 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
3269RenderLayer* 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
3286RenderLayer* 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
3372void 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
3398void 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
3468void 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
3480IntRect 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
3497void 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
3559IntRect 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
3568IntRect 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
3577void RenderLayer::addBlockSelectionGapsBounds(const IntRect& bounds)
3578{
3579    m_blockSelectionGapsBounds.unite(bounds);
3580}
3581
3582void RenderLayer::clearBlockSelectionGapsBounds()
3583{
3584    m_blockSelectionGapsBounds = IntRect();
3585    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
3586        child->clearBlockSelectionGapsBounds();
3587}
3588
3589void 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
3607bool 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
3631IntRect 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
3678IntRect 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
3691IntRect RenderLayer::absoluteBoundingBox() const
3692{
3693    return boundingBox(root());
3694}
3695
3696void 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
3707void 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)
3719RenderLayerBacking* RenderLayer::ensureBacking()
3720{
3721    if (!m_backing)
3722        m_backing.set(new RenderLayerBacking(this));
3723    return m_backing.get();
3724}
3725
3726void RenderLayer::clearBacking()
3727{
3728    m_backing.clear();
3729}
3730
3731bool RenderLayer::hasCompositedMask() const
3732{
3733    return m_backing && m_backing->hasMaskLayer();
3734}
3735
3736GraphicsLayer* RenderLayer::layerForHorizontalScrollbar() const
3737{
3738    return m_backing ? m_backing->layerForHorizontalScrollbar() : 0;
3739}
3740
3741GraphicsLayer* RenderLayer::layerForVerticalScrollbar() const
3742{
3743    return m_backing ? m_backing->layerForVerticalScrollbar() : 0;
3744}
3745
3746GraphicsLayer* RenderLayer::layerForScrollCorner() const
3747{
3748    return m_backing ? m_backing->layerForScrollCorner() : 0;
3749}
3750#endif
3751
3752bool 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
3762void 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
3780static 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
3793void 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.
3874static inline bool compareZIndex(RenderLayer* first, RenderLayer* second)
3875{
3876    return first->zIndex() < second->zIndex();
3877}
3878
3879void 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
3893void RenderLayer::dirtyStackingContextZOrderLists()
3894{
3895    RenderLayer* sc = stackingContext();
3896    if (sc)
3897        sc->dirtyZOrderLists();
3898}
3899
3900void 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
3912void 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
3931void 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
3948void 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
3976void RenderLayer::updateLayerListsIfNeeded()
3977{
3978    updateZOrderLists();
3979    updateNormalFlowList();
3980}
3981
3982void 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
3994void 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)
4002void 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
4015void 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.
4035void 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
4046bool 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
4062bool 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
4078void 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
4135void 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
4151void 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
4167RenderLayer* RenderLayer::reflectionLayer() const
4168{
4169    return m_reflection ? m_reflection->layer() : 0;
4170}
4171
4172void 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
4179void 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
4189void 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
4226void 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
4237void 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
4248void showLayerTree(const WebCore::RenderObject* renderer)
4249{
4250    if (!renderer)
4251        return;
4252    showLayerTree(renderer->enclosingLayer());
4253}
4254#endif
4255