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