Fix hover area for divs with css transforms
[WebKit-https.git] / Source / WebCore / rendering / RenderLayer.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 "AnimationController.h"
48 #include "ColumnInfo.h"
49 #include "CSSPropertyNames.h"
50 #include "Chrome.h"
51 #include "Document.h"
52 #include "DocumentEventQueue.h"
53 #include "Element.h"
54 #include "EventHandler.h"
55 #include "FeatureObserver.h"
56 #include "FloatConversion.h"
57 #include "FloatPoint3D.h"
58 #include "FloatRect.h"
59 #include "FlowThreadController.h"
60 #include "FocusController.h"
61 #include "Frame.h"
62 #include "FrameLoader.h"
63 #include "FrameLoaderClient.h"
64 #include "FrameSelection.h"
65 #include "FrameTree.h"
66 #include "FrameView.h"
67 #include "Gradient.h"
68 #include "GraphicsContext.h"
69 #include "HTMLFrameElement.h"
70 #include "HTMLFrameOwnerElement.h"
71 #include "HTMLNames.h"
72 #include "HistogramSupport.h"
73 #include "HitTestingTransformState.h"
74 #include "HitTestRequest.h"
75 #include "HitTestResult.h"
76 #include "InspectorInstrumentation.h"
77 #include "OverflowEvent.h"
78 #include "OverlapTestRequestClient.h"
79 #include "Page.h"
80 #include "PlatformMouseEvent.h"
81 #include "RenderFlowThread.h"
82 #include "RenderGeometryMap.h"
83 #include "RenderInline.h"
84 #include "RenderMarquee.h"
85 #include "RenderNamedFlowFragment.h"
86 #include "RenderNamedFlowThread.h"
87 #include "RenderRegion.h"
88 #include "RenderReplica.h"
89 #include "RenderSVGResourceClipper.h"
90 #include "RenderScrollbar.h"
91 #include "RenderScrollbarPart.h"
92 #include "RenderTableCell.h"
93 #include "RenderTableRow.h"
94 #include "RenderTheme.h"
95 #include "RenderTreeAsText.h"
96 #include "RenderView.h"
97 #include "ScaleTransformOperation.h"
98 #include "ScrollAnimator.h"
99 #include "Scrollbar.h"
100 #include "ScrollbarTheme.h"
101 #include "ScrollingCoordinator.h"
102 #include "Settings.h"
103 #include "ShadowRoot.h"
104 #include "SourceGraphic.h"
105 #include "StylePropertySet.h"
106 #include "StyleResolver.h"
107 #include "TextStream.h"
108 #include "TransformationMatrix.h"
109 #include "TranslateTransformOperation.h"
110 #include <wtf/StdLibExtras.h>
111 #include <wtf/text/CString.h>
112
113 #if ENABLE(CSS_FILTERS)
114 #include "FEColorMatrix.h"
115 #include "FEMerge.h"
116 #include "FilterEffectRenderer.h"
117 #include "RenderLayerFilterInfo.h"
118 #endif
119
120 #if USE(ACCELERATED_COMPOSITING)
121 #include "RenderLayerBacking.h"
122 #include "RenderLayerCompositor.h"
123 #endif
124
125 #if ENABLE(SVG)
126 #include "SVGNames.h"
127 #endif
128
129 #if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
130 #include "CustomFilterGlobalContext.h"
131 #include "CustomFilterOperation.h"
132 #include "CustomFilterValidatedProgram.h"
133 #include "ValidatedCustomFilterOperation.h"
134 #endif
135
136 #define MIN_INTERSECT_FOR_REVEAL 32
137
138 namespace WebCore {
139
140 using namespace HTMLNames;
141
142 bool ClipRect::intersects(const HitTestLocation& hitTestLocation) const
143 {
144     return hitTestLocation.intersects(m_rect);
145 }
146
147 void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering)
148 {
149 #if !ENABLE(3D_RENDERING)
150     UNUSED_PARAM(has3DRendering);
151     matrix.makeAffine();
152 #else
153     if (!has3DRendering)
154         matrix.makeAffine();
155 #endif
156 }
157
158 RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
159     : m_inResizeMode(false)
160     , m_scrollDimensionsDirty(true)
161     , m_normalFlowListDirty(true)
162     , m_hasSelfPaintingLayerDescendant(false)
163     , m_hasSelfPaintingLayerDescendantDirty(false)
164     , m_hasOutOfFlowPositionedDescendant(false)
165     , m_hasOutOfFlowPositionedDescendantDirty(true)
166     , m_needsCompositedScrolling(false)
167     , m_descendantsAreContiguousInStackingOrder(false)
168     , m_isRootLayer(rendererLayerModelObject.isRenderView())
169     , m_usedTransparency(false)
170     , m_paintingInsideReflection(false)
171     , m_inOverflowRelayout(false)
172     , m_repaintStatus(NeedsNormalRepaint)
173     , m_visibleContentStatusDirty(true)
174     , m_hasVisibleContent(false)
175     , m_visibleDescendantStatusDirty(false)
176     , m_hasVisibleDescendant(false)
177     , m_isPaginated(false)
178     , m_3DTransformedDescendantStatusDirty(true)
179     , m_has3DTransformedDescendant(false)
180 #if USE(ACCELERATED_COMPOSITING)
181     , m_hasCompositingDescendant(false)
182     , m_indirectCompositingReason(NoIndirectCompositingReason)
183     , m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
184 #endif
185     , m_containsDirtyOverlayScrollbars(false)
186     , m_updatingMarqueePosition(false)
187 #if !ASSERT_DISABLED
188     , m_layerListMutationAllowed(true)
189 #endif
190 #if ENABLE(CSS_FILTERS)
191     , m_hasFilterInfo(false)
192 #endif
193 #if ENABLE(CSS_COMPOSITING)
194     , m_blendMode(BlendModeNormal)
195 #endif
196     , m_renderer(rendererLayerModelObject)
197     , m_parent(0)
198     , m_previous(0)
199     , m_next(0)
200     , m_first(0)
201     , m_last(0)
202     , m_staticInlinePosition(0)
203     , m_staticBlockPosition(0)
204     , m_reflection(0)
205     , m_scrollCorner(0)
206     , m_resizer(0)
207     , m_enclosingPaginationLayer(0)
208 {
209     m_isNormalFlowOnly = shouldBeNormalFlowOnly();
210     m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
211
212     // Non-stacking containers should have empty z-order lists. As this is already the case,
213     // there is no need to dirty / recompute these lists.
214     m_zOrderListsDirty = isStackingContainer();
215
216     ScrollableArea::setConstrainsScrollingToContentEdge(false);
217
218     if (!renderer().firstChild()) {
219         m_visibleContentStatusDirty = false;
220         m_hasVisibleContent = renderer().style().visibility() == VISIBLE;
221     }
222
223     if (Element* element = renderer().element()) {
224         // We save and restore only the scrollOffset as the other scroll values are recalculated.
225         m_scrollOffset = element->savedLayerScrollOffset();
226         if (!m_scrollOffset.isZero())
227             scrollAnimator()->setCurrentPosition(FloatPoint(m_scrollOffset.width(), m_scrollOffset.height()));
228         element->setSavedLayerScrollOffset(IntSize());
229     }
230 }
231
232 RenderLayer::~RenderLayer()
233 {
234     if (inResizeMode() && !renderer().documentBeingDestroyed())
235         renderer().frame().eventHandler().resizeLayerDestroyed();
236
237     renderer().view().frameView().removeScrollableArea(this);
238
239     if (!renderer().documentBeingDestroyed()) {
240         if (Element* element = renderer().element())
241             element->setSavedLayerScrollOffset(m_scrollOffset);
242     }
243
244     destroyScrollbar(HorizontalScrollbar);
245     destroyScrollbar(VerticalScrollbar);
246
247     if (renderer().frame().page()) {
248         if (ScrollingCoordinator* scrollingCoordinator = renderer().frame().page()->scrollingCoordinator())
249             scrollingCoordinator->willDestroyScrollableArea(this);
250     }
251
252     if (m_reflection)
253         removeReflection();
254     
255 #if ENABLE(CSS_FILTERS)
256     FilterInfo::remove(*this);
257 #endif
258
259     // Child layers will be deleted by their corresponding render objects, so
260     // we don't need to delete them ourselves.
261
262 #if USE(ACCELERATED_COMPOSITING)
263     clearBacking(true);
264 #endif
265     
266     if (m_scrollCorner)
267         m_scrollCorner->destroy();
268     if (m_resizer)
269         m_resizer->destroy();
270 }
271
272 String RenderLayer::name() const
273 {
274     StringBuilder name;
275     name.append(renderer().renderName());
276
277     if (Element* element = renderer().element()) {
278         name.append(' ');
279         name.append(element->tagName());
280
281         if (element->hasID()) {
282             name.appendLiteral(" id=\'");
283             name.append(element->getIdAttribute());
284             name.append('\'');
285         }
286
287         if (element->hasClass()) {
288             name.appendLiteral(" class=\'");
289             for (size_t i = 0; i < element->classNames().size(); ++i) {
290                 if (i > 0)
291                     name.append(' ');
292                 name.append(element->classNames()[i]);
293             }
294             name.append('\'');
295         }
296     }
297
298     if (isReflection())
299         name.appendLiteral(" (reflection)");
300
301     return name.toString();
302 }
303
304 #if USE(ACCELERATED_COMPOSITING)
305
306 RenderLayerCompositor& RenderLayer::compositor() const
307 {
308     return renderer().view().compositor();
309 }
310
311 void RenderLayer::contentChanged(ContentChangeType changeType)
312 {
313     // This can get called when video becomes accelerated, so the layers may change.
314     if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged) && compositor().updateLayerCompositingState(*this))
315         compositor().setCompositingLayersNeedRebuild();
316
317     if (m_backing)
318         m_backing->contentChanged(changeType);
319 }
320
321 #endif // USE(ACCELERATED_COMPOSITING)
322
323 bool RenderLayer::canRender3DTransforms() const
324 {
325 #if USE(ACCELERATED_COMPOSITING)
326     return compositor().canRender3DTransforms();
327 #else
328     return false;
329 #endif
330 }
331
332 #if ENABLE(CSS_FILTERS)
333
334 bool RenderLayer::paintsWithFilters() const
335 {
336     // FIXME: Eventually there will be cases where we paint with filters even without accelerated compositing,
337     // and this whole function won't be inside the #if below.
338
339 #if USE(ACCELERATED_COMPOSITING)
340     if (!renderer().hasFilter())
341         return false;
342         
343     if (!isComposited())
344         return true;
345
346     if (!m_backing || !m_backing->canCompositeFilters())
347         return true;
348 #endif
349
350     return false;
351 }
352
353 bool RenderLayer::requiresFullLayerImageForFilters() const 
354 {
355     if (!paintsWithFilters())
356         return false;
357     FilterEffectRenderer* renderer = filterRenderer();
358     return renderer && renderer->hasFilterThatMovesPixels();
359 }
360
361 FilterEffectRenderer* RenderLayer::filterRenderer() const
362 {
363     FilterInfo* filterInfo = FilterInfo::getIfExists(*this);
364     return filterInfo ? filterInfo->renderer() : 0;
365 }
366
367 #endif
368
369 LayoutPoint RenderLayer::computeOffsetFromRoot(bool& hasLayerOffset) const
370 {
371     hasLayerOffset = true;
372
373     if (!parent())
374         return LayoutPoint();
375
376     // This is similar to root() but we check if an ancestor layer would
377     // prevent the optimization from working.
378     const RenderLayer* rootLayer = 0;
379     for (const RenderLayer* parentLayer = parent(); parentLayer; rootLayer = parentLayer, parentLayer = parentLayer->parent()) {
380         hasLayerOffset = parentLayer->canUseConvertToLayerCoords();
381         if (!hasLayerOffset)
382             return LayoutPoint();
383     }
384     ASSERT(rootLayer == root());
385
386     LayoutPoint offset;
387     parent()->convertToLayerCoords(rootLayer, offset);
388     return offset;
389 }
390
391 void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags flags)
392 {
393     RenderGeometryMap geometryMap(UseTransforms);
394     if (this != rootLayer)
395         geometryMap.pushMappingsToAncestor(parent(), 0);
396     updateLayerPositions(&geometryMap, flags);
397 }
398
399 void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLayerPositionsFlags flags)
400 {
401     updateLayerPosition(); // For relpositioned layers or non-positioned layers,
402                            // we need to keep in sync, since we may have shifted relative
403                            // to our parent layer.
404     if (geometryMap)
405         geometryMap->pushMappingsToAncestor(this, parent());
406
407     // Clear our cached clip rect information.
408     clearClipRects();
409     
410     if (hasOverflowControls()) {
411         LayoutPoint offsetFromRoot;
412         if (geometryMap)
413             offsetFromRoot = LayoutPoint(geometryMap->absolutePoint(FloatPoint()));
414         else {
415             // FIXME: It looks suspicious to call convertToLayerCoords here
416             // as canUseConvertToLayerCoords may be true for an ancestor layer.
417             convertToLayerCoords(root(), offsetFromRoot);
418         }
419         positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
420     }
421
422     updateDescendantDependentFlags();
423
424     if (flags & UpdatePagination)
425         updatePagination();
426     else {
427         m_isPaginated = false;
428         m_enclosingPaginationLayer = 0;
429     }
430
431     if (m_hasVisibleContent) {
432         // FIXME: LayoutState does not work with RenderLayers as there is not a 1-to-1
433         // mapping between them and the RenderObjects. It would be neat to enable
434         // LayoutState outside the layout() phase and use it here.
435         ASSERT(!renderer().view().layoutStateEnabled());
436
437         RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
438         LayoutRect oldRepaintRect = m_repaintRect;
439         LayoutRect oldOutlineBox = m_outlineBox;
440         computeRepaintRects(repaintContainer, geometryMap);
441
442         // FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
443         // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
444         if (flags & CheckForRepaint) {
445             if (!renderer().view().printing()) {
446                 bool didRepaint = false;
447                 if (m_repaintStatus & NeedsFullRepaint) {
448                     renderer().repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldRepaintRect));
449                     if (m_repaintRect != oldRepaintRect) {
450                         renderer().repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect));
451                         didRepaint = true;
452                     }
453                 } else if (shouldRepaintAfterLayout()) {
454                     renderer().repaintAfterLayoutIfNeeded(repaintContainer, oldRepaintRect, oldOutlineBox, &m_repaintRect, &m_outlineBox);
455                     didRepaint = true;
456                 }
457
458                 if (didRepaint && renderer().isRenderNamedFlowFragmentContainer()) {
459                     // If we just repainted a region, we must also repaint the flow thread since it is the one
460                     // doing the actual painting of the flowed content.
461                     RenderNamedFlowFragment* region = toRenderBlockFlow(&renderer())->renderNamedFlowFragment();
462                     if (region->flowThread())
463                         region->flowThread()->layer()->repaintIncludingDescendants();
464                 }
465             }
466         }
467     } else
468         clearRepaintRects();
469
470     m_repaintStatus = NeedsNormalRepaint;
471
472     // Go ahead and update the reflection's position and size.
473     if (m_reflection)
474         m_reflection->layout();
475
476 #if USE(ACCELERATED_COMPOSITING)
477     // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
478     bool isUpdateRoot = (flags & IsCompositingUpdateRoot);
479     if (isComposited())
480         flags &= ~IsCompositingUpdateRoot;
481 #endif
482
483     if (useRegionBasedColumns() && renderer().isInFlowRenderFlowThread()) {
484         updatePagination();
485         flags |= UpdatePagination;
486     }
487     
488     if (renderer().hasColumns())
489         flags |= UpdatePagination;
490
491     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
492         child->updateLayerPositions(geometryMap, flags);
493
494 #if USE(ACCELERATED_COMPOSITING)
495     if ((flags & UpdateCompositingLayers) && isComposited()) {
496         RenderLayerBacking::UpdateAfterLayoutFlags updateFlags = RenderLayerBacking::CompositingChildrenOnly;
497         if (flags & NeedsFullRepaintInBacking)
498             updateFlags |= RenderLayerBacking::NeedsFullRepaint;
499         if (isUpdateRoot)
500             updateFlags |= RenderLayerBacking::IsUpdateRoot;
501         backing()->updateAfterLayout(updateFlags);
502     }
503 #endif
504         
505     // With all our children positioned, now update our marquee if we need to.
506     if (m_marquee) {
507         // FIXME: would like to use TemporaryChange<> but it doesn't work with bitfields.
508         bool oldUpdatingMarqueePosition = m_updatingMarqueePosition;
509         m_updatingMarqueePosition = true;
510         m_marquee->updateMarqueePosition();
511         m_updatingMarqueePosition = oldUpdatingMarqueePosition;
512     }
513
514     if (geometryMap)
515         geometryMap->popMappingsToAncestor(parent());
516 }
517
518 LayoutRect RenderLayer::repaintRectIncludingNonCompositingDescendants() const
519 {
520     LayoutRect repaintRect = m_repaintRect;
521     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
522         // Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
523         if (child->isComposited())
524             continue;
525
526         repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants());
527     }
528     return repaintRect;
529 }
530
531 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
532 {
533     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
534         if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaintingLayerDescendant())
535             break;
536
537         layer->m_hasSelfPaintingLayerDescendantDirty = false;
538         layer->m_hasSelfPaintingLayerDescendant = true;
539     }
540 }
541
542 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
543 {
544     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
545         layer->m_hasSelfPaintingLayerDescendantDirty = true;
546         // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
547         // in this case, there is no need to dirty our ancestors further.
548         if (layer->isSelfPaintingLayer()) {
549             ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant());
550             break;
551         }
552     }
553 }
554
555 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
556 {
557     return renderer().frame().settings().acceleratedCompositingForOverflowScrollEnabled();
558 }
559
560 // If we are a stacking container, then this function will determine if our
561 // descendants for a contiguous block in stacking order. This is required in
562 // order for an element to be safely promoted to a stacking container. It is safe
563 // to become a stacking container if this change would not alter the stacking
564 // order of layers on the page. That can only happen if a non-descendant appear
565 // between us and our descendants in stacking order. Here's an example:
566 //
567 //                                 this
568 //                                /  |  \.
569 //                               A   B   C
570 //                              /\   |   /\.
571 //                             0 -8  D  2  7
572 //                                   |
573 //                                   5
574 //
575 // I've labeled our normal flow descendants A, B, C, and D, our stacking
576 // container descendants with their z indices, and us with 'this' (we're a
577 // stacking container and our zIndex doesn't matter here). These nodes appear in
578 // three lists: posZOrder, negZOrder, and normal flow (keep in mind that normal
579 // flow layers don't overlap). So if we arrange these lists in order we get our
580 // stacking order:
581 //
582 //                     [-8], [A-D], [0, 2, 5, 7]--> pos z-order.
583 //                       |     |
584 //        Neg z-order. <-+     +--> Normal flow descendants.
585 //
586 // We can then assign new, 'stacking' order indices to these elements as follows:
587 //
588 //                     [-8], [A-D], [0, 2, 5, 7]
589 // 'Stacking' indices:  -1     0     1  2  3  4
590 //
591 // Note that the normal flow descendants can share an index because they don't
592 // stack/overlap. Now our problem becomes very simple: a layer can safely become
593 // a stacking container if the stacking-order indices of it and its descendants
594 // appear in a contiguous block in the list of stacking indices. This problem
595 // can be solved very efficiently by calculating the min/max stacking indices in
596 // the subtree, and the number stacking container descendants. Once we have this
597 // information, we know that the subtree's indices form a contiguous block if:
598 //
599 //           maxStackIndex - minStackIndex == numSCDescendants
600 //
601 // So for node A in the example above we would have:
602 //   maxStackIndex = 1
603 //   minStackIndex = -1
604 //   numSCDecendants = 2
605 //
606 // and so,
607 //       maxStackIndex - minStackIndex == numSCDescendants
608 //  ===>                      1 - (-1) == 2
609 //  ===>                             2 == 2
610 //
611 //  Since this is true, A can safely become a stacking container.
612 //  Now, for node C we have:
613 //
614 //   maxStackIndex = 4
615 //   minStackIndex = 0 <-- because C has stacking index 0.
616 //   numSCDecendants = 2
617 //
618 // and so,
619 //       maxStackIndex - minStackIndex == numSCDescendants
620 //  ===>                         4 - 0 == 2
621 //  ===>                             4 == 2
622 //
623 // Since this is false, C cannot be safely promoted to a stacking container. This
624 // happened because of the elements with z-index 5 and 0. Now if 5 had been a
625 // child of C rather than D, and A had no child with Z index 0, we would have had:
626 //
627 //   maxStackIndex = 3
628 //   minStackIndex = 0 <-- because C has stacking index 0.
629 //   numSCDecendants = 3
630 //
631 // and so,
632 //       maxStackIndex - minStackIndex == numSCDescendants
633 //  ===>                         3 - 0 == 3
634 //  ===>                             3 == 3
635 //
636 //  And we would conclude that C could be promoted.
637 void RenderLayer::updateDescendantsAreContiguousInStackingOrder()
638 {
639     if (!isStackingContext() || !acceleratedCompositingForOverflowScrollEnabled())
640         return;
641
642     ASSERT(!m_normalFlowListDirty);
643     ASSERT(!m_zOrderListsDirty);
644
645     OwnPtr<Vector<RenderLayer*>> posZOrderList;
646     OwnPtr<Vector<RenderLayer*>> negZOrderList;
647     rebuildZOrderLists(StopAtStackingContexts, posZOrderList, negZOrderList);
648
649     // Create a reverse lookup.
650     HashMap<const RenderLayer*, int> lookup;
651
652     if (negZOrderList) {
653         int stackingOrderIndex = -1;
654         size_t listSize = negZOrderList->size();
655         for (size_t i = 0; i < listSize; ++i) {
656             RenderLayer* currentLayer = negZOrderList->at(listSize - i - 1);
657             if (!currentLayer->isStackingContext())
658                 continue;
659             lookup.set(currentLayer, stackingOrderIndex--);
660         }
661     }
662
663     if (posZOrderList) {
664         size_t listSize = posZOrderList->size();
665         int stackingOrderIndex = 1;
666         for (size_t i = 0; i < listSize; ++i) {
667             RenderLayer* currentLayer = posZOrderList->at(i);
668             if (!currentLayer->isStackingContext())
669                 continue;
670             lookup.set(currentLayer, stackingOrderIndex++);
671         }
672     }
673
674     int minIndex = 0;
675     int maxIndex = 0;
676     int count = 0;
677     bool firstIteration = true;
678     updateDescendantsAreContiguousInStackingOrderRecursive(lookup, minIndex, maxIndex, count, firstIteration);
679 }
680
681 void RenderLayer::updateDescendantsAreContiguousInStackingOrderRecursive(const HashMap<const RenderLayer*, int>& lookup, int& minIndex, int& maxIndex, int& count, bool firstIteration)
682 {
683     if (isStackingContext() && !firstIteration) {
684         if (lookup.contains(this)) {
685             minIndex = std::min(minIndex, lookup.get(this));
686             maxIndex = std::max(maxIndex, lookup.get(this));
687             count++;
688         }
689         return;
690     }
691
692     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
693         int childMinIndex = 0;
694         int childMaxIndex = 0;
695         int childCount = 0;
696         child->updateDescendantsAreContiguousInStackingOrderRecursive(lookup, childMinIndex, childMaxIndex, childCount, false);
697         if (childCount) {
698             count += childCount;
699             minIndex = std::min(minIndex, childMinIndex);
700             maxIndex = std::max(maxIndex, childMaxIndex);
701         }
702     }
703
704     if (!isStackingContext()) {
705         bool newValue = maxIndex - minIndex == count;
706 #if USE(ACCELERATED_COMPOSITING)
707         bool didUpdate = newValue != m_descendantsAreContiguousInStackingOrder;
708 #endif
709         m_descendantsAreContiguousInStackingOrder = newValue;
710 #if USE(ACCELERATED_COMPOSITING)
711         if (didUpdate)
712             updateNeedsCompositedScrolling();
713 #endif
714     }
715 }
716
717 void RenderLayer::computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap)
718 {
719     ASSERT(!m_visibleContentStatusDirty);
720
721     m_repaintRect = renderer().clippedOverflowRectForRepaint(repaintContainer);
722     m_outlineBox = renderer().outlineBoundsForRepaint(repaintContainer, geometryMap);
723 }
724
725
726 void RenderLayer::computeRepaintRectsIncludingDescendants()
727 {
728     // FIXME: computeRepaintRects() has to walk up the parent chain for every layer to compute the rects.
729     // We should make this more efficient.
730     // FIXME: it's wrong to call this when layout is not up-to-date, which we do.
731     computeRepaintRects(renderer().containerForRepaint());
732
733     for (RenderLayer* layer = firstChild(); layer; layer = layer->nextSibling())
734         layer->computeRepaintRectsIncludingDescendants();
735 }
736
737 void RenderLayer::clearRepaintRects()
738 {
739     ASSERT(!m_hasVisibleContent);
740     ASSERT(!m_visibleContentStatusDirty);
741
742     m_repaintRect = IntRect();
743     m_outlineBox = IntRect();
744 }
745
746 void RenderLayer::updateLayerPositionsAfterDocumentScroll()
747 {
748     ASSERT(this == renderer().view().layer());
749
750     RenderGeometryMap geometryMap(UseTransforms);
751     updateLayerPositionsAfterScroll(&geometryMap);
752 }
753
754 void RenderLayer::updateLayerPositionsAfterOverflowScroll()
755 {
756     RenderGeometryMap geometryMap(UseTransforms);
757     if (this != renderer().view().layer())
758         geometryMap.pushMappingsToAncestor(parent(), 0);
759
760     // FIXME: why is it OK to not check the ancestors of this layer in order to
761     // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags?
762     updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll);
763 }
764
765 void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap, UpdateLayerPositionsAfterScrollFlags flags)
766 {
767     // FIXME: This shouldn't be needed, but there are some corner cases where
768     // these flags are still dirty. Update so that the check below is valid.
769     updateDescendantDependentFlags();
770
771     // If we have no visible content and no visible descendants, there is no point recomputing
772     // our rectangles as they will be empty. If our visibility changes, we are expected to
773     // recompute all our positions anyway.
774     if (!m_hasVisibleDescendant && !m_hasVisibleContent)
775         return;
776
777     bool positionChanged = updateLayerPosition();
778     if (positionChanged)
779         flags |= HasChangedAncestor;
780
781     if (geometryMap)
782         geometryMap->pushMappingsToAncestor(this, parent());
783
784     if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll)
785         clearClipRects();
786
787     if (renderer().style().hasViewportConstrainedPosition())
788         flags |= HasSeenViewportConstrainedAncestor;
789
790     if (renderer().hasOverflowClip())
791         flags |= HasSeenAncestorWithOverflowClip;
792
793     if (flags & HasSeenViewportConstrainedAncestor
794         || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip)) {
795         // FIXME: We could track the repaint container as we walk down the tree.
796         computeRepaintRects(renderer().containerForRepaint(), geometryMap);
797     } else {
798         // Check that our cached rects are correct.
799         ASSERT(m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint()));
800         ASSERT(m_outlineBox == renderer().outlineBoundsForRepaint(renderer().containerForRepaint(), geometryMap));
801     }
802     
803     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
804         child->updateLayerPositionsAfterScroll(geometryMap, flags);
805
806     // We don't update our reflection as scrolling is a translation which does not change the size()
807     // of an object, thus RenderReplica will still repaint itself properly as the layer position was
808     // updated above.
809
810     if (m_marquee) {
811         bool oldUpdatingMarqueePosition = m_updatingMarqueePosition;
812         m_updatingMarqueePosition = true;
813         m_marquee->updateMarqueePosition();
814         m_updatingMarqueePosition = oldUpdatingMarqueePosition;
815     }
816
817     if (geometryMap)
818         geometryMap->popMappingsToAncestor(parent());
819 }
820
821 #if USE(ACCELERATED_COMPOSITING)
822
823 void RenderLayer::positionNewlyCreatedOverflowControls()
824 {
825     if (!backing()->hasUnpositionedOverflowControlsLayers())
826         return;
827
828     RenderGeometryMap geometryMap(UseTransforms);
829     if (this != renderer().view().layer() && parent())
830         geometryMap.pushMappingsToAncestor(parent(), 0);
831
832     LayoutPoint offsetFromRoot = LayoutPoint(geometryMap.absolutePoint(FloatPoint()));
833     positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
834 }
835
836 #endif
837
838 #if ENABLE(CSS_COMPOSITING)
839
840 void RenderLayer::updateBlendMode()
841 {
842     BlendMode newBlendMode = renderer().style().blendMode();
843     if (newBlendMode != m_blendMode) {
844         m_blendMode = newBlendMode;
845         if (backing())
846             backing()->setBlendMode(newBlendMode);
847     }
848 }
849
850 #endif
851
852 void RenderLayer::updateTransform()
853 {
854     // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
855     // so check style too.
856     bool hasTransform = renderer().hasTransform() && renderer().style().hasTransform();
857     bool had3DTransform = has3DTransform();
858
859     bool hadTransform = m_transform;
860     if (hasTransform != hadTransform) {
861         if (hasTransform)
862             m_transform = adoptPtr(new TransformationMatrix);
863         else
864             m_transform.clear();
865         
866         // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
867         clearClipRectsIncludingDescendants();
868     }
869     
870     if (hasTransform) {
871         RenderBox* box = renderBox();
872         ASSERT(box);
873         m_transform->makeIdentity();
874         box->style().applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
875         makeMatrixRenderable(*m_transform, canRender3DTransforms());
876     }
877
878     if (had3DTransform != has3DTransform())
879         dirty3DTransformedDescendantStatus();
880 }
881
882 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
883 {
884     if (!m_transform)
885         return TransformationMatrix();
886
887 #if USE(ACCELERATED_COMPOSITING)
888     if (renderer().style().isRunningAcceleratedAnimation()) {
889         TransformationMatrix currTransform;
890         RefPtr<RenderStyle> style = renderer().animation().getAnimatedStyleForRenderer(&renderer());
891         style->applyTransform(currTransform, renderBox()->pixelSnappedBorderBoxRect().size(), applyOrigin);
892         makeMatrixRenderable(currTransform, canRender3DTransforms());
893         return currTransform;
894     }
895
896     // m_transform includes transform-origin, so we need to recompute the transform here.
897     if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
898         RenderBox* box = renderBox();
899         TransformationMatrix currTransform;
900         box->style().applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
901         makeMatrixRenderable(currTransform, canRender3DTransforms());
902         return currTransform;
903     }
904 #else
905     UNUSED_PARAM(applyOrigin);
906 #endif
907
908     return *m_transform;
909 }
910
911 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
912 {
913     if (!m_transform)
914         return TransformationMatrix();
915     
916     if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
917         TransformationMatrix matrix = *m_transform;
918         makeMatrixRenderable(matrix, false /* flatten 3d */);
919         return matrix;
920     }
921
922     return *m_transform;
923 }
924
925 RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
926 {
927     const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
928     while (layer) {
929         if (layer->renderer().hasOverflowClip())
930             return const_cast<RenderLayer*>(layer);
931
932         layer = layer->parent();
933     }
934     return 0;
935 }
936
937 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
938 {
939     RenderLayerModelObject* prevBlock = renderer;
940     RenderBlock* containingBlock;
941     for (containingBlock = renderer->containingBlock();
942         containingBlock && containingBlock != &renderer->view() && containingBlock != ancestorColumnsRenderer;
943         containingBlock = containingBlock->containingBlock()) {
944         prevBlock = containingBlock;
945     }
946     
947     // If the columns block wasn't in our containing block chain, then we aren't paginated by it.
948     if (containingBlock != ancestorColumnsRenderer)
949         return false;
950         
951     // If the previous block is absolutely positioned, then we can't be paginated by the columns block.
952     if (prevBlock->isOutOfFlowPositioned())
953         return false;
954         
955     // Otherwise we are paginated by the columns block.
956     return true;
957 }
958
959 bool RenderLayer::useRegionBasedColumns() const
960 {
961     const Settings& settings = renderer().frame().settings();
962     return settings.regionBasedColumnsEnabled();
963 }
964
965 void RenderLayer::updatePagination()
966 {
967     m_isPaginated = false;
968     m_enclosingPaginationLayer = 0;
969
970     if (isComposited() || !parent())
971         return; // FIXME: We will have to deal with paginated compositing layers someday.
972                 // FIXME: For now the RenderView can't be paginated.  Eventually printing will move to a model where it is though.
973
974     // The main difference between the paginated booleans for the old column code and the new column code
975     // is that each paginated layer has to paint on its own with the new code. There is no
976     // recurring into child layers. This means that the m_isPaginated bits for the new column code can't just be set on
977     // "roots" that get split and paint all their descendants. Instead each layer has to be checked individually and
978     // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant
979     // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
980     // to that layer easily.
981     bool regionBasedColumnsUsed = useRegionBasedColumns();
982     if (regionBasedColumnsUsed && renderer().isInFlowRenderFlowThread()) {
983         m_enclosingPaginationLayer = this;
984         return;
985     }
986
987     if (isNormalFlowOnly()) {
988         if (regionBasedColumnsUsed) {
989             // Content inside a transform is not considered to be paginated, since we simply
990             // paint the transform multiple times in each column, so we don't have to use
991             // fragments for the transformed content.
992             m_enclosingPaginationLayer = parent()->enclosingPaginationLayer();
993             if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
994                 m_enclosingPaginationLayer = 0;
995         } else
996             m_isPaginated = parent()->renderer().hasColumns();
997         return;
998     }
999
1000     // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once
1001     // we find one, then we just check its pagination status.
1002     if (regionBasedColumnsUsed) {
1003         RenderView* renderView = &renderer().view();
1004         RenderBlock* containingBlock;
1005         for (containingBlock = renderer().containingBlock();
1006             containingBlock && containingBlock != renderView;
1007             containingBlock = containingBlock->containingBlock()) {
1008             if (containingBlock->hasLayer()) {
1009                 // Content inside a transform is not considered to be paginated, since we simply
1010                 // paint the transform multiple times in each column, so we don't have to use
1011                 // fragments for the transformed content.
1012                 m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer();
1013                 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
1014                     m_enclosingPaginationLayer = 0;
1015                 return;
1016             }
1017         }
1018         return;
1019     }
1020
1021     // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container.
1022     RenderLayer* ancestorStackingContainer = stackingContainer();
1023     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1024         if (curr->renderer().hasColumns()) {
1025             m_isPaginated = checkContainingBlockChainForPagination(&renderer(), curr->renderBox());
1026             return;
1027         }
1028         if (curr == ancestorStackingContainer)
1029             return;
1030     }
1031 }
1032
1033 bool RenderLayer::canBeStackingContainer() const
1034 {
1035     if (isStackingContext() || !stackingContainer())
1036         return true;
1037
1038     return m_descendantsAreContiguousInStackingOrder;
1039 }
1040
1041 void RenderLayer::setHasVisibleContent()
1042
1043     if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
1044         ASSERT(!parent() || parent()->hasVisibleDescendant());
1045         return;
1046     }
1047
1048     m_visibleContentStatusDirty = false; 
1049     m_hasVisibleContent = true;
1050     computeRepaintRects(renderer().containerForRepaint());
1051     if (!isNormalFlowOnly()) {
1052         // We don't collect invisible layers in z-order lists if we are not in compositing mode.
1053         // As we became visible, we need to dirty our stacking containers ancestors to be properly
1054         // collected. FIXME: When compositing, we could skip this dirtying phase.
1055         for (RenderLayer* sc = stackingContainer(); sc; sc = sc->stackingContainer()) {
1056             sc->dirtyZOrderLists();
1057             if (sc->hasVisibleContent())
1058                 break;
1059         }
1060     }
1061
1062     if (parent())
1063         parent()->setAncestorChainHasVisibleDescendant();
1064 }
1065
1066 void RenderLayer::dirtyVisibleContentStatus() 
1067
1068     m_visibleContentStatusDirty = true; 
1069     if (parent())
1070         parent()->dirtyAncestorChainVisibleDescendantStatus();
1071 }
1072
1073 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
1074 {
1075     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1076         if (layer->m_visibleDescendantStatusDirty)
1077             break;
1078
1079         layer->m_visibleDescendantStatusDirty = true;
1080     }
1081 }
1082
1083 void RenderLayer::setAncestorChainHasVisibleDescendant()
1084 {
1085     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1086         if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendant())
1087             break;
1088
1089         layer->m_hasVisibleDescendant = true;
1090         layer->m_visibleDescendantStatusDirty = false;
1091     }
1092 }
1093
1094 void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks)
1095 {
1096     if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) {
1097         m_hasVisibleDescendant = false;
1098         m_hasSelfPaintingLayerDescendant = false;
1099         m_hasOutOfFlowPositionedDescendant = false;
1100
1101         HashSet<const RenderObject*> childOutOfFlowDescendantContainingBlocks;
1102         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1103             childOutOfFlowDescendantContainingBlocks.clear();
1104             child->updateDescendantDependentFlags(&childOutOfFlowDescendantContainingBlocks);
1105
1106             bool childIsOutOfFlowPositioned = child->renderer().isOutOfFlowPositioned();
1107             if (childIsOutOfFlowPositioned)
1108                 childOutOfFlowDescendantContainingBlocks.add(child->renderer().containingBlock());
1109
1110             if (outOfFlowDescendantContainingBlocks) {
1111                 HashSet<const RenderObject*>::const_iterator it = childOutOfFlowDescendantContainingBlocks.begin();
1112                 for (; it != childOutOfFlowDescendantContainingBlocks.end(); ++it)
1113                     outOfFlowDescendantContainingBlocks->add(*it);
1114             }
1115
1116             bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant;
1117             bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
1118             bool hasOutOfFlowPositionedDescendant = !childOutOfFlowDescendantContainingBlocks.isEmpty();
1119
1120             m_hasVisibleDescendant |= hasVisibleDescendant;
1121             m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
1122             m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescendant;
1123
1124             if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && m_hasOutOfFlowPositionedDescendant)
1125                 break;
1126         }
1127
1128         if (outOfFlowDescendantContainingBlocks)
1129             outOfFlowDescendantContainingBlocks->remove(&renderer());
1130
1131         m_visibleDescendantStatusDirty = false;
1132         m_hasSelfPaintingLayerDescendantDirty = false;
1133
1134 #if USE(ACCELERATED_COMPOSITING)
1135         if (m_hasOutOfFlowPositionedDescendantDirty)
1136             updateNeedsCompositedScrolling();
1137 #endif
1138         m_hasOutOfFlowPositionedDescendantDirty = false;
1139     }
1140
1141     if (m_visibleContentStatusDirty) {
1142         if (renderer().style().visibility() == VISIBLE)
1143             m_hasVisibleContent = true;
1144         else {
1145             // layer may be hidden but still have some visible content, check for this
1146             m_hasVisibleContent = false;
1147             RenderObject* r = renderer().firstChild();
1148             while (r) {
1149                 if (r->style().visibility() == VISIBLE && !r->hasLayer()) {
1150                     m_hasVisibleContent = true;
1151                     break;
1152                 }
1153                 RenderObject* child;
1154                 if (!r->hasLayer() && (child = r->firstChildSlow()))
1155                     r = child;
1156                 else if (r->nextSibling())
1157                     r = r->nextSibling();
1158                 else {
1159                     do {
1160                         r = r->parent();
1161                         if (r == &renderer())
1162                             r = 0;
1163                     } while (r && !r->nextSibling());
1164                     if (r)
1165                         r = r->nextSibling();
1166                 }
1167             }
1168         }    
1169         m_visibleContentStatusDirty = false; 
1170     }
1171 }
1172
1173 #if USE(ACCELERATED_COMPOSITING)
1174 // Return true if the new clipping behaviour requires layer update.
1175 bool RenderLayer::checkIfDescendantClippingContextNeedsUpdate(bool isClipping)
1176 {
1177     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1178         RenderLayerBacking* backing = child->backing();
1179         // Layer subtree needs update when new clipping is added or existing clipping is removed.
1180         if (backing && (isClipping || backing->hasAncestorClippingLayer()))
1181             return true;
1182
1183         if (child->checkIfDescendantClippingContextNeedsUpdate(isClipping))
1184             return true;
1185     }
1186     return false;
1187 }
1188 #endif
1189
1190 void RenderLayer::dirty3DTransformedDescendantStatus()
1191 {
1192     RenderLayer* curr = stackingContainer();
1193     if (curr)
1194         curr->m_3DTransformedDescendantStatusDirty = true;
1195         
1196     // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
1197     // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
1198     while (curr && curr->preserves3D()) {
1199         curr->m_3DTransformedDescendantStatusDirty = true;
1200         curr = curr->stackingContainer();
1201     }
1202 }
1203
1204 // Return true if this layer or any preserve-3d descendants have 3d.
1205 bool RenderLayer::update3DTransformedDescendantStatus()
1206 {
1207     if (m_3DTransformedDescendantStatusDirty) {
1208         m_has3DTransformedDescendant = false;
1209
1210         updateZOrderLists();
1211
1212         // Transformed or preserve-3d descendants can only be in the z-order lists, not
1213         // in the normal flow list, so we only need to check those.
1214         if (Vector<RenderLayer*>* positiveZOrderList = posZOrderList()) {
1215             for (unsigned i = 0; i < positiveZOrderList->size(); ++i)
1216                 m_has3DTransformedDescendant |= positiveZOrderList->at(i)->update3DTransformedDescendantStatus();
1217         }
1218
1219         // Now check our negative z-index children.
1220         if (Vector<RenderLayer*>* negativeZOrderList = negZOrderList()) {
1221             for (unsigned i = 0; i < negativeZOrderList->size(); ++i)
1222                 m_has3DTransformedDescendant |= negativeZOrderList->at(i)->update3DTransformedDescendantStatus();
1223         }
1224         
1225         m_3DTransformedDescendantStatusDirty = false;
1226     }
1227     
1228     // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
1229     // the m_has3DTransformedDescendant set.
1230     if (preserves3D())
1231         return has3DTransform() || m_has3DTransformedDescendant;
1232
1233     return has3DTransform();
1234 }
1235
1236 bool RenderLayer::updateLayerPosition()
1237 {
1238     LayoutPoint localPoint;
1239     LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
1240     if (renderer().isInline() && renderer().isRenderInline()) {
1241         RenderInline& inlineFlow = toRenderInline(renderer());
1242         IntRect lineBox = inlineFlow.linesBoundingBox();
1243         setSize(lineBox.size());
1244         inlineBoundingBoxOffset = toSize(lineBox.location());
1245         localPoint += inlineBoundingBoxOffset;
1246     } else if (RenderBox* box = renderBox()) {
1247         // FIXME: Is snapping the size really needed here for the RenderBox case?
1248         setSize(pixelSnappedIntSize(box->size(), box->location()));
1249         localPoint += box->topLeftLocationOffset();
1250     }
1251
1252     if (!renderer().isOutOfFlowPositioned() && renderer().parent()) {
1253         // We must adjust our position by walking up the render tree looking for the
1254         // nearest enclosing object with a layer.
1255         RenderElement* curr = renderer().parent();
1256         while (curr && !curr->hasLayer()) {
1257             if (curr->isBox() && !curr->isTableRow()) {
1258                 // Rows and cells share the same coordinate space (that of the section).
1259                 // Omit them when computing our xpos/ypos.
1260                 localPoint += toRenderBox(curr)->topLeftLocationOffset();
1261             }
1262             curr = curr->parent();
1263         }
1264         if (curr->isBox() && curr->isTableRow()) {
1265             // Put ourselves into the row coordinate space.
1266             localPoint -= toRenderBox(curr)->topLeftLocationOffset();
1267         }
1268     }
1269     
1270     // Subtract our parent's scroll offset.
1271     if (renderer().isOutOfFlowPositioned() && enclosingPositionedAncestor()) {
1272         RenderLayer* positionedParent = enclosingPositionedAncestor();
1273
1274         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
1275         if (positionedParent->renderer().hasOverflowClip()) {
1276             LayoutSize offset = positionedParent->scrolledContentOffset();
1277             localPoint -= offset;
1278         }
1279         
1280         if (renderer().isOutOfFlowPositioned() && positionedParent->renderer().isInFlowPositioned() && positionedParent->renderer().isRenderInline()) {
1281             LayoutSize offset = toRenderInline(positionedParent->renderer()).offsetForInFlowPositionedInline(&toRenderBox(renderer()));
1282             localPoint += offset;
1283         }
1284     } else if (parent()) {
1285         if (parent()->renderer().hasOverflowClip()) {
1286             IntSize scrollOffset = parent()->scrolledContentOffset();
1287             localPoint -= scrollOffset;
1288         }
1289     }
1290     
1291     bool positionOrOffsetChanged = false;
1292     if (renderer().isInFlowPositioned()) {
1293         LayoutSize newOffset = toRenderBoxModelObject(renderer()).offsetForInFlowPosition();
1294         positionOrOffsetChanged = newOffset != m_offsetForInFlowPosition;
1295         m_offsetForInFlowPosition = newOffset;
1296         localPoint.move(m_offsetForInFlowPosition);
1297     } else {
1298         m_offsetForInFlowPosition = LayoutSize();
1299     }
1300
1301     // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
1302     localPoint -= inlineBoundingBoxOffset;
1303     
1304     positionOrOffsetChanged |= location() != localPoint;
1305     setLocation(localPoint);
1306     return positionOrOffsetChanged;
1307 }
1308
1309 TransformationMatrix RenderLayer::perspectiveTransform() const
1310 {
1311     if (!renderer().hasTransform())
1312         return TransformationMatrix();
1313
1314     const RenderStyle& style = renderer().style();
1315     if (!style.hasPerspective())
1316         return TransformationMatrix();
1317
1318     // Maybe fetch the perspective from the backing?
1319     const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
1320     const float boxWidth = borderBox.width();
1321     const float boxHeight = borderBox.height();
1322
1323     float perspectiveOriginX = floatValueForLength(style.perspectiveOriginX(), boxWidth);
1324     float perspectiveOriginY = floatValueForLength(style.perspectiveOriginY(), boxHeight);
1325
1326     // A perspective origin of 0,0 makes the vanishing point in the center of the element.
1327     // We want it to be in the top-left, so subtract half the height and width.
1328     perspectiveOriginX -= boxWidth / 2.0f;
1329     perspectiveOriginY -= boxHeight / 2.0f;
1330     
1331     TransformationMatrix t;
1332     t.translate(perspectiveOriginX, perspectiveOriginY);
1333     t.applyPerspective(style.perspective());
1334     t.translate(-perspectiveOriginX, -perspectiveOriginY);
1335     
1336     return t;
1337 }
1338
1339 FloatPoint RenderLayer::perspectiveOrigin() const
1340 {
1341     if (!renderer().hasTransform())
1342         return FloatPoint();
1343
1344     const LayoutRect borderBox = toRenderBox(renderer()).borderBoxRect();
1345     const RenderStyle& style = renderer().style();
1346
1347     return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBox.width()),
1348                       floatValueForLength(style.perspectiveOriginY(), borderBox.height()));
1349 }
1350
1351 RenderLayer* RenderLayer::stackingContainer() const
1352 {
1353     RenderLayer* layer = parent();
1354     while (layer && !layer->isStackingContainer())
1355         layer = layer->parent();
1356
1357     ASSERT(!layer || layer->isStackingContainer());
1358     return layer;
1359 }
1360
1361 static inline bool isPositionedContainer(RenderLayer* layer)
1362 {
1363     return layer->isRootLayer() || layer->renderer().isPositioned() || layer->hasTransform();
1364 }
1365
1366 static inline bool isFixedPositionedContainer(RenderLayer* layer)
1367 {
1368     return layer->isRootLayer() || layer->hasTransform();
1369 }
1370
1371 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
1372 {
1373     RenderLayer* curr = parent();
1374     while (curr && !isPositionedContainer(curr))
1375         curr = curr->parent();
1376
1377     return curr;
1378 }
1379
1380 static RenderLayer* parentLayerCrossFrame(const RenderLayer* layer)
1381 {
1382     ASSERT(layer);
1383     if (layer->parent())
1384         return layer->parent();
1385
1386     HTMLFrameOwnerElement* ownerElement = layer->renderer().document().ownerElement();
1387     if (!ownerElement)
1388         return 0;
1389
1390     RenderElement* ownerRenderer = ownerElement->renderer();
1391     if (!ownerRenderer)
1392         return 0;
1393
1394     return ownerRenderer->enclosingLayer();
1395 }
1396
1397 RenderLayer* RenderLayer::enclosingScrollableLayer() const
1398 {
1399     for (RenderLayer* nextLayer = parentLayerCrossFrame(this); nextLayer; nextLayer = parentLayerCrossFrame(nextLayer)) {
1400         if (nextLayer->renderer().isBox() && toRenderBox(nextLayer->renderer()).canBeScrolledAndHasScrollableArea())
1401             return nextLayer;
1402     }
1403
1404     return 0;
1405 }
1406
1407 IntRect RenderLayer::scrollableAreaBoundingBox() const
1408 {
1409     return renderer().absoluteBoundingBoxRect();
1410 }
1411
1412 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
1413 {
1414     RenderLayer* curr = parent();
1415     while (curr && !curr->isRootLayer() && !curr->transform())
1416         curr = curr->parent();
1417
1418     return curr;
1419 }
1420
1421 static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
1422 {
1423     return layer->isNormalFlowOnly() ? layer->parent() : layer->stackingContainer();
1424 }
1425
1426 inline bool RenderLayer::shouldRepaintAfterLayout() const
1427 {
1428 #if USE(ACCELERATED_COMPOSITING)
1429     if (m_repaintStatus == NeedsNormalRepaint)
1430         return true;
1431
1432     // Composited layers that were moved during a positioned movement only
1433     // layout, don't need to be repainted. They just need to be recomposited.
1434     ASSERT(m_repaintStatus == NeedsFullRepaintForPositionedMovementLayout);
1435     return !isComposited() || backing()->paintsIntoCompositedAncestor();
1436 #else
1437     return true;
1438 #endif
1439 }
1440
1441 #if USE(ACCELERATED_COMPOSITING)
1442
1443 static bool compositedWithOwnBackingStore(const RenderLayer* layer)
1444 {
1445     return layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor();
1446 }
1447
1448 RenderLayer* RenderLayer::enclosingCompositingLayer(IncludeSelfOrNot includeSelf) const
1449 {
1450     if (includeSelf == IncludeSelf && isComposited())
1451         return const_cast<RenderLayer*>(this);
1452
1453     for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
1454         if (curr->isComposited())
1455             return const_cast<RenderLayer*>(curr);
1456     }
1457          
1458     return 0;
1459 }
1460
1461 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
1462 {
1463     if (includeSelf == IncludeSelf && isComposited() && !backing()->paintsIntoCompositedAncestor())
1464         return const_cast<RenderLayer*>(this);
1465
1466     for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
1467         if (compositedWithOwnBackingStore(curr))
1468             return const_cast<RenderLayer*>(curr);
1469     }
1470          
1471     return 0;
1472 }
1473
1474 #endif
1475
1476 #if ENABLE(CSS_FILTERS)
1477
1478 RenderLayer* RenderLayer::enclosingFilterLayer(IncludeSelfOrNot includeSelf) const
1479 {
1480     const RenderLayer* curr = (includeSelf == IncludeSelf) ? this : parent();
1481     for (; curr; curr = curr->parent()) {
1482         if (curr->requiresFullLayerImageForFilters())
1483             return const_cast<RenderLayer*>(curr);
1484     }
1485     
1486     return 0;
1487 }
1488
1489 RenderLayer* RenderLayer::enclosingFilterRepaintLayer() const
1490 {
1491     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1492         if ((curr != this && curr->requiresFullLayerImageForFilters())
1493 #if USE(ACCELERATED_COMPOSITING)
1494             || compositedWithOwnBackingStore(curr)
1495 #endif
1496             || curr->isRootLayer()
1497         )
1498             return const_cast<RenderLayer*>(curr);
1499     }
1500     return 0;
1501 }
1502
1503 void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect, bool immediate)
1504 {
1505     if (rect.isEmpty())
1506         return;
1507     
1508     LayoutRect rectForRepaint = rect;
1509     renderer().style().filterOutsets().expandRect(rectForRepaint);
1510
1511     FilterInfo& filterInfo = FilterInfo::get(*this);
1512     filterInfo.expandDirtySourceRect(rectForRepaint);
1513     
1514 #if ENABLE(CSS_SHADERS)
1515     ASSERT(filterInfo.renderer());
1516     if (filterInfo.renderer()->hasCustomShaderFilter()) {
1517         // If we have at least one custom shader, we need to update the whole bounding box of the layer, because the
1518         // shader can address any ouput pixel.
1519         // Note: This is only for output rect, so there's no need to expand the dirty source rect.
1520         rectForRepaint.unite(calculateLayerBounds(this));
1521     }
1522 #endif
1523     
1524     RenderLayer* parentLayer = enclosingFilterRepaintLayer();
1525     ASSERT(parentLayer);
1526     FloatQuad repaintQuad(rectForRepaint);
1527     LayoutRect parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1528     
1529 #if USE(ACCELERATED_COMPOSITING)
1530     if (parentLayer->isComposited()) {
1531         if (!parentLayer->backing()->paintsIntoWindow()) {
1532             parentLayer->setBackingNeedsRepaintInRect(parentLayerRect);
1533             return;
1534         }
1535         // If the painting goes to window, redirect the painting to the parent RenderView.
1536         parentLayer = renderer().view().layer();
1537         parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1538     }
1539 #endif
1540
1541     if (parentLayer->paintsWithFilters()) {
1542         parentLayer->setFilterBackendNeedsRepaintingInRect(parentLayerRect, immediate);
1543         return;        
1544     }
1545     
1546     if (parentLayer->isRootLayer()) {
1547         toRenderView(parentLayer->renderer()).repaintViewRectangle(parentLayerRect, immediate);
1548         return;
1549     }
1550     
1551     ASSERT_NOT_REACHED();
1552 }
1553
1554 bool RenderLayer::hasAncestorWithFilterOutsets() const
1555 {
1556     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1557         if (curr->renderer().style().hasFilterOutsets())
1558             return true;
1559     }
1560     return false;
1561 }
1562
1563 #endif
1564
1565 RenderLayer* RenderLayer::clippingRootForPainting() const
1566 {
1567 #if USE(ACCELERATED_COMPOSITING)
1568     if (isComposited())
1569         return const_cast<RenderLayer*>(this);
1570 #endif
1571
1572     const RenderLayer* current = this;
1573     while (current) {
1574         if (current->isRootLayer())
1575             return const_cast<RenderLayer*>(current);
1576
1577         current = compositingContainer(current);
1578         ASSERT(current);
1579         if (current->transform()
1580 #if USE(ACCELERATED_COMPOSITING)
1581             || compositedWithOwnBackingStore(current)
1582 #endif
1583         )
1584             return const_cast<RenderLayer*>(current);
1585     }
1586
1587     ASSERT_NOT_REACHED();
1588     return 0;
1589 }
1590
1591 LayoutPoint RenderLayer::absoluteToContents(const LayoutPoint& absolutePoint) const
1592 {
1593     // We don't use convertToLayerCoords because it doesn't know about transforms
1594     return roundedLayoutPoint(renderer().absoluteToLocal(absolutePoint, UseTransforms));
1595 }
1596
1597 bool RenderLayer::cannotBlitToWindow() const
1598 {
1599     if (isTransparent() || hasReflection() || hasTransform())
1600         return true;
1601     if (!parent())
1602         return false;
1603     return parent()->cannotBlitToWindow();
1604 }
1605
1606 bool RenderLayer::isTransparent() const
1607 {
1608 #if ENABLE(SVG)
1609     if (renderer().element() && renderer().element()->isSVGElement())
1610         return false;
1611 #endif
1612     return renderer().isTransparent() || renderer().hasMask();
1613 }
1614
1615 RenderLayer* RenderLayer::transparentPaintingAncestor()
1616 {
1617     if (isComposited())
1618         return 0;
1619
1620     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1621         if (curr->isComposited())
1622             return 0;
1623         if (curr->isTransparent())
1624             return curr;
1625     }
1626     return 0;
1627 }
1628
1629 enum TransparencyClipBoxBehavior {
1630     PaintingTransparencyClipBox,
1631     HitTestingTransparencyClipBox
1632 };
1633
1634 enum TransparencyClipBoxMode {
1635     DescendantsOfTransparencyClipBox,
1636     RootOfTransparencyClipBox
1637 };
1638
1639 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
1640
1641 static void expandClipRectForRegionAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
1642     TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
1643 {
1644     // If this is a region, then the painting is actually done by its flow thread's layer.
1645     if (layer->renderer().isRenderNamedFlowFragmentContainer()) {
1646         RenderBlockFlow* regionContainer = toRenderBlockFlow(&layer->renderer());
1647         RenderNamedFlowFragment* region = regionContainer->renderNamedFlowFragment();
1648         RenderLayer* flowThreadLayer = region->flowThread()->layer();
1649         if (!layer->reflection() || layer->reflectionLayer() != flowThreadLayer) {
1650             LayoutRect flowThreadClipRect = transparencyClipBox(flowThreadLayer, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior);
1651             
1652             LayoutPoint offsetFromRoot;
1653             layer->convertToLayerCoords(flowThreadLayer, offsetFromRoot);
1654
1655             LayoutSize moveOffset = (offsetFromRoot + regionContainer->contentBoxRect().location()) - region->flowThreadPortionRect().location();
1656             flowThreadClipRect.move(moveOffset);
1657             
1658             clipRect.unite(flowThreadClipRect);
1659         }
1660     }
1661 }
1662
1663 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
1664     TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
1665 {
1666     // If we have a mask, then the clip is limited to the border box area (and there is
1667     // no need to examine child layers).
1668     if (!layer->renderer().hasMask()) {
1669         // Note: we don't have to walk z-order lists since transparent elements always establish
1670         // a stacking container. This means we can just walk the layer tree directly.
1671         for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
1672             if (!layer->reflection() || layer->reflectionLayer() != curr)
1673                 clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
1674         }
1675     }
1676
1677     expandClipRectForRegionAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
1678
1679     // If we have a reflection, then we need to account for that when we push the clip.  Reflect our entire
1680     // current transparencyClipBox to catch all child layers.
1681     // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1682     // size into the parent layer.
1683     if (layer->renderer().hasReflection()) {
1684         LayoutPoint delta;
1685         layer->convertToLayerCoords(rootLayer, delta);
1686         clipRect.move(-delta.x(), -delta.y());
1687         clipRect.unite(layer->renderBox()->reflectedRect(clipRect));
1688         clipRect.moveBy(delta);
1689     }
1690 }
1691
1692 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
1693     TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior)
1694 {
1695     // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
1696     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
1697     // would be better to respect clips.
1698     
1699     if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior))
1700         || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransform()))) {
1701         // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
1702         // the transformed layer and all of its children.
1703         const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0;
1704         const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
1705         LayoutPoint delta;
1706         layer->convertToLayerCoords(rootLayerForTransform, delta);
1707
1708         TransformationMatrix transform;
1709         transform.translate(delta.x(), delta.y());
1710         transform = transform * *layer->transform();
1711
1712         // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
1713         // paints unfragmented.
1714         LayoutRect clipRect = layer->boundingBox(layer);
1715         expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, paintBehavior);
1716 #if ENABLE(CSS_FILTERS)
1717         layer->renderer().style().filterOutsets().expandRect(clipRect);
1718 #endif
1719         LayoutRect result = transform.mapRect(clipRect);
1720         if (!paginationLayer)
1721             return result;
1722         
1723         // We have to break up the transformed extent across our columns.
1724         // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
1725         // get our true bounding box.
1726         RenderFlowThread& enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
1727         result = enclosingFlowThread.fragmentsBoundingBox(result);
1728         
1729         LayoutPoint rootLayerDelta;
1730         paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta);
1731         result.moveBy(rootLayerDelta);
1732         return result;
1733     }
1734     
1735     LayoutRect clipRect = layer->boundingBox(rootLayer, RenderLayer::UseFragmentBoxes);
1736     expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
1737 #if ENABLE(CSS_FILTERS)
1738     layer->renderer().style().filterOutsets().expandRect(clipRect);
1739 #endif
1740     return clipRect;
1741 }
1742
1743 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1744 {
1745     return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
1746 }
1747
1748 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1749 {
1750     if (context->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
1751         return;
1752     
1753     RenderLayer* ancestor = transparentPaintingAncestor();
1754     if (ancestor)
1755         ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
1756     
1757     if (paintsWithTransparency(paintBehavior)) {
1758         m_usedTransparency = true;
1759         context->save();
1760         LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
1761         context->clip(clipRect);
1762         context->beginTransparencyLayer(renderer().opacity());
1763 #ifdef REVEAL_TRANSPARENCY_LAYERS
1764         context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), ColorSpaceDeviceRGB);
1765         context->fillRect(clipRect);
1766 #endif
1767     }
1768 }
1769
1770 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
1771 {
1772     RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
1773     if (prevSibling) {
1774         child->setPreviousSibling(prevSibling);
1775         prevSibling->setNextSibling(child);
1776         ASSERT(prevSibling != child);
1777     } else
1778         setFirstChild(child);
1779
1780     if (beforeChild) {
1781         beforeChild->setPreviousSibling(child);
1782         child->setNextSibling(beforeChild);
1783         ASSERT(beforeChild != child);
1784     } else
1785         setLastChild(child);
1786
1787     child->setParent(this);
1788
1789     if (child->isNormalFlowOnly())
1790         dirtyNormalFlowList();
1791
1792     if (!child->isNormalFlowOnly() || child->firstChild()) {
1793         // Dirty the z-order list in which we are contained. The stackingContainer() can be null in the
1794         // case where we're building up generated content layers. This is ok, since the lists will start
1795         // off dirty in that case anyway.
1796         child->dirtyStackingContainerZOrderLists();
1797     }
1798
1799     child->updateDescendantDependentFlags();
1800     if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
1801         setAncestorChainHasVisibleDescendant();
1802
1803     if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
1804         setAncestorChainHasSelfPaintingLayerDescendant();
1805
1806     if (child->renderer().isOutOfFlowPositioned() || child->hasOutOfFlowPositionedDescendant())
1807         setAncestorChainHasOutOfFlowPositionedDescendant(child->renderer().containingBlock());
1808
1809 #if USE(ACCELERATED_COMPOSITING)
1810     compositor().layerWasAdded(*this, *child);
1811 #endif
1812 }
1813
1814 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1815 {
1816 #if USE(ACCELERATED_COMPOSITING)
1817     if (!renderer().documentBeingDestroyed())
1818         compositor().layerWillBeRemoved(*this, *oldChild);
1819 #endif
1820
1821     // remove the child
1822     if (oldChild->previousSibling())
1823         oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1824     if (oldChild->nextSibling())
1825         oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1826
1827     if (m_first == oldChild)
1828         m_first = oldChild->nextSibling();
1829     if (m_last == oldChild)
1830         m_last = oldChild->previousSibling();
1831
1832     if (oldChild->isNormalFlowOnly())
1833         dirtyNormalFlowList();
1834     if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { 
1835         // Dirty the z-order list in which we are contained.  When called via the
1836         // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1837         // from the main layer tree, so we need to null-check the |stackingContainer| value.
1838         oldChild->dirtyStackingContainerZOrderLists();
1839     }
1840
1841     if (oldChild->renderer().isOutOfFlowPositioned() || oldChild->hasOutOfFlowPositionedDescendant())
1842         dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
1843
1844     oldChild->setPreviousSibling(0);
1845     oldChild->setNextSibling(0);
1846     oldChild->setParent(0);
1847     
1848     oldChild->updateDescendantDependentFlags();
1849     if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1850         dirtyAncestorChainVisibleDescendantStatus();
1851
1852     if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
1853         dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1854
1855     return oldChild;
1856 }
1857
1858 void RenderLayer::removeOnlyThisLayer()
1859 {
1860     if (!m_parent)
1861         return;
1862
1863     // Mark that we are about to lose our layer. This makes render tree
1864     // walks ignore this layer while we're removing it.
1865     renderer().setHasLayer(false);
1866
1867 #if USE(ACCELERATED_COMPOSITING)
1868     compositor().layerWillBeRemoved(*m_parent, *this);
1869 #endif
1870
1871     // Dirty the clip rects.
1872     clearClipRectsIncludingDescendants();
1873
1874     RenderLayer* nextSib = nextSibling();
1875
1876     // Remove the child reflection layer before moving other child layers.
1877     // The reflection layer should not be moved to the parent.
1878     if (reflection())
1879         removeChild(reflectionLayer());
1880
1881     // Now walk our kids and reattach them to our parent.
1882     RenderLayer* current = m_first;
1883     while (current) {
1884         RenderLayer* next = current->nextSibling();
1885         removeChild(current);
1886         m_parent->addChild(current, nextSib);
1887         current->setRepaintStatus(NeedsFullRepaint);
1888         // updateLayerPositions depends on hasLayer() already being false for proper layout.
1889         ASSERT(!renderer().hasLayer());
1890         current->updateLayerPositions(0); // FIXME: use geometry map.
1891         current = next;
1892     }
1893
1894     // Remove us from the parent.
1895     m_parent->removeChild(this);
1896     renderer().destroyLayer();
1897 }
1898
1899 void RenderLayer::insertOnlyThisLayer()
1900 {
1901     if (!m_parent && renderer().parent()) {
1902         // We need to connect ourselves when our renderer() has a parent.
1903         // Find our enclosingLayer and add ourselves.
1904         RenderLayer* parentLayer = renderer().parent()->enclosingLayer();
1905         ASSERT(parentLayer);
1906         RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer().parent()->findNextLayer(parentLayer, &renderer()) : 0;
1907         parentLayer->addChild(this, beforeChild);
1908     }
1909
1910     // Remove all descendant layers from the hierarchy and add them to the new position.
1911     for (RenderObject* curr = renderer().firstChild(); curr; curr = curr->nextSibling()) {
1912         if (curr->isRenderElement())
1913             toRenderElement(curr)->moveLayers(m_parent, this);
1914     }
1915
1916     // Clear out all the clip rects.
1917     clearClipRectsIncludingDescendants();
1918 }
1919
1920 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation, ColumnOffsetAdjustment adjustForColumns) const
1921 {
1922     LayoutPoint location = roundedLocation;
1923     convertToLayerCoords(ancestorLayer, location, adjustForColumns);
1924     roundedLocation = roundedIntPoint(location);
1925 }
1926
1927 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect& roundedRect, ColumnOffsetAdjustment adjustForColumns) const
1928 {
1929     LayoutRect rect = roundedRect;
1930     convertToLayerCoords(ancestorLayer, rect, adjustForColumns);
1931     roundedRect = pixelSnappedIntRect(rect);
1932 }
1933
1934 // Returns the layer reached on the walk up towards the ancestor.
1935 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location, RenderLayer::ColumnOffsetAdjustment adjustForColumns)
1936 {
1937     ASSERT(ancestorLayer != layer);
1938
1939     const RenderLayerModelObject& renderer = layer->renderer();
1940     EPosition position = renderer.style().position();
1941
1942     // FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great.
1943     RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer.flowThreadContainingBlock() : 0;
1944     if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned())
1945         fixedFlowThreadContainer = 0;
1946
1947     // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
1948     // may need to be revisited in a future patch.
1949     // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
1950     // since localToAbsolute maps the coordinates from named flow to regions coordinates and regions can be
1951     // positioned in a completely different place in the viewport (RenderView).
1952     if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer.view().layer())) {
1953         // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
1954         // localToAbsolute() on the RenderView.
1955         FloatPoint absPos = renderer.localToAbsolute(FloatPoint(), IsFixed);
1956         location += LayoutSize(absPos.x(), absPos.y());
1957         return ancestorLayer;
1958     }
1959
1960     // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
1961     // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
1962     // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
1963     if (position == FixedPosition && !fixedFlowThreadContainer) {
1964         // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
1965         // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
1966         // so we should always find the ancestor at or before we find the fixed position container.
1967         RenderLayer* fixedPositionContainerLayer = 0;
1968         bool foundAncestor = false;
1969         for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
1970             if (currLayer == ancestorLayer)
1971                 foundAncestor = true;
1972
1973             if (isFixedPositionedContainer(currLayer)) {
1974                 fixedPositionContainerLayer = currLayer;
1975                 ASSERT_UNUSED(foundAncestor, foundAncestor);
1976                 break;
1977             }
1978         }
1979         
1980         ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
1981
1982         if (fixedPositionContainerLayer != ancestorLayer) {
1983             LayoutPoint fixedContainerCoords;
1984             layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
1985
1986             LayoutPoint ancestorCoords;
1987             ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
1988
1989             location += (fixedContainerCoords - ancestorCoords);
1990             return ancestorLayer;
1991         }
1992     }
1993
1994     if (position == FixedPosition && fixedFlowThreadContainer) {
1995         ASSERT(ancestorLayer);
1996         if (ancestorLayer->isOutOfFlowRenderFlowThread()) {
1997             location += toSize(layer->location());
1998             return ancestorLayer;
1999         }
2000
2001         if (ancestorLayer == renderer.view().layer()) {
2002             // Add location in flow thread coordinates.
2003             location += toSize(layer->location());
2004
2005             // Add flow thread offset in view coordinates since the view may be scrolled.
2006             FloatPoint absPos = renderer.view().localToAbsolute(FloatPoint(), IsFixed);
2007             location += LayoutSize(absPos.x(), absPos.y());
2008             return ancestorLayer;
2009         }
2010     }
2011
2012     RenderLayer* parentLayer;
2013     if (position == AbsolutePosition || position == FixedPosition) {
2014         // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
2015         parentLayer = layer->parent();
2016         bool foundAncestorFirst = false;
2017         while (parentLayer) {
2018             // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0).
2019             // This implies that, for out-of-flow positioned elements inside a RenderFlowThread,
2020             // we are bailing out before reaching root layer.
2021             if (isPositionedContainer(parentLayer))
2022                 break;
2023
2024             if (parentLayer == ancestorLayer) {
2025                 foundAncestorFirst = true;
2026                 break;
2027             }
2028
2029             parentLayer = parentLayer->parent();
2030         }
2031
2032         // We should not reach RenderView layer past the RenderFlowThread layer for any
2033         // children of the RenderFlowThread.
2034         if (renderer.flowThreadContainingBlock() && !layer->isOutOfFlowRenderFlowThread())
2035             ASSERT(parentLayer != renderer.view().layer());
2036
2037         if (foundAncestorFirst) {
2038             // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
2039             // to enclosingPositionedAncestor and subtract.
2040             RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
2041
2042             LayoutPoint thisCoords;
2043             layer->convertToLayerCoords(positionedAncestor, thisCoords);
2044             
2045             LayoutPoint ancestorCoords;
2046             ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
2047
2048             location += (thisCoords - ancestorCoords);
2049             return ancestorLayer;
2050         }
2051     } else
2052         parentLayer = layer->parent();
2053     
2054     if (!parentLayer)
2055         return 0;
2056
2057     location += toSize(layer->location());
2058
2059     if (adjustForColumns == RenderLayer::AdjustForColumns) {
2060         if (RenderLayer* parentLayer = layer->parent()) {
2061             LayoutSize layerColumnOffset;
2062             parentLayer->renderer().adjustForColumns(layerColumnOffset, location);
2063             location += layerColumnOffset;
2064         }
2065     }
2066
2067     return parentLayer;
2068 }
2069
2070 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location, ColumnOffsetAdjustment adjustForColumns) const
2071 {
2072     if (ancestorLayer == this)
2073         return;
2074
2075     const RenderLayer* currLayer = this;
2076     while (currLayer && currLayer != ancestorLayer)
2077         currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, location, adjustForColumns);
2078 }
2079
2080 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect, ColumnOffsetAdjustment adjustForColumns) const
2081 {
2082     LayoutPoint delta;
2083     convertToLayerCoords(ancestorLayer, delta, adjustForColumns);
2084     rect.move(-delta.x(), -delta.y());
2085 }
2086
2087 #if USE(ACCELERATED_COMPOSITING)
2088
2089 bool RenderLayer::usesCompositedScrolling() const
2090 {
2091     return isComposited() && backing()->scrollingLayer();
2092 }
2093
2094 bool RenderLayer::needsCompositedScrolling() const
2095 {
2096     return m_needsCompositedScrolling;
2097 }
2098
2099 void RenderLayer::updateNeedsCompositedScrolling()
2100 {
2101     bool oldNeedsCompositedScrolling = m_needsCompositedScrolling;
2102
2103     if (!renderer().view().frameView().containsScrollableArea(this))
2104         m_needsCompositedScrolling = false;
2105     else {
2106         bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScrollEnabled()
2107             && canBeStackingContainer()
2108             && !hasOutOfFlowPositionedDescendant();
2109
2110 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2111         m_needsCompositedScrolling = forceUseCompositedScrolling || renderer().style().useTouchOverflowScrolling();
2112 #else
2113         m_needsCompositedScrolling = forceUseCompositedScrolling;
2114 #endif
2115         // We gather a boolean value for use with Google UMA histograms to
2116         // quantify the actual effects of a set of patches attempting to
2117         // relax composited scrolling requirements, thereby increasing the
2118         // number of composited overflow divs.
2119         if (acceleratedCompositingForOverflowScrollEnabled())
2120             HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScrolling", m_needsCompositedScrolling, 2);
2121     }
2122
2123     if (oldNeedsCompositedScrolling != m_needsCompositedScrolling) {
2124         updateSelfPaintingLayer();
2125         if (isStackingContainer())
2126             dirtyZOrderLists();
2127         else
2128             clearZOrderLists();
2129
2130         dirtyStackingContainerZOrderLists();
2131
2132         compositor().setShouldReevaluateCompositingAfterLayout();
2133         compositor().setCompositingLayersNeedRebuild();
2134     }
2135 }
2136
2137 #endif
2138
2139 static inline int adjustedScrollDelta(int beginningDelta) {
2140     // This implemention matches Firefox's.
2141     // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856.
2142     const int speedReducer = 12;
2143
2144     int adjustedDelta = beginningDelta / speedReducer;
2145     if (adjustedDelta > 1)
2146         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(adjustedDelta))) - 1;
2147     else if (adjustedDelta < -1)
2148         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(-adjustedDelta))) + 1;
2149
2150     return adjustedDelta;
2151 }
2152
2153 static inline IntSize adjustedScrollDelta(const IntSize& delta)
2154 {
2155     return IntSize(adjustedScrollDelta(delta.width()), adjustedScrollDelta(delta.height()));
2156 }
2157
2158 void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
2159 {
2160     IntPoint lastKnownMousePosition = renderer().frame().eventHandler().lastKnownMousePosition();
2161     
2162     // We need to check if the last known mouse position is out of the window. When the mouse is out of the window, the position is incoherent
2163     static IntPoint previousMousePosition;
2164     if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0)
2165         lastKnownMousePosition = previousMousePosition;
2166     else
2167         previousMousePosition = lastKnownMousePosition;
2168
2169     IntSize delta = lastKnownMousePosition - sourcePoint;
2170
2171     if (abs(delta.width()) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon
2172         delta.setWidth(0);
2173     if (abs(delta.height()) <= ScrollView::noPanScrollRadius)
2174         delta.setHeight(0);
2175
2176     scrollByRecursively(adjustedScrollDelta(delta), ScrollOffsetClamped);
2177 }
2178
2179 void RenderLayer::scrollByRecursively(const IntSize& delta, ScrollOffsetClamping clamp, ScrollableArea** scrolledArea)
2180 {
2181     if (delta.isZero())
2182         return;
2183
2184     bool restrictedByLineClamp = false;
2185     if (renderer().parent())
2186         restrictedByLineClamp = !renderer().parent()->style().lineClamp().isNone();
2187
2188     if (renderer().hasOverflowClip() && !restrictedByLineClamp) {
2189         IntSize newScrollOffset = scrollOffset() + delta;
2190         scrollToOffset(newScrollOffset, clamp);
2191         if (scrolledArea)
2192             *scrolledArea = this;
2193
2194         // If this layer can't do the scroll we ask the next layer up that can scroll to try
2195         IntSize remainingScrollOffset = newScrollOffset - scrollOffset();
2196         if (!remainingScrollOffset.isZero() && renderer().parent()) {
2197             if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
2198                 scrollableLayer->scrollByRecursively(remainingScrollOffset, clamp, scrolledArea);
2199
2200             renderer().frame().eventHandler().updateAutoscrollRenderer();
2201         }
2202     } else {
2203         // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
2204         // have an overflow clip. Which means that it is a document node that can be scrolled.
2205         renderer().view().frameView().scrollBy(delta);
2206         if (scrolledArea)
2207             *scrolledArea = &renderer().view().frameView();
2208
2209         // FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement? 
2210         // https://bugs.webkit.org/show_bug.cgi?id=28237
2211     }
2212 }
2213
2214 IntSize RenderLayer::clampScrollOffset(const IntSize& scrollOffset) const
2215 {
2216     RenderBox* box = renderBox();
2217     ASSERT(box);
2218
2219     int maxX = scrollWidth() - box->pixelSnappedClientWidth();
2220     int maxY = scrollHeight() - box->pixelSnappedClientHeight();
2221
2222     int x = std::max(std::min(scrollOffset.width(), maxX), 0);
2223     int y = std::max(std::min(scrollOffset.height(), maxY), 0);
2224     return IntSize(x, y);
2225 }
2226
2227 void RenderLayer::scrollToOffset(const IntSize& scrollOffset, ScrollOffsetClamping clamp)
2228 {
2229     IntSize newScrollOffset = clamp == ScrollOffsetClamped ? clampScrollOffset(scrollOffset) : scrollOffset;
2230     if (newScrollOffset != this->scrollOffset())
2231         scrollToOffsetWithoutAnimation(IntPoint(newScrollOffset));
2232 }
2233
2234 void RenderLayer::scrollTo(int x, int y)
2235 {
2236     RenderBox* box = renderBox();
2237     if (!box)
2238         return;
2239
2240     if (box->style().overflowX() != OMARQUEE) {
2241         // Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
2242         if (m_scrollDimensionsDirty)
2243             computeScrollDimensions();
2244     }
2245     
2246     // FIXME: Eventually, we will want to perform a blit.  For now never
2247     // blit, since the check for blitting is going to be very
2248     // complicated (since it will involve testing whether our layer
2249     // is either occluded by another layer or clipped by an enclosing
2250     // layer or contains fixed backgrounds, etc.).
2251     IntSize newScrollOffset = IntSize(x - scrollOrigin().x(), y - scrollOrigin().y());
2252     if (m_scrollOffset == newScrollOffset)
2253         return;
2254     m_scrollOffset = newScrollOffset;
2255
2256     InspectorInstrumentation::willScrollLayer(&renderer().frame());
2257
2258     RenderView& view = renderer().view();
2259
2260     // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
2261     // We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
2262     bool inLayout = view.frameView().isInLayout();
2263     if (!inLayout) {
2264         // If we're in the middle of layout, we'll just update layers once layout has finished.
2265         updateLayerPositionsAfterOverflowScroll();
2266         // Update regions, scrolling may change the clip of a particular region.
2267 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
2268         view.frameView().updateAnnotatedRegions();
2269 #endif
2270         view.frameView().updateWidgetPositions();
2271
2272         if (!m_updatingMarqueePosition) {
2273             // Avoid updating compositing layers if, higher on the stack, we're already updating layer
2274             // positions. Updating layer positions requires a full walk of up-to-date RenderLayers, and
2275             // in this case we're still updating their positions; we'll update compositing layers later
2276             // when that completes.
2277             updateCompositingLayersAfterScroll();
2278         }
2279     }
2280
2281     Frame& frame = renderer().frame();
2282     RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
2283     // The caret rect needs to be invalidated after scrolling
2284     frame.selection().setCaretRectNeedsUpdate();
2285
2286     FloatQuad quadForFakeMouseMoveEvent = FloatQuad(m_repaintRect);
2287     if (repaintContainer)
2288         quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
2289     frame.eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
2290
2291     bool requiresRepaint = true;
2292
2293 #if USE(ACCELERATED_COMPOSITING)
2294     if (compositor().inCompositingMode() && usesCompositedScrolling())
2295         requiresRepaint = false;
2296 #endif
2297
2298     // Just schedule a full repaint of our object.
2299     if (requiresRepaint)
2300         renderer().repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect));
2301
2302     // Schedule the scroll DOM event.
2303     if (Element* element = renderer().element())
2304         element->document().eventQueue().enqueueOrDispatchScrollEvent(*element);
2305
2306     InspectorInstrumentation::didScrollLayer(&frame);
2307     if (scrollsOverflow())
2308         frame.loader().client().didChangeScrollOffset();
2309 }
2310
2311 static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameElementBase, FrameView* frameView) 
2312 {
2313     // If scrollbars aren't explicitly forbidden, permit scrolling.
2314     if (frameElementBase && frameElementBase->scrollingMode() != ScrollbarAlwaysOff)
2315         return true;
2316
2317     // If scrollbars are forbidden, user initiated scrolls should obviously be ignored.
2318     if (frameView->wasScrolledByUser())
2319         return false;
2320
2321     // Forbid autoscrolls when scrollbars are off, but permits other programmatic scrolls,
2322     // like navigation to an anchor.
2323     return !frameView->frame().eventHandler().autoscrollInProgress();
2324 }
2325
2326 void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
2327 {
2328     RenderLayer* parentLayer = 0;
2329     LayoutRect newRect = rect;
2330
2331     // We may end up propagating a scroll event. It is important that we suspend events until 
2332     // the end of the function since they could delete the layer or the layer's renderer().
2333     FrameView& frameView = renderer().view().frameView();
2334     frameView.pauseScheduledEvents();
2335
2336     bool restrictedByLineClamp = false;
2337     if (renderer().parent()) {
2338         parentLayer = renderer().parent()->enclosingLayer();
2339         restrictedByLineClamp = !renderer().parent()->style().lineClamp().isNone();
2340     }
2341
2342     if (renderer().hasOverflowClip() && !restrictedByLineClamp) {
2343         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
2344         // This will prevent us from revealing text hidden by the slider in Safari RSS.
2345         RenderBox* box = renderBox();
2346         ASSERT(box);
2347         LayoutRect localExposeRect(box->absoluteToLocalQuad(FloatQuad(FloatRect(rect)), UseTransforms).boundingBox());
2348         LayoutRect layerBounds(0, 0, box->clientWidth(), box->clientHeight());
2349         LayoutRect r = getRectToExpose(layerBounds, layerBounds, localExposeRect, alignX, alignY);
2350
2351         IntSize clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(r).location()));
2352         if (clampedScrollOffset != scrollOffset()) {
2353             IntSize oldScrollOffset = scrollOffset();
2354             scrollToOffset(clampedScrollOffset);
2355             IntSize scrollOffsetDifference = scrollOffset() - oldScrollOffset;
2356             localExposeRect.move(-scrollOffsetDifference);
2357             newRect = LayoutRect(box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
2358         }
2359     } else if (!parentLayer && renderer().isBox() && renderBox()->canBeProgramaticallyScrolled()) {
2360         Element* ownerElement = renderer().document().ownerElement();
2361
2362         if (ownerElement && ownerElement->renderer()) {
2363             HTMLFrameElementBase* frameElementBase = 0;
2364
2365             if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))
2366                 frameElementBase = toHTMLFrameElementBase(ownerElement);
2367
2368             if (frameElementAndViewPermitScroll(frameElementBase, &frameView)) {
2369                 LayoutRect viewRect = frameView.visibleContentRect();
2370                 LayoutRect exposeRect = getRectToExpose(viewRect, viewRect, rect, alignX, alignY);
2371
2372                 int xOffset = roundToInt(exposeRect.x());
2373                 int yOffset = roundToInt(exposeRect.y());
2374                 // Adjust offsets if they're outside of the allowable range.
2375                 xOffset = std::max(0, std::min(frameView.contentsWidth(), xOffset));
2376                 yOffset = std::max(0, std::min(frameView.contentsHeight(), yOffset));
2377
2378                 frameView.setScrollPosition(IntPoint(xOffset, yOffset));
2379                 if (frameView.safeToPropagateScrollToParent()) {
2380                     parentLayer = ownerElement->renderer()->enclosingLayer();
2381                     // FIXME: This doesn't correctly convert the rect to
2382                     // absolute coordinates in the parent.
2383                     newRect.setX(rect.x() - frameView.scrollX() + frameView.x());
2384                     newRect.setY(rect.y() - frameView.scrollY() + frameView.y());
2385                 } else
2386                     parentLayer = 0;
2387             }
2388         } else {
2389             LayoutRect viewRect = frameView.visibleContentRect();
2390             LayoutRect visibleRectRelativeToDocument = viewRect;
2391             IntSize scrollOffsetRelativeToDocument = frameView.scrollOffsetRelativeToDocument();
2392             visibleRectRelativeToDocument.setLocation(IntPoint(scrollOffsetRelativeToDocument.width(), scrollOffsetRelativeToDocument.height()));
2393
2394             LayoutRect r = getRectToExpose(viewRect, visibleRectRelativeToDocument, rect, alignX, alignY);
2395                 
2396             frameView.setScrollPosition(roundedIntPoint(r.location()));
2397
2398             // This is the outermost view of a web page, so after scrolling this view we
2399             // scroll its container by calling Page::scrollRectIntoView.
2400             // This only has an effect on the Mac platform in applications
2401             // that put web views into scrolling containers, such as Mac OS X Mail.
2402             // The canAutoscroll function in EventHandler also knows about this.
2403             if (Page* page = frameView.frame().page())
2404                 page->chrome().scrollRectIntoView(pixelSnappedIntRect(rect));
2405         }
2406     }
2407     
2408     if (renderer().frame().eventHandler().autoscrollInProgress())
2409         parentLayer = enclosingScrollableLayer();
2410
2411     if (parentLayer)
2412         parentLayer->scrollRectToVisible(newRect, alignX, alignY);
2413
2414     frameView.resumeScheduledEvents();
2415 }
2416
2417 void RenderLayer::updateCompositingLayersAfterScroll()
2418 {
2419 #if USE(ACCELERATED_COMPOSITING)
2420     if (compositor().inCompositingMode()) {
2421         // Our stacking container is guaranteed to contain all of our descendants that may need
2422         // repositioning, so update compositing layers from there.
2423         if (RenderLayer* compositingAncestor = stackingContainer()->enclosingCompositingLayer()) {
2424             if (usesCompositedScrolling() && !hasOutOfFlowPositionedDescendant())
2425                 compositor().updateCompositingLayers(CompositingUpdateOnCompositedScroll, compositingAncestor);
2426             else
2427                 compositor().updateCompositingLayers(CompositingUpdateOnScroll, compositingAncestor);
2428         }
2429     }
2430 #endif
2431 }
2432
2433 LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const LayoutRect &visibleRectRelativeToDocument, const LayoutRect &exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
2434 {
2435     // Determine the appropriate X behavior.
2436     ScrollBehavior scrollX;
2437     LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
2438     LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width();
2439     if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
2440         // If the rectangle is fully visible, use the specified visible behavior.
2441         // If the rectangle is partially visible, but over a certain threshold,
2442         // then treat it as fully visible to avoid unnecessary horizontal scrolling
2443         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2444     else if (intersectWidth == visibleRect.width()) {
2445         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2446         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2447         if (scrollX == alignCenter)
2448             scrollX = noScroll;
2449     } else if (intersectWidth > 0)
2450         // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
2451         scrollX = ScrollAlignment::getPartialBehavior(alignX);
2452     else
2453         scrollX = ScrollAlignment::getHiddenBehavior(alignX);
2454     // If we're trying to align to the closest edge, and the exposeRect is further right
2455     // than the visibleRect, and not bigger than the visible area, then align with the right.
2456     if (scrollX == alignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
2457         scrollX = alignRight;
2458
2459     // Given the X behavior, compute the X coordinate.
2460     LayoutUnit x;
2461     if (scrollX == noScroll) 
2462         x = visibleRect.x();
2463     else if (scrollX == alignRight)
2464         x = exposeRect.maxX() - visibleRect.width();
2465     else if (scrollX == alignCenter)
2466         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
2467     else
2468         x = exposeRect.x();
2469
2470     // Determine the appropriate Y behavior.
2471     ScrollBehavior scrollY;
2472     LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
2473     LayoutUnit intersectHeight = intersection(visibleRectRelativeToDocument, exposeRectY).height();
2474     if (intersectHeight == exposeRect.height())
2475         // If the rectangle is fully visible, use the specified visible behavior.
2476         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2477     else if (intersectHeight == visibleRect.height()) {
2478         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2479         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2480         if (scrollY == alignCenter)
2481             scrollY = noScroll;
2482     } else if (intersectHeight > 0)
2483         // If the rectangle is partially visible, use the specified partial behavior
2484         scrollY = ScrollAlignment::getPartialBehavior(alignY);
2485     else
2486         scrollY = ScrollAlignment::getHiddenBehavior(alignY);
2487     // If we're trying to align to the closest edge, and the exposeRect is further down
2488     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
2489     if (scrollY == alignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
2490         scrollY = alignBottom;
2491
2492     // Given the Y behavior, compute the Y coordinate.
2493     LayoutUnit y;
2494     if (scrollY == noScroll) 
2495         y = visibleRect.y();
2496     else if (scrollY == alignBottom)
2497         y = exposeRect.maxY() - visibleRect.height();
2498     else if (scrollY == alignCenter)
2499         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
2500     else
2501         y = exposeRect.y();
2502
2503     return LayoutRect(LayoutPoint(x, y), visibleRect.size());
2504 }
2505
2506 void RenderLayer::autoscroll(const IntPoint& position)
2507 {
2508     IntPoint currentDocumentPosition = renderer().view().frameView().windowToContents(position);
2509     scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
2510 }
2511
2512 bool RenderLayer::canResize() const
2513 {
2514     // We need a special case for <iframe> because they never have
2515     // hasOverflowClip(). However, they do "implicitly" clip their contents, so
2516     // we want to allow resizing them also.
2517     return (renderer().hasOverflowClip() || renderer().isRenderIFrame()) && renderer().style().resize() != RESIZE_NONE;
2518 }
2519
2520 void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOffset)
2521 {
2522     // FIXME: This should be possible on generated content but is not right now.
2523     if (!inResizeMode() || !canResize() || !renderer().element())
2524         return;
2525
2526     // FIXME: The only case where renderer->element()->renderer() != renderer is with continuations. Do they matter here?
2527     // If they do it would still be better to deal with them explicitly.
2528     Element* element = renderer().element();
2529     RenderBox* renderer = toRenderBox(element->renderer());
2530
2531     Document& document = element->document();
2532     if (!document.frame()->eventHandler().mousePressed())
2533         return;
2534
2535     float zoomFactor = renderer->style().effectiveZoom();
2536
2537     LayoutSize newOffset = offsetFromResizeCorner(document.view()->windowToContents(evt.position()));
2538     newOffset.setWidth(newOffset.width() / zoomFactor);
2539     newOffset.setHeight(newOffset.height() / zoomFactor);
2540     
2541     LayoutSize currentSize = LayoutSize(renderer->width() / zoomFactor, renderer->height() / zoomFactor);
2542     LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
2543     element->setMinimumSizeForResizing(minimumSize);
2544     
2545     LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
2546     if (renderer->style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
2547         newOffset.setWidth(-newOffset.width());
2548         adjustedOldOffset.setWidth(-adjustedOldOffset.width());
2549     }
2550     
2551     LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
2552
2553     ASSERT_WITH_SECURITY_IMPLICATION(element->isStyledElement());
2554     StyledElement* styledElement = static_cast<StyledElement*>(element);
2555     bool isBoxSizingBorder = renderer->style().boxSizing() == BORDER_BOX;
2556
2557     EResize resize = renderer->style().resize();
2558     if (resize != RESIZE_VERTICAL && difference.width()) {
2559         if (element->isFormControlElement()) {
2560             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2561             styledElement->setInlineStyleProperty(CSSPropertyMarginLeft, renderer->marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2562             styledElement->setInlineStyleProperty(CSSPropertyMarginRight, renderer->marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2563         }
2564         LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? LayoutUnit() : renderer->borderAndPaddingWidth());
2565         baseWidth = baseWidth / zoomFactor;
2566         styledElement->setInlineStyleProperty(CSSPropertyWidth, roundToInt(baseWidth + difference.width()), CSSPrimitiveValue::CSS_PX);
2567     }
2568
2569     if (resize != RESIZE_HORIZONTAL && difference.height()) {
2570         if (element->isFormControlElement()) {
2571             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2572             styledElement->setInlineStyleProperty(CSSPropertyMarginTop, renderer->marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2573             styledElement->setInlineStyleProperty(CSSPropertyMarginBottom, renderer->marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2574         }
2575         LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? LayoutUnit() : renderer->borderAndPaddingHeight());
2576         baseHeight = baseHeight / zoomFactor;
2577         styledElement->setInlineStyleProperty(CSSPropertyHeight, roundToInt(baseHeight + difference.height()), CSSPrimitiveValue::CSS_PX);
2578     }
2579
2580     document.updateLayout();
2581
2582     // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
2583 }
2584
2585 int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
2586 {
2587     Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
2588     return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
2589 }
2590
2591 void RenderLayer::setScrollOffset(const IntPoint& offset)
2592 {
2593     scrollTo(offset.x(), offset.y());
2594 }
2595
2596 int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
2597 {
2598     if (scrollbar->orientation() == HorizontalScrollbar)
2599         return scrollXOffset();
2600     if (scrollbar->orientation() == VerticalScrollbar)
2601         return scrollYOffset();
2602     return 0;
2603 }
2604
2605 IntPoint RenderLayer::scrollPosition() const
2606 {
2607     return IntPoint(m_scrollOffset);
2608 }
2609
2610 IntPoint RenderLayer::minimumScrollPosition() const
2611 {
2612     return -scrollOrigin();
2613 }
2614
2615 IntPoint RenderLayer::maximumScrollPosition() const
2616 {
2617     // FIXME: m_scrollSize may not be up-to-date if m_scrollDimensionsDirty is true.
2618     return -scrollOrigin() + roundedIntSize(m_scrollSize) - visibleContentRect(IncludeScrollbars).size();
2619 }
2620
2621 IntRect RenderLayer::visibleContentRect(VisibleContentRectIncludesScrollbars scrollbarInclusion) const
2622 {
2623     int verticalScrollbarWidth = 0;
2624     int horizontalScrollbarHeight = 0;
2625     if (scrollbarInclusion == IncludeScrollbars) {
2626         verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar()) ? verticalScrollbar()->width() : 0;
2627         horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar()) ? horizontalScrollbar()->height() : 0;
2628     }
2629     
2630     return IntRect(IntPoint(scrollXOffset(), scrollYOffset()),
2631                    IntSize(std::max(0, m_layerSize.width() - verticalScrollbarWidth),
2632                            std::max(0, m_layerSize.height() - horizontalScrollbarHeight)));
2633 }
2634
2635 IntSize RenderLayer::overhangAmount() const
2636 {
2637     return IntSize();
2638 }
2639
2640 bool RenderLayer::isActive() const
2641 {
2642     Page* page = renderer().frame().page();
2643     return page && page->focusController().isActive();
2644 }
2645
2646 static int cornerStart(const RenderLayer* layer, int minX, int maxX, int thickness)
2647 {
2648     if (layer->renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2649         return minX + layer->renderer().style().borderLeftWidth();
2650     return maxX - thickness - layer->renderer().style().borderRightWidth();
2651 }
2652
2653 static IntRect cornerRect(const RenderLayer* layer, const IntRect& bounds)
2654 {
2655     int horizontalThickness;
2656     int verticalThickness;
2657     if (!layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
2658         // FIXME: This isn't right.  We need to know the thickness of custom scrollbars
2659         // even when they don't exist in order to set the resizer square size properly.
2660         horizontalThickness = ScrollbarTheme::theme()->scrollbarThickness();
2661         verticalThickness = horizontalThickness;
2662     } else if (layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
2663         horizontalThickness = layer->verticalScrollbar()->width();
2664         verticalThickness = horizontalThickness;
2665     } else if (layer->horizontalScrollbar() && !layer->verticalScrollbar()) {
2666         verticalThickness = layer->horizontalScrollbar()->height();
2667         horizontalThickness = verticalThickness;
2668     } else {
2669         horizontalThickness = layer->verticalScrollbar()->width();
2670         verticalThickness = layer->horizontalScrollbar()->height();
2671     }
2672     return IntRect(cornerStart(layer, bounds.x(), bounds.maxX(), horizontalThickness),
2673         bounds.maxY() - verticalThickness - layer->renderer().style().borderBottomWidth(),
2674         horizontalThickness, verticalThickness);
2675 }
2676
2677 IntRect RenderLayer::scrollCornerRect() const
2678 {
2679     // We have a scrollbar corner when a scrollbar is visible and not filling the entire length of the box.
2680     // This happens when:
2681     // (a) A resizer is present and at least one scrollbar is present
2682     // (b) Both scrollbars are present.
2683     bool hasHorizontalBar = horizontalScrollbar();
2684     bool hasVerticalBar = verticalScrollbar();
2685     bool hasResizer = renderer().style().resize() != RESIZE_NONE;
2686     if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
2687         return cornerRect(this, renderBox()->pixelSnappedBorderBoxRect());
2688     return IntRect();
2689 }
2690
2691 static IntRect resizerCornerRect(const RenderLayer* layer, const IntRect& bounds)
2692 {
2693     ASSERT(layer->renderer().isBox());
2694     if (layer->renderer().style().resize() == RESIZE_NONE)
2695         return IntRect();
2696     return cornerRect(layer, bounds);
2697 }
2698
2699 IntRect RenderLayer::scrollCornerAndResizerRect() const
2700 {
2701     RenderBox* box = renderBox();
2702     if (!box)
2703         return IntRect();
2704     IntRect scrollCornerAndResizer = scrollCornerRect();
2705     if (scrollCornerAndResizer.isEmpty())
2706         scrollCornerAndResizer = resizerCornerRect(this, box->pixelSnappedBorderBoxRect());
2707     return scrollCornerAndResizer;
2708 }
2709
2710 bool RenderLayer::isScrollCornerVisible() const
2711 {
2712     ASSERT(renderer().isBox());
2713     return !scrollCornerRect().isEmpty();
2714 }
2715
2716 IntRect RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
2717 {
2718     IntRect rect = scrollbarRect;
2719     rect.move(scrollbarOffset(scrollbar));
2720
2721     return renderer().view().frameView().convertFromRenderer(&renderer(), rect);
2722 }
2723
2724 IntRect RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
2725 {
2726     IntRect rect = renderer().view().frameView().convertToRenderer(&renderer(), parentRect);
2727     rect.move(-scrollbarOffset(scrollbar));
2728     return rect;
2729 }
2730
2731 IntPoint RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
2732 {
2733     IntPoint point = scrollbarPoint;
2734     point.move(scrollbarOffset(scrollbar));
2735     return renderer().view().frameView().convertFromRenderer(&renderer(), point);
2736 }
2737
2738 IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
2739 {
2740     IntPoint point = renderer().view().frameView().convertToRenderer(&renderer(), parentPoint);
2741     point.move(-scrollbarOffset(scrollbar));
2742     return point;
2743 }
2744
2745 IntSize RenderLayer::contentsSize() const
2746 {
2747     return IntSize(scrollWidth(), scrollHeight());
2748 }
2749
2750 int RenderLayer::visibleHeight() const
2751 {
2752     return m_layerSize.height();
2753 }
2754
2755 int RenderLayer::visibleWidth() const
2756 {
2757     return m_layerSize.width();
2758 }
2759
2760 bool RenderLayer::shouldSuspendScrollAnimations() const
2761 {
2762     return renderer().view().frameView().shouldSuspendScrollAnimations();
2763 }
2764
2765 IntPoint RenderLayer::lastKnownMousePosition() const
2766 {
2767     return renderer().frame().eventHandler().lastKnownMousePosition();
2768 }
2769
2770 bool RenderLayer::isHandlingWheelEvent() const
2771 {
2772     return renderer().frame().eventHandler().isHandlingWheelEvent();
2773 }
2774
2775 IntRect RenderLayer::rectForHorizontalScrollbar(const IntRect& borderBoxRect) const
2776 {
2777     if (!m_hBar)
2778         return IntRect();
2779
2780     const RenderBox* box = renderBox();
2781     const IntRect& scrollCorner = scrollCornerRect();
2782
2783     return IntRect(horizontalScrollbarStart(borderBoxRect.x()),
2784         borderBoxRect.maxY() - box->borderBottom() - m_hBar->height(),
2785         borderBoxRect.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
2786         m_hBar->height());
2787 }
2788
2789 IntRect RenderLayer::rectForVerticalScrollbar(const IntRect& borderBoxRect) const
2790 {
2791     if (!m_vBar)
2792         return IntRect();
2793
2794     const RenderBox* box = renderBox();
2795     const IntRect& scrollCorner = scrollCornerRect();
2796
2797     return IntRect(verticalScrollbarStart(borderBoxRect.x(), borderBoxRect.maxX()),
2798         borderBoxRect.y() + box->borderTop(),
2799         m_vBar->width(),
2800         borderBoxRect.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height());
2801 }
2802
2803 LayoutUnit RenderLayer::verticalScrollbarStart(int minX, int maxX) const
2804 {
2805     const RenderBox* box = renderBox();
2806     if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2807         return minX + box->borderLeft();
2808     return maxX - box->borderRight() - m_vBar->width();
2809 }
2810
2811 LayoutUnit RenderLayer::horizontalScrollbarStart(int minX) const
2812 {
2813     const RenderBox* box = renderBox();
2814     int x = minX + box->borderLeft();
2815     if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2816         x += m_vBar ? m_vBar->width() : resizerCornerRect(this, box->pixelSnappedBorderBoxRect()).width();
2817     return x;
2818 }
2819
2820 IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
2821 {
2822     RenderBox* box = renderBox();
2823
2824     if (scrollbar == m_vBar.get())
2825         return IntSize(verticalScrollbarStart(0, box->width()), box->borderTop());
2826
2827     if (scrollbar == m_hBar.get())
2828         return IntSize(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar->height());
2829     
2830     ASSERT_NOT_REACHED();
2831     return IntSize();
2832 }
2833
2834 void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
2835 {
2836 #if USE(ACCELERATED_COMPOSITING)
2837     if (scrollbar == m_vBar.get()) {
2838         if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
2839             layer->setNeedsDisplayInRect(rect);
2840             return;
2841         }
2842     } else {
2843         if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
2844             layer->setNeedsDisplayInRect(rect);
2845             return;
2846         }
2847     }
2848 #endif
2849     IntRect scrollRect = rect;
2850     RenderBox* box = renderBox();
2851     ASSERT(box);
2852     // If we are not yet inserted into the tree, there is no need to repaint.
2853     if (!box->parent())
2854         return;
2855
2856     if (scrollbar == m_vBar.get())
2857         scrollRect.move(verticalScrollbarStart(0, box->width()), box->borderTop());
2858     else
2859         scrollRect.move(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar->height());
2860     LayoutRect repaintRect = scrollRect;
2861     renderBox()->flipForWritingMode(repaintRect);
2862     renderer().repaintRectangle(repaintRect);
2863 }
2864
2865 void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
2866 {
2867 #if USE(ACCELERATED_COMPOSITING)
2868     if (GraphicsLayer* layer = layerForScrollCorner()) {
2869         layer->setNeedsDisplayInRect(rect);
2870         return;
2871     }
2872 #endif
2873     if (m_scrollCorner)
2874         m_scrollCorner->repaintRectangle(rect);
2875     if (m_resizer)
2876         m_resizer->repaintRectangle(rect);
2877 }
2878
2879 static inline RenderElement* rendererForScrollbar(RenderLayerModelObject& renderer)
2880 {
2881     if (Element* element = renderer.element()) {
2882         if (ShadowRoot* shadowRoot = element->containingShadowRoot()) {
2883             if (shadowRoot->type() == ShadowRoot::UserAgentShadowRoot)
2884                 return shadowRoot->hostElement()->renderer();
2885         }
2886     }
2887
2888     return &renderer;
2889 }
2890
2891 PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
2892 {
2893     RefPtr<Scrollbar> widget;
2894     RenderElement* actualRenderer = rendererForScrollbar(renderer());
2895     bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style().hasPseudoStyle(SCROLLBAR);
2896     if (hasCustomScrollbarStyle)
2897         widget = RenderScrollbar::createCustomScrollbar(this, orientation, actualRenderer->element());
2898     else {
2899         widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
2900         didAddScrollbar(widget.get(), orientation);
2901     }
2902     renderer().view().frameView().addChild(widget.get());
2903     return widget.release();
2904 }
2905
2906 void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
2907 {
2908     RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
2909     if (!scrollbar)
2910         return;
2911
2912     if (!scrollbar->isCustomScrollbar())
2913         willRemoveScrollbar(scrollbar.get(), orientation);
2914
2915     scrollbar->removeFromParent();
2916     scrollbar->disconnectFromScrollableArea();
2917     scrollbar = 0;
2918 }
2919
2920 bool RenderLayer::scrollsOverflow() const
2921 {
2922     if (!renderer().isBox())
2923         return false;
2924
2925     return toRenderBox(renderer()).scrollsOverflow();
2926 }
2927
2928 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
2929 {
2930     if (hasScrollbar == hasHorizontalScrollbar())
2931         return;
2932
2933     if (hasScrollbar)
2934         m_hBar = createScrollbar(HorizontalScrollbar);
2935     else
2936         destroyScrollbar(HorizontalScrollbar);
2937
2938     // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
2939     if (m_hBar)
2940         m_hBar->styleChanged();
2941     if (m_vBar)
2942         m_vBar->styleChanged();
2943
2944     // Force an update since we know the scrollbars have changed things.
2945 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
2946     if (renderer().document().hasAnnotatedRegions())
2947         renderer().document().setAnnotatedRegionsDirty(true);
2948 #endif
2949 }
2950
2951 void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
2952 {
2953     if (hasScrollbar == hasVerticalScrollbar())
2954         return;
2955
2956     if (hasScrollbar)
2957         m_vBar = createScrollbar(VerticalScrollbar);
2958     else
2959         destroyScrollbar(VerticalScrollbar);
2960
2961      // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
2962     if (m_hBar)
2963         m_hBar->styleChanged();
2964     if (m_vBar)
2965         m_vBar->styleChanged();
2966
2967     // Force an update since we know the scrollbars have changed things.
2968 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
2969     if (renderer().document().hasAnnotatedRegions())
2970         renderer().document().setAnnotatedRegionsDirty(true);
2971 #endif
2972 }
2973
2974 ScrollableArea* RenderLayer::enclosingScrollableArea() const
2975 {
2976     if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
2977         return scrollableLayer;
2978
2979     // FIXME: We should return the frame view here (or possibly an ancestor frame view,
2980     // if the frame view isn't scrollable.
2981     return 0;
2982 }
2983
2984 int RenderLayer::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const
2985 {
2986     if (!m_vBar || (m_vBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayScrollbarSize || !m_vBar->shouldParticipateInHitTesting())))
2987         return 0;
2988     return m_vBar->width();
2989 }
2990
2991 int RenderLayer::horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy relevancy) const
2992 {
2993     if (!m_hBar || (m_hBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayScrollbarSize || !m_hBar->shouldParticipateInHitTesting())))
2994         return 0;
2995     return m_hBar->height();
2996 }
2997
2998 IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
2999 {
3000     // Currently the resize corner is either the bottom right corner or the bottom left corner.
3001     // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
3002     IntSize elementSize = size();
3003     if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
3004         elementSize.setWidth(0);
3005     IntPoint resizerPoint = IntPoint(elementSize);
3006     IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
3007     return localPoint - resizerPoint;
3008 }
3009
3010 bool RenderLayer::hasOverflowControls() const
3011 {
3012     return m_hBar || m_vBar || m_scrollCorner || renderer().style().resize() != RESIZE_NONE;
3013 }
3014
3015 void RenderLayer::positionOverflowControls(const IntSize& offsetFromRoot)
3016 {
3017     if (!m_hBar && !m_vBar && !canResize())
3018         return;
3019     
3020     RenderBox* box = renderBox();
3021     if (!box)
3022         return;
3023
3024     const IntRect borderBox = box->pixelSnappedBorderBoxRect();
3025     const IntRect& scrollCorner = scrollCornerRect();
3026     IntRect absBounds(borderBox.location() + offsetFromRoot, borderBox.size());
3027     if (m_vBar) {
3028         IntRect vBarRect = rectForVerticalScrollbar(borderBox);
3029         vBarRect.move(offsetFromRoot);
3030         m_vBar->setFrameRect(vBarRect);
3031     }
3032     
3033     if (m_hBar) {
3034         IntRect hBarRect = rectForHorizontalScrollbar(borderBox);
3035         hBarRect.move(offsetFromRoot);
3036         m_hBar->setFrameRect(hBarRect);
3037     }
3038     
3039     if (m_scrollCorner)
3040         m_scrollCorner->setFrameRect(scrollCorner);
3041     if (m_resizer)
3042         m_resizer->setFrameRect(resizerCornerRect(this, borderBox));
3043
3044 #if USE(ACCELERATED_COMPOSITING)    
3045     if (isComposited())
3046         backing()->positionOverflowControlsLayers();
3047 #endif
3048 }
3049
3050 int RenderLayer::scrollWidth() const
3051 {
3052     ASSERT(renderBox());
3053     if (m_scrollDimensionsDirty)
3054         const_cast<RenderLayer*>(this)->computeScrollDimensions();
3055     return snapSizeToPixel(m_scrollSize.width(), renderBox()->clientLeft() + renderBox()->x());
3056 }
3057
3058 int RenderLayer::scrollHeight() const
3059 {
3060     ASSERT(renderBox());
3061     if (m_scrollDimensionsDirty)
3062         const_cast<RenderLayer*>(this)->computeScrollDimensions();
3063     return snapSizeToPixel(m_scrollSize.height(), renderBox()->clientTop() + renderBox()->y());
3064 }
3065
3066 LayoutUnit RenderLayer::overflowTop() const
3067 {
3068     RenderBox* box = renderBox();
3069     LayoutRect overflowRect(box->layoutOverflowRect());
3070     box->flipForWritingMode(overflowRect);
3071     return overflowRect.y();
3072 }
3073
3074 LayoutUnit RenderLayer::overflowBottom() const
3075 {
3076     RenderBox* box = renderBox();
3077     LayoutRect overflowRect(box->layoutOverflowRect());
3078     box->flipForWritingMode(overflowRect);
3079     return overflowRect.maxY();
3080 }
3081
3082 LayoutUnit RenderLayer::overflowLeft() const
3083 {
3084     RenderBox* box = renderBox();
3085     LayoutRect overflowRect(box->layoutOverflowRect());
3086     box->flipForWritingMode(overflowRect);
3087     return overflowRect.x();
3088 }
3089
3090 LayoutUnit RenderLayer::overflowRight() const
3091 {
3092     RenderBox* box = renderBox();
3093     LayoutRect overflowRect(box->layoutOverflowRect());
3094     box->flipForWritingMode(overflowRect);
3095     return overflowRect.maxX();
3096 }
3097
3098 void RenderLayer::computeScrollDimensions()
3099 {
3100     RenderBox* box = renderBox();
3101     ASSERT(box);
3102
3103     m_scrollDimensionsDirty = false;
3104
3105     m_scrollSize.setWidth(overflowRight() - overflowLeft());
3106     m_scrollSize.setHeight(overflowBottom() - overflowTop());
3107
3108     int scrollableLeftOverflow = overflowLeft() - box->borderLeft();
3109     int scrollableTopOverflow = overflowTop() - box->borderTop();
3110     setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
3111 }
3112
3113 bool RenderLayer::hasScrollableHorizontalOverflow() const
3114 {
3115     return hasHorizontalOverflow() && renderBox()->scrollsOverflowX();
3116 }
3117
3118 bool RenderLayer::hasScrollableVerticalOverflow() const
3119 {
3120     return hasVerticalOverflow() && renderBox()->scrollsOverflowY();
3121 }
3122
3123 bool RenderLayer::hasHorizontalOverflow() const
3124 {
3125     ASSERT(!m_scrollDimensionsDirty);
3126
3127     return scrollWidth() > renderBox()->pixelSnappedClientWidth();
3128 }
3129
3130 bool RenderLayer::hasVerticalOverflow() const
3131 {
3132     ASSERT(!m_scrollDimensionsDirty);
3133
3134     return scrollHeight() > renderBox()->pixelSnappedClientHeight();
3135 }
3136
3137 void RenderLayer::updateScrollbarsAfterLayout()
3138 {
3139     RenderBox* box = renderBox();
3140     ASSERT(box);
3141
3142     // List box parts handle the scrollbars by themselves so we have nothing to do.
3143     if (box->style().appearance() == ListboxPart)
3144         return;
3145
3146     bool hasHorizontalOverflow = this->hasHorizontalOverflow();
3147     bool hasVerticalOverflow = this->hasVerticalOverflow();
3148
3149     // overflow:scroll should just enable/disable.
3150     if (renderer().style().overflowX() == OSCROLL)
3151         m_hBar->setEnabled(hasHorizontalOverflow);
3152     if (renderer().style().overflowY() == OSCROLL)
3153         m_vBar->setEnabled(hasVerticalOverflow);
3154
3155     // overflow:auto may need to lay out again if scrollbars got added/removed.
3156     bool autoHorizontalScrollBarChanged = box->hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
3157     bool autoVerticalScrollBarChanged = box->hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
3158
3159     if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) {
3160         if (box->hasAutoHorizontalScrollbar())
3161             setHasHorizontalScrollbar(hasHorizontalOverflow);
3162         if (box->hasAutoVerticalScrollbar())
3163             setHasVerticalScrollbar(hasVerticalOverflow);
3164
3165         updateSelfPaintingLayer();
3166
3167         // Force an update since we know the scrollbars have changed things.
3168 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
3169         if (renderer().document().hasAnnotatedRegions())
3170             renderer().document().setAnnotatedRegionsDirty(true);
3171 #endif
3172
3173         renderer().repaint();
3174
3175         if (renderer().style().overflowX() == OAUTO || renderer().style().overflowY() == OAUTO) {
3176             if (!m_inOverflowRelayout) {
3177                 // Our proprietary overflow: overlay value doesn't trigger a layout.
3178                 m_inOverflowRelayout = true;
3179                 renderer().setNeedsLayout(MarkOnlyThis);
3180                 if (renderer().isRenderBlock()) {
3181                     RenderBlock& block = toRenderBlock(renderer());
3182                     block.scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
3183                     block.layoutBlock(true);
3184                 } else
3185                     renderer().layout();
3186                 m_inOverflowRelayout = false;
3187             }
3188         }
3189     }
3190
3191     // Set up the range (and page step/line step).
3192     if (m_hBar) {
3193         int clientWidth = box->pixelSnappedClientWidth();
3194         int pageStep = std::max(std::max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
3195         m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
3196         m_hBar->setProportion(clientWidth, m_scrollSize.width());
3197     }
3198     if (m_vBar) {
3199         int clientHeight = box->pixelSnappedClientHeight();
3200         int pageStep = std::max(std::max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
3201         m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
3202         m_vBar->setProportion(clientHeight, m_scrollSize.height());
3203     }
3204
3205     updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
3206 }
3207
3208 void RenderLayer::updateScrollInfoAfterLayout()
3209 {
3210     RenderBox* box = renderBox();
3211     if (!box)
3212         return;
3213
3214     m_scrollDimensionsDirty = true;
3215     IntSize originalScrollOffset = scrollOffset();
3216
3217     computeScrollDimensions();
3218
3219     if (box->style().overflowX() != OMARQUEE) {
3220         // Layout may cause us to be at an invalid scroll position. In this case we need
3221         // to pull our scroll offsets back to the max (or push them up to the min).
3222         IntSize clampedScrollOffset = clampScrollOffset(scrollOffset());
3223         if (clampedScrollOffset != scrollOffset())
3224             scrollToOffset(clampedScrollOffset);
3225     }
3226
3227     updateScrollbarsAfterLayout();
3228
3229     if (originalScrollOffset != scrollOffset())
3230         scrollToOffsetWithoutAnimation(IntPoint(scrollOffset()));
3231
3232 #if USE(ACCELERATED_COMPOSITING)
3233     // Composited scrolling may need to be enabled or disabled if the amount of overflow changed.
3234     if (compositor().updateLayerCompositingState(*this))
3235         compositor().setCompositingLayersNeedRebuild();
3236 #endif
3237 }
3238
3239 bool RenderLayer::overflowControlsIntersectRect(const IntRect& localRect) const
3240 {
3241     const IntRect borderBox = renderBox()->pixelSnappedBorderBoxRect();
3242
3243     if (rectForHorizontalScrollbar(borderBox).intersects(localRect))
3244         return true;
3245
3246     if (rectForVerticalScrollbar(borderBox).intersects(localRect))
3247         return true;
3248
3249     if (scrollCornerRect().intersects(localRect))
3250         return true;
3251     
3252     if (resizerCornerRect(this, borderBox).intersects(localRect))
3253         return true;
3254
3255     return false;
3256 }
3257
3258 void RenderLayer::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
3259 {
3260     // Don't do anything if we have no overflow.
3261     if (!renderer().hasOverflowClip())
3262         return;
3263
3264     // Overlay scrollbars paint in a second pass through the layer tree so that they will paint
3265     // on top of everything else. If this is the normal painting pass, paintingOverlayControls
3266     // will be false, and we should just tell the root layer that there are overlay scrollbars
3267     // that need to be painted. That will cause the second pass through the layer tree to run,
3268     // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the 
3269     // second pass doesn't need to re-enter the RenderTree to get it right.
3270     if (hasOverlayScrollbars() && !paintingOverlayControls) {
3271         m_cachedOverlayScrollbarOffset = paintOffset;
3272 #if USE(ACCELERATED_COMPOSITING)
3273         // It's not necessary to do the second pass if the scrollbars paint into layers.
3274         if ((m_hBar && layerForHorizontalScrollbar()) || (m_vBar && layerForVerticalScrollbar()))
3275             return;
3276 #endif
3277         IntRect localDamgeRect = damageRect;
3278         localDamgeRect.moveBy(-paintOffset);
3279         if (!overflowControlsIntersectRect(localDamgeRect))
3280             return;
3281
3282         RenderLayer* paintingRoot = 0;
3283 #if USE(ACCELERATED_COMPOSITING)
3284         paintingRoot = enclosingCompositingLayer();
3285 #endif
3286         if (!paintingRoot)
3287             paintingRoot = renderer().view().layer();
3288
3289         paintingRoot->setContainsDirtyOverlayScrollbars(true);
3290         return;
3291     }
3292
3293     // This check is required to avoid painting custom CSS scrollbars twice.
3294     if (paintingOverlayControls && !hasOverlayScrollbars())
3295         return;
3296
3297     IntPoint adjustedPaintOffset = paintOffset;
3298     if (paintingOverlayControls)
3299         adjustedPaintOffset = m_cachedOverlayScrollbarOffset;
3300
3301     // Move the scrollbar widgets if necessary.  We normally move and resize widgets during layout, but sometimes
3302     // widgets can move without layout occurring (most notably when you scroll a document that
3303     // contains fixed positioned elements).
3304     positionOverflowControls(toIntSize(adjustedPaintOffset));
3305
3306     // Now that we're sure the scrollbars are in the right place, paint them.
3307     if (m_hBar
3308 #if USE(ACCELERATED_COMPOSITING)
3309         && !layerForHorizontalScrollbar()
3310 #endif
3311               )
3312         m_hBar->paint(context, damageRect);
3313     if (m_vBar
3314 #if USE(ACCELERATED_COMPOSITING)
3315         && !layerForVerticalScrollbar()
3316 #endif
3317               )
3318         m_vBar->paint(context, damageRect);
3319
3320 #if USE(ACCELERATED_COMPOSITING)
3321     if (layerForScrollCorner())
3322         return;
3323 #endif
3324
3325     // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
3326     // edge of the box.
3327     paintScrollCorner(context, adjustedPaintOffset, damageRect);
3328     
3329     // Paint our resizer last, since it sits on top of the scroll corner.
3330     paintResizer(context, adjustedPaintOffset, damageRect);
3331 }
3332
3333 void RenderLayer::paintScrollCorner(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
3334 {
3335     RenderBox* box = renderBox();
3336     ASSERT(box);
3337
3338     IntRect absRect = scrollCornerRect();
3339     absRect.moveBy(paintOffset);
3340     if (!absRect.intersects(damageRect))
3341         return;
3342
3343     if (context->updatingControlTints()) {
3344         updateScrollCornerStyle();
3345         return;
3346     }
3347
3348     if (m_scrollCorner) {
3349         m_scrollCorner->paintIntoRect(context, paintOffset, absRect);
3350         return;
3351     }
3352
3353     // We don't want to paint white if we have overlay scrollbars, since we need
3354     // to see what is behind it.
3355     if (!hasOverlayScrollbars())
3356         context->fillRect(absRect, Color::white, box->style().colorSpace());
3357 }
3358
3359 void RenderLayer::drawPlatformResizerImage(GraphicsContext* context, IntRect resizerCornerRect)
3360 {
3361     float deviceScaleFactor = WebCore::deviceScaleFactor(&renderer().frame());
3362
3363     RefPtr<Image> resizeCornerImage;
3364     IntSize cornerResizerSize;
3365     if (deviceScaleFactor >= 2) {
3366         DEFINE_STATIC_LOCAL(Image*, resizeCornerImageHiRes, (Image::loadPlatformResource("textAreaResizeCorner@2x").leakRef()));
3367         resizeCornerImage = resizeCornerImageHiRes;
3368         cornerResizerSize = resizeCornerImage->size();
3369         cornerResizerSize.scale(0.5f);
3370     } else {
3371         DEFINE_STATIC_LOCAL(Image*, resizeCornerImageLoRes, (Image::loadPlatformResource("textAreaResizeCorner").leakRef()));
3372         resizeCornerImage = resizeCornerImageLoRes;
3373         cornerResizerSize = resizeCornerImage->size();
3374     }
3375
3376     if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
3377         context->save();
3378         context->translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
3379         context->scale(FloatSize(-1.0, 1.0));
3380         context->drawImage(resizeCornerImage.get(), renderer().style().colorSpace(), IntRect(IntPoint(), cornerResizerSize));
3381         context->restore();
3382         return;
3383     }
3384     IntRect imageRect(resizerCornerRect.maxXMaxYCorner() - cornerResizerSize, cornerResizerSize);
3385     context->drawImage(resizeCornerImage.get(), renderer().style().colorSpace(), imageRect);
3386 }
3387
3388 void RenderLayer::paintResizer(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
3389 {
3390     if (renderer().style().resize() == RESIZE_NONE)
3391         return;
3392
3393     RenderBox* box = renderBox();
3394     ASSERT(box);
3395
3396     IntRect absRect = resizerCornerRect(this, box->pixelSnappedBorderBoxRect());
3397     absRect.moveBy(paintOffset);
3398     if (!absRect.intersects(damageRect))
3399         return;
3400
3401     if (context->updatingControlTints()) {
3402         updateResizerStyle();
3403         return;
3404     }
3405     
3406     if (m_resizer) {
3407         m_resizer->paintIntoRect(context, paintOffset, absRect);
3408         return;
3409     }
3410
3411     drawPlatformResizerImage(context, absRect);
3412
3413