summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderLayer.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-05 14:34:32 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-05 14:34:32 -0800
commit635860845790a19bf50bbc51ba8fb66a96dde068 (patch)
treeef6ad9ff73a5b57f65249d4232a202fa77e6a140 /WebCore/rendering/RenderLayer.cpp
parent8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2 (diff)
downloadexternal_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.zip
external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.gz
external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.bz2
auto import from //depot/cupcake/@136594
Diffstat (limited to 'WebCore/rendering/RenderLayer.cpp')
-rw-r--r--WebCore/rendering/RenderLayer.cpp577
1 files changed, 308 insertions, 269 deletions
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 93efde1..1a538c6 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -74,6 +74,7 @@
#include "ScrollbarTheme.h"
#include "SelectionController.h"
#include "TranslateTransformOperation.h"
+#include <wtf/StdLibExtras.h>
#if ENABLE(SVG)
#include "SVGNames.h"
@@ -115,8 +116,8 @@ void ClipRects::destroy(RenderArena* renderArena)
renderArena->free(*(size_t *)this, this);
}
-RenderLayer::RenderLayer(RenderObject* object)
- : m_object(object)
+RenderLayer::RenderLayer(RenderBox* renderer)
+ : m_renderer(renderer)
, m_parent(0)
, m_previous(0)
, m_next(0)
@@ -139,6 +140,9 @@ RenderLayer::RenderLayer(RenderObject* object)
, m_negZOrderList(0)
, m_overflowList(0)
, m_clipRects(0)
+#ifndef NDEBUG
+ , m_clipRectsRoot(0)
+#endif
, m_scrollDimensionsDirty(true)
, m_zOrderListsDirty(true)
, m_overflowListDirty(true)
@@ -160,9 +164,9 @@ RenderLayer::RenderLayer(RenderObject* object)
, m_scrollCorner(0)
, m_resizer(0)
{
- if (!object->firstChild() && object->style()) {
+ if (!renderer->firstChild() && renderer->style()) {
m_visibleContentStatusDirty = false;
- m_hasVisibleContent = object->style()->visibility() == VISIBLE;
+ m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
}
}
@@ -203,7 +207,7 @@ RenderLayer::~RenderLayer()
void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
{
if (doFullRepaint) {
- m_object->repaint();
+ renderer()->repaint();
checkForRepaint = doFullRepaint = false;
}
@@ -221,14 +225,14 @@ void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
updateTransform();
if (m_hasVisibleContent) {
- RenderView* view = m_object->view();
+ RenderView* view = renderer()->view();
ASSERT(view);
// FIXME: Optimize using LayoutState and remove the disableLayoutState() call
// from updateScrollInfoAfterLayout().
- ASSERT(!view->layoutState());
+ ASSERT(!view->layoutStateEnabled());
- IntRect newRect = m_object->absoluteClippedOverflowRect();
- IntRect newOutlineBox = m_object->absoluteOutlineBox();
+ IntRect newRect = renderer()->absoluteClippedOverflowRect();
+ IntRect newOutlineBox = renderer()->absoluteOutlineBounds();
if (checkForRepaint) {
if (view && !view->printing()) {
if (m_needsFullRepaint) {
@@ -236,7 +240,7 @@ void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
if (newRect != m_repaintRect)
view->repaintViewRectangle(newRect);
} else
- m_object->repaintAfterLayoutIfNeeded(m_repaintRect, m_outlineBox);
+ renderer()->repaintAfterLayoutIfNeeded(m_repaintRect, m_outlineBox);
}
}
m_repaintRect = newRect;
@@ -266,14 +270,14 @@ void RenderLayer::updateTransform()
bool hadTransform = m_transform;
if (hasTransform != hadTransform) {
if (hasTransform)
- m_transform.set(new AffineTransform);
+ m_transform.set(new TransformationMatrix);
else
m_transform.clear();
}
if (hasTransform) {
m_transform->reset();
- renderer()->style()->applyTransform(*m_transform, renderer()->borderBox().size());
+ renderer()->style()->applyTransform(*m_transform, renderer()->borderBoxRect().size());
}
}
@@ -285,7 +289,7 @@ void RenderLayer::setHasVisibleContent(bool b)
m_hasVisibleContent = b;
if (m_hasVisibleContent) {
m_repaintRect = renderer()->absoluteClippedOverflowRect();
- m_outlineBox = renderer()->absoluteOutlineBox();
+ m_outlineBox = renderer()->absoluteOutlineBounds();
if (!isOverflowOnly())
dirtyStackingContextZOrderLists();
}
@@ -338,12 +342,12 @@ void RenderLayer::updateVisibilityStatus()
}
if (m_visibleContentStatusDirty) {
- if (m_object->style()->visibility() == VISIBLE)
+ if (renderer()->style()->visibility() == VISIBLE)
m_hasVisibleContent = true;
else {
// layer may be hidden but still have some visible content, check for this
m_hasVisibleContent = false;
- RenderObject* r = m_object->firstChild();
+ RenderObject* r = renderer()->firstChild();
while (r) {
if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
m_hasVisibleContent = true;
@@ -356,7 +360,7 @@ void RenderLayer::updateVisibilityStatus()
else {
do {
r = r->parent();
- if (r==m_object)
+ if (r==renderer())
r = 0;
} while (r && !r->nextSibling());
if (r)
@@ -371,72 +375,80 @@ void RenderLayer::updateVisibilityStatus()
void RenderLayer::updateLayerPosition()
{
// Clear our cached clip rect information.
- clearClipRect();
+ clearClipRects();
- int x = m_object->xPos();
- int y = m_object->yPos() - m_object->borderTopExtra();
+ int x = renderer()->x();
+ int y = renderer()->y();
- if (!m_object->isPositioned() && m_object->parent()) {
+ if (!renderer()->isPositioned() && renderer()->parent()) {
// We must adjust our position by walking up the render tree looking for the
// nearest enclosing object with a layer.
- RenderObject* curr = m_object->parent();
+ RenderBox* curr = renderer()->parentBox();
while (curr && !curr->hasLayer()) {
if (!curr->isTableRow()) {
// Rows and cells share the same coordinate space (that of the section).
// Omit them when computing our xpos/ypos.
- x += curr->xPos();
- y += curr->yPos();
+ x += curr->x();
+ y += curr->y();
}
- curr = curr->parent();
+ curr = curr->parentBox();
}
- y += curr->borderTopExtra();
if (curr->isTableRow()) {
// Put ourselves into the row coordinate space.
- x -= curr->xPos();
- y -= curr->yPos();
+ x -= curr->x();
+ y -= curr->y();
}
}
m_relX = m_relY = 0;
- if (m_object->isRelPositioned()) {
- m_relX = static_cast<RenderBox*>(m_object)->relativePositionOffsetX();
- m_relY = static_cast<RenderBox*>(m_object)->relativePositionOffsetY();
+ if (renderer()->isRelPositioned()) {
+ m_relX = toRenderBox(renderer())->relativePositionOffsetX();
+ m_relY = toRenderBox(renderer())->relativePositionOffsetY();
x += m_relX; y += m_relY;
}
// Subtract our parent's scroll offset.
- if (m_object->isPositioned() && enclosingPositionedAncestor()) {
+ if (renderer()->isPositioned() && enclosingPositionedAncestor()) {
RenderLayer* positionedParent = enclosingPositionedAncestor();
// For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
- positionedParent->subtractScrollOffset(x, y);
+ positionedParent->subtractScrolledContentOffset(x, y);
- if (m_object->isPositioned()) {
- IntSize offset = static_cast<RenderBox*>(m_object)->offsetForPositionedInContainer(positionedParent->renderer());
+ if (renderer()->isPositioned()) {
+ IntSize offset = toRenderBox(renderer())->offsetForPositionedInContainer(positionedParent->renderer());
x += offset.width();
y += offset.height();
}
} else if (parent())
- parent()->subtractScrollOffset(x, y);
+ parent()->subtractScrolledContentOffset(x, y);
- setPos(x,y);
+ // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
- setWidth(m_object->width());
- setHeight(m_object->height() + m_object->borderTopExtra() + m_object->borderBottomExtra());
+ setPos(x, y);
- if (!m_object->hasOverflowClip()) {
- if (m_object->overflowWidth() > m_object->width())
- setWidth(m_object->overflowWidth());
- if (m_object->overflowHeight() > m_object->height())
- setHeight(m_object->overflowHeight());
+ if (renderer()->isRenderInline()) {
+ RenderInline* inlineFlow = static_cast<RenderInline*>(renderer());
+ IntRect lineBox = inlineFlow->linesBoundingBox();
+ setWidth(lineBox.width());
+ setHeight(lineBox.height());
+ } else {
+ setWidth(renderer()->width());
+ setHeight(renderer()->height());
+
+ if (!renderer()->hasOverflowClip()) {
+ if (renderer()->overflowWidth() > renderer()->width())
+ setWidth(renderer()->overflowWidth());
+ if (renderer()->overflowHeight() > renderer()->height())
+ setHeight(renderer()->overflowHeight());
+ }
}
}
RenderLayer *RenderLayer::stackingContext() const
{
RenderLayer* curr = parent();
- for ( ; curr && !curr->m_object->isRenderView() && !curr->m_object->isRoot() &&
- curr->m_object->style()->hasAutoZIndex();
+ for ( ; curr && !curr->renderer()->isRenderView() && !curr->renderer()->isRoot() &&
+ curr->renderer()->style()->hasAutoZIndex();
curr = curr->parent()) { }
return curr;
}
@@ -444,7 +456,7 @@ RenderLayer *RenderLayer::stackingContext() const
RenderLayer* RenderLayer::enclosingPositionedAncestor() const
{
RenderLayer* curr = parent();
- for ( ; curr && !curr->m_object->isRenderView() && !curr->m_object->isPositioned() && !curr->m_object->isRelPositioned() && !curr->hasTransform();
+ for ( ; curr && !curr->renderer()->isRenderView() && !curr->renderer()->isPositioned() && !curr->renderer()->isRelPositioned() && !curr->hasTransform();
curr = curr->parent()) { }
return curr;
}
@@ -452,11 +464,17 @@ RenderLayer* RenderLayer::enclosingPositionedAncestor() const
RenderLayer* RenderLayer::enclosingTransformedAncestor() const
{
RenderLayer* curr = parent();
- for ( ; curr && !curr->m_object->isRenderView() && !curr->transform(); curr = curr->parent())
+ for ( ; curr && !curr->renderer()->isRenderView() && !curr->transform(); curr = curr->parent())
{ }
return curr;
}
+IntPoint RenderLayer::absoluteToContents(const IntPoint& absolutePoint) const
+{
+ // We don't use convertToLayerCoords because it doesn't know about transforms
+ return roundedIntPoint(renderer()->absoluteToLocal(absolutePoint, false, true));
+}
+
bool RenderLayer::requiresSlowRepaints() const
{
if (isTransparent() || hasReflection() || hasTransform())
@@ -469,10 +487,10 @@ bool RenderLayer::requiresSlowRepaints() const
bool RenderLayer::isTransparent() const
{
#if ENABLE(SVG)
- if (m_object->node()->namespaceURI() == SVGNames::svgNamespaceURI)
+ if (renderer()->node()->namespaceURI() == SVGNames::svgNamespaceURI)
return false;
#endif
- return m_object->isTransparent() || m_object->hasMask();
+ return renderer()->isTransparent() || renderer()->hasMask();
}
RenderLayer*
@@ -483,20 +501,20 @@ RenderLayer::transparentAncestor()
return curr;
}
-static IntRect transparencyClipBox(const AffineTransform& enclosingTransform, const RenderLayer* l, const RenderLayer* rootLayer)
+static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransform, const RenderLayer* l, const RenderLayer* rootLayer)
{
// FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
// paintDirtyRect, and that should cut down on the amount we have to paint. Still it
// would be better to respect clips.
- AffineTransform* t = l->transform();
+ TransformationMatrix* t = l->transform();
if (t && rootLayer != l) {
// The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
// the transformed layer and all of its children.
int x = 0;
int y = 0;
l->convertToLayerCoords(rootLayer, x, y);
- AffineTransform transform;
+ TransformationMatrix transform;
transform.translate(x, y);
transform = *t * transform;
transform = transform * enclosingTransform;
@@ -542,7 +560,7 @@ void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer*
if (isTransparent()) {
m_usedTransparency = true;
p->save();
- p->clip(transparencyClipBox(AffineTransform(), this, rootLayer));
+ p->clip(transparencyClipBox(TransformationMatrix(), this, rootLayer));
p->beginTransparencyLayer(renderer()->opacity());
}
}
@@ -637,7 +655,7 @@ void RenderLayer::removeOnlyThisLayer()
return;
// Dirty the clip rects.
- clearClipRects();
+ clearClipRectsIncludingDescendants();
// Remove us from the parent.
RenderLayer* parent = m_parent;
@@ -676,7 +694,7 @@ void RenderLayer::insertOnlyThisLayer()
curr->moveLayers(m_parent, this);
// Clear out all the clip rects.
- clearClipRects();
+ clearClipRectsIncludingDescendants();
}
void
@@ -685,18 +703,17 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int&
if (ancestorLayer == this)
return;
- if (m_object->style()->position() == FixedPosition) {
+ if (renderer()->style()->position() == FixedPosition) {
// Add in the offset of the view. We can obtain this by calling
- // absolutePosition() on the RenderView.
- int xOff, yOff;
- m_object->absolutePosition(xOff, yOff, true);
- x += xOff;
- y += yOff;
+ // localToAbsolute() on the RenderView.
+ FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
+ x += absPos.x();
+ y += absPos.y();
return;
}
RenderLayer* parentLayer;
- if (m_object->style()->position() == AbsolutePosition)
+ if (renderer()->style()->position() == AbsolutePosition)
parentLayer = enclosingPositionedAncestor();
else
parentLayer = parent();
@@ -749,10 +766,10 @@ void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
{
bool restrictedByLineClamp = false;
- if (m_object->parent())
- restrictedByLineClamp = m_object->parent()->style()->lineClamp() >= 0;
+ if (renderer()->parent())
+ restrictedByLineClamp = renderer()->parent()->style()->lineClamp() >= 0;
- if (m_object->hasOverflowClip() && !restrictedByLineClamp) {
+ if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
int newOffsetX = scrollXOffset() + xDelta;
int newOffsetY = scrollYOffset() + yDelta;
scrollToOffset(newOffsetX, newOffsetY);
@@ -760,26 +777,26 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
// If this layer can't do the scroll we ask its parent
int leftToScrollX = newOffsetX - scrollXOffset();
int leftToScrollY = newOffsetY - scrollYOffset();
- if ((leftToScrollX || leftToScrollY) && m_object->parent()) {
- m_object->parent()->enclosingLayer()->scrollByRecursively(leftToScrollX, leftToScrollY);
+ if ((leftToScrollX || leftToScrollY) && renderer()->parent()) {
+ renderer()->parent()->enclosingLayer()->scrollByRecursively(leftToScrollX, leftToScrollY);
Frame* frame = renderer()->document()->frame();
if (frame)
frame->eventHandler()->updateAutoscrollRenderer();
}
- } else if (m_object->view()->frameView())
- m_object->view()->frameView()->scrollBy(IntSize(xDelta, yDelta));
+ } else if (renderer()->view()->frameView())
+ renderer()->view()->frameView()->scrollBy(IntSize(xDelta, yDelta));
}
void
-RenderLayer::scrollOffset(int& x, int& y)
+RenderLayer::addScrolledContentOffset(int& x, int& y) const
{
x += scrollXOffset() + m_scrollLeftOverflow;
y += scrollYOffset();
}
void
-RenderLayer::subtractScrollOffset(int& x, int& y)
+RenderLayer::subtractScrolledContentOffset(int& x, int& y) const
{
x -= scrollXOffset() + m_scrollLeftOverflow;
y -= scrollYOffset();
@@ -793,8 +810,8 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
// Call the scrollWidth/Height functions so that the dimensions will be computed if they need
// to be (for overflow:hidden blocks).
- int maxX = scrollWidth() - m_object->clientWidth();
- int maxY = scrollHeight() - m_object->clientHeight();
+ int maxX = scrollWidth() - renderer()->clientWidth();
+ int maxY = scrollHeight() - renderer()->clientHeight();
if (x > maxX) x = maxX;
if (y > maxY) y = maxY;
@@ -805,7 +822,10 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
// complicated (since it will involve testing whether our layer
// is either occluded by another layer or clipped by an enclosing
// layer or contains fixed backgrounds, etc.).
- m_scrollX = x - m_scrollOriginX;
+ int newScrollX = x - m_scrollOriginX;
+ if (m_scrollY == y && m_scrollX == newScrollX)
+ return;
+ m_scrollX = newScrollX;
m_scrollY = y;
// Update the positions of our child layers.
@@ -826,9 +846,14 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
view->updateWidgetPositions();
}
+ // The caret rect needs to be invalidated after scrolling
+ Frame* frame = renderer()->document()->frame();
+ if (frame)
+ frame->invalidateSelection();
+
// Just schedule a full repaint of our object.
if (repaint)
- m_object->repaint();
+ renderer()->repaint();
if (updateScrollbars) {
if (m_hBar)
@@ -851,31 +876,29 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
int xOffset = 0, yOffset = 0;
// We may end up propagating a scroll event. It is important that we suspend events until
- // the end of the function since they could delete the layer or the layer's m_object.
- FrameView* frameView = m_object->document()->view();
+ // the end of the function since they could delete the layer or the layer's renderer().
+ FrameView* frameView = renderer()->document()->view();
if (frameView)
frameView->pauseScheduledEvents();
bool restrictedByLineClamp = false;
- if (m_object->parent()) {
- parentLayer = m_object->parent()->enclosingLayer();
- restrictedByLineClamp = m_object->parent()->style()->lineClamp() >= 0;
+ if (renderer()->parent()) {
+ parentLayer = renderer()->parent()->enclosingLayer();
+ restrictedByLineClamp = renderer()->parent()->style()->lineClamp() >= 0;
}
- if (m_object->hasOverflowClip() && !restrictedByLineClamp) {
+ if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
// Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
// This will prevent us from revealing text hidden by the slider in Safari RSS.
- int x, y;
- m_object->absolutePosition(x, y);
- x += m_object->borderLeft();
- y += m_object->borderTop();
+ FloatPoint absPos = renderer()->localToAbsolute();
+ absPos.move(renderer()->borderLeft(), renderer()->borderTop());
- IntRect layerBounds = IntRect(x + scrollXOffset(), y + scrollYOffset(), m_object->clientWidth(), m_object->clientHeight());
+ IntRect layerBounds = IntRect(absPos.x() + scrollXOffset(), absPos.y() + scrollYOffset(), renderer()->clientWidth(), renderer()->clientHeight());
IntRect exposeRect = IntRect(rect.x() + scrollXOffset(), rect.y() + scrollYOffset(), rect.width(), rect.height());
IntRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
- xOffset = r.x() - x;
- yOffset = r.y() - y;
+ xOffset = r.x() - absPos.x();
+ yOffset = r.y() - absPos.y();
// Adjust offsets if they're outside of the allowable range.
xOffset = max(0, min(scrollWidth() - layerBounds.width(), xOffset));
yOffset = max(0, min(scrollHeight() - layerBounds.height(), yOffset));
@@ -891,7 +914,7 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
}
} else if (!parentLayer && renderer()->canBeProgramaticallyScrolled(scrollToAnchor)) {
if (frameView) {
- if (m_object->document() && m_object->document()->ownerElement() && m_object->document()->ownerElement()->renderer()) {
+ if (renderer()->document() && renderer()->document()->ownerElement() && renderer()->document()->ownerElement()->renderer()) {
IntRect viewRect = frameView->visibleContentRect();
IntRect r = getRectToExpose(viewRect, rect, alignX, alignY);
@@ -902,7 +925,7 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
yOffset = max(0, min(frameView->contentsHeight(), yOffset));
frameView->setScrollPosition(IntPoint(xOffset, yOffset));
- parentLayer = m_object->document()->ownerElement()->renderer()->enclosingLayer();
+ parentLayer = renderer()->document()->ownerElement()->renderer()->enclosingLayer();
newRect.setX(rect.x() - frameView->scrollX() + frameView->x());
newRect.setY(rect.y() - frameView->scrollY() + frameView->y());
} else {
@@ -1014,13 +1037,13 @@ void RenderLayer::autoscroll()
void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset)
{
- if (!inResizeMode() || !m_object->hasOverflowClip())
+ if (!inResizeMode() || !renderer()->hasOverflowClip())
return;
// Set the width and height of the shadow ancestor node if there is one.
// This is necessary for textarea elements since the resizable layer is in the shadow content.
- Element* element = static_cast<Element*>(m_object->node()->shadowAncestorNode());
- RenderBox* renderer = static_cast<RenderBox*>(element->renderer());
+ Element* element = static_cast<Element*>(renderer()->node()->shadowAncestorNode());
+ RenderBox* renderer = toRenderBox(element->renderer());
EResize resize = renderer->style()->resize();
if (resize == RESIZE_NONE)
@@ -1156,7 +1179,7 @@ static IntRect resizerCornerRect(const RenderLayer* layer, const IntRect& bounds
bool RenderLayer::scrollbarCornerPresent() const
{
- return !scrollCornerRect(this, m_object->borderBox()).isEmpty();
+ return !scrollCornerRect(this, renderer()->borderBoxRect()).isEmpty();
}
void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
@@ -1172,12 +1195,12 @@ void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& r
PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
{
RefPtr<Scrollbar> widget;
- bool hasCustomScrollbarStyle = m_object->node()->shadowAncestorNode()->renderer()->style()->hasPseudoStyle(RenderStyle::SCROLLBAR);
+ bool hasCustomScrollbarStyle = renderer()->node()->shadowAncestorNode()->renderer()->style()->hasPseudoStyle(RenderStyle::SCROLLBAR);
if (hasCustomScrollbarStyle)
- widget = RenderScrollbar::createCustomScrollbar(this, orientation, m_object->node()->shadowAncestorNode()->renderer());
+ widget = RenderScrollbar::createCustomScrollbar(this, orientation, renderer()->node()->shadowAncestorNode()->renderBox());
else
widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
- m_object->document()->view()->addChild(widget.get());
+ renderer()->document()->view()->addChild(widget.get());
return widget.release();
}
@@ -1209,8 +1232,8 @@ void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
#if ENABLE(DASHBOARD_SUPPORT)
// Force an update since we know the scrollbars have changed things.
- if (m_object->document()->hasDashboardRegions())
- m_object->document()->setDashboardRegionsDirty(true);
+ if (renderer()->document()->hasDashboardRegions())
+ renderer()->document()->setDashboardRegionsDirty(true);
#endif
}
@@ -1232,8 +1255,8 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
#if ENABLE(DASHBOARD_SUPPORT)
// Force an update since we know the scrollbars have changed things.
- if (m_object->document()->hasDashboardRegions())
- m_object->document()->setDashboardRegionsDirty(true);
+ if (renderer()->document()->hasDashboardRegions())
+ renderer()->document()->setDashboardRegionsDirty(true);
#endif
}
@@ -1251,39 +1274,38 @@ int RenderLayer::horizontalScrollbarHeight() const
return m_hBar->height();
}
-IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& p) const
+IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
{
// Currently the resize corner is always the bottom right corner
- int x = width();
- int y = height();
- convertToLayerCoords(root(), x, y);
- return p - IntPoint(x, y);
+ IntPoint bottomRight(width(), height());
+ IntPoint localPoint = absoluteToContents(absolutePoint);
+ return localPoint - bottomRight;
}
void RenderLayer::positionOverflowControls(int tx, int ty)
{
- if (!m_hBar && !m_vBar && (!m_object->hasOverflowClip() || m_object->style()->resize() == RESIZE_NONE))
+ if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
return;
- IntRect borderBox = m_object->borderBox();
+ IntRect borderBox = renderer()->borderBoxRect();
IntRect scrollCorner(scrollCornerRect(this, borderBox));
IntRect absBounds(borderBox.x() + tx, borderBox.y() + ty, borderBox.width(), borderBox.height());
if (m_vBar)
- m_vBar->setFrameRect(IntRect(absBounds.right() - m_object->borderRight() - m_vBar->width(),
- absBounds.y() + m_object->borderTop(),
+ m_vBar->setFrameRect(IntRect(absBounds.right() - renderer()->borderRight() - m_vBar->width(),
+ absBounds.y() + renderer()->borderTop(),
m_vBar->width(),
- absBounds.height() - (m_object->borderTop() + m_object->borderBottom()) - scrollCorner.height()));
+ absBounds.height() - (renderer()->borderTop() + renderer()->borderBottom()) - scrollCorner.height()));
if (m_hBar)
- m_hBar->setFrameRect(IntRect(absBounds.x() + m_object->borderLeft(),
- absBounds.bottom() - m_object->borderBottom() - m_hBar->height(),
- absBounds.width() - (m_object->borderLeft() + m_object->borderRight()) - scrollCorner.width(),
+ m_hBar->setFrameRect(IntRect(absBounds.x() + renderer()->borderLeft(),
+ absBounds.bottom() - renderer()->borderBottom() - m_hBar->height(),
+ absBounds.width() - (renderer()->borderLeft() + renderer()->borderRight()) - scrollCorner.width(),
m_hBar->height()));
if (m_scrollCorner)
- m_scrollCorner->setRect(scrollCorner);
+ m_scrollCorner->setFrameRect(scrollCorner);
if (m_resizer)
- m_resizer->setRect(resizerCornerRect(this, borderBox));
+ m_resizer->setFrameRect(resizerCornerRect(this, borderBox));
}
int RenderLayer::scrollWidth()
@@ -1304,17 +1326,17 @@ void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
{
m_scrollDimensionsDirty = false;
- bool ltr = m_object->style()->direction() == LTR;
+ bool ltr = renderer()->style()->direction() == LTR;
- int clientWidth = m_object->clientWidth();
- int clientHeight = m_object->clientHeight();
+ int clientWidth = renderer()->clientWidth();
+ int clientHeight = renderer()->clientHeight();
- m_scrollLeftOverflow = ltr ? 0 : min(0, m_object->leftmostPosition(true, false) - m_object->borderLeft());
+ m_scrollLeftOverflow = ltr ? 0 : min(0, renderer()->leftmostPosition(true, false) - renderer()->borderLeft());
int rightPos = ltr ?
- m_object->rightmostPosition(true, false) - m_object->borderLeft() :
+ renderer()->rightmostPosition(true, false) - renderer()->borderLeft() :
clientWidth - m_scrollLeftOverflow;
- int bottomPos = m_object->lowestPosition(true, false) - m_object->borderTop();
+ int bottomPos = renderer()->lowestPosition(true, false) - renderer()->borderTop();
m_scrollWidth = max(rightPos, clientWidth);
m_scrollHeight = max(bottomPos, clientHeight);
@@ -1344,9 +1366,9 @@ void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOve
m_horizontalOverflow = horizontalOverflow;
m_verticalOverflow = verticalOverflow;
- if (FrameView* frameView = m_object->document()->view()) {
+ if (FrameView* frameView = renderer()->document()->view()) {
frameView->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow),
- EventTargetNodeCast(m_object->element()));
+ EventTargetNodeCast(renderer()->element()));
}
}
}
@@ -1359,13 +1381,13 @@ RenderLayer::updateScrollInfoAfterLayout()
bool horizontalOverflow, verticalOverflow;
computeScrollDimensions(&horizontalOverflow, &verticalOverflow);
- if (m_object->style()->overflowX() != OMARQUEE) {
+ if (renderer()->style()->overflowX() != OMARQUEE) {
// Layout may cause us to be in an invalid scroll position. In this case we need
// to pull our scroll offsets back to the max (or push them up to the min).
- int newX = max(0, min(scrollXOffset(), scrollWidth() - m_object->clientWidth()));
- int newY = max(0, min(m_scrollY, scrollHeight() - m_object->clientHeight()));
+ int newX = max(0, min(scrollXOffset(), scrollWidth() - renderer()->clientWidth()));
+ int newY = max(0, min(m_scrollY, scrollHeight() - renderer()->clientHeight()));
if (newX != scrollXOffset() || newY != m_scrollY) {
- RenderView* view = m_object->view();
+ RenderView* view = renderer()->view();
ASSERT(view);
// scrollToOffset() may call updateLayerPositions(), which doesn't work
// with LayoutState.
@@ -1382,58 +1404,58 @@ RenderLayer::updateScrollInfoAfterLayout()
bool haveVerticalBar = m_vBar;
// overflow:scroll should just enable/disable.
- if (m_object->style()->overflowX() == OSCROLL)
+ if (renderer()->style()->overflowX() == OSCROLL)
m_hBar->setEnabled(horizontalOverflow);
- if (m_object->style()->overflowY() == OSCROLL)
+ if (renderer()->style()->overflowY() == OSCROLL)
m_vBar->setEnabled(verticalOverflow);
// A dynamic change from a scrolling overflow to overflow:hidden means we need to get rid of any
// scrollbars that may be present.
- if (m_object->style()->overflowX() == OHIDDEN && haveHorizontalBar)
+ if (renderer()->style()->overflowX() == OHIDDEN && haveHorizontalBar)
setHasHorizontalScrollbar(false);
- if (m_object->style()->overflowY() == OHIDDEN && haveVerticalBar)
+ if (renderer()->style()->overflowY() == OHIDDEN && haveVerticalBar)
setHasVerticalScrollbar(false);
// overflow:auto may need to lay out again if scrollbars got added/removed.
- bool scrollbarsChanged = (m_object->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow) ||
- (m_object->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow);
+ bool scrollbarsChanged = (renderer()->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow) ||
+ (renderer()->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow);
if (scrollbarsChanged) {
- if (m_object->hasAutoHorizontalScrollbar())
+ if (renderer()->hasAutoHorizontalScrollbar())
setHasHorizontalScrollbar(horizontalOverflow);
- if (m_object->hasAutoVerticalScrollbar())
+ if (renderer()->hasAutoVerticalScrollbar())
setHasVerticalScrollbar(verticalOverflow);
#if ENABLE(DASHBOARD_SUPPORT)
// Force an update since we know the scrollbars have changed things.
- if (m_object->document()->hasDashboardRegions())
- m_object->document()->setDashboardRegionsDirty(true);
+ if (renderer()->document()->hasDashboardRegions())
+ renderer()->document()->setDashboardRegionsDirty(true);
#endif
- m_object->repaint();
+ renderer()->repaint();
- if (m_object->style()->overflowX() == OAUTO || m_object->style()->overflowY() == OAUTO) {
+ if (renderer()->style()->overflowX() == OAUTO || renderer()->style()->overflowY() == OAUTO) {
if (!m_inOverflowRelayout) {
// Our proprietary overflow: overlay value doesn't trigger a layout.
m_inOverflowRelayout = true;
- m_object->setNeedsLayout(true);
- if (m_object->isRenderBlock())
- static_cast<RenderBlock*>(m_object)->layoutBlock(true);
+ renderer()->setNeedsLayout(true, false);
+ if (renderer()->isRenderBlock())
+ static_cast<RenderBlock*>(renderer())->layoutBlock(true);
else
- m_object->layout();
+ renderer()->layout();
m_inOverflowRelayout = false;
}
}
}
// If overflow:scroll is turned into overflow:auto a bar might still be disabled (Bug 11985).
- if (m_hBar && m_object->hasAutoHorizontalScrollbar())
+ if (m_hBar && renderer()->hasAutoHorizontalScrollbar())
m_hBar->setEnabled(true);
- if (m_vBar && m_object->hasAutoVerticalScrollbar())
+ if (m_vBar && renderer()->hasAutoVerticalScrollbar())
m_vBar->setEnabled(true);
// Set up the range (and page step/line step).
if (m_hBar) {
- int clientWidth = m_object->clientWidth();
+ int clientWidth = renderer()->clientWidth();
int pageStep = (clientWidth - cAmountToKeepWhenPaging);
if (pageStep < 0) pageStep = clientWidth;
m_hBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
@@ -1441,21 +1463,21 @@ RenderLayer::updateScrollInfoAfterLayout()
m_hBar->setValue(scrollXOffset());
}
if (m_vBar) {
- int clientHeight = m_object->clientHeight();
+ int clientHeight = renderer()->clientHeight();
int pageStep = (clientHeight - cAmountToKeepWhenPaging);
if (pageStep < 0) pageStep = clientHeight;
m_vBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
m_vBar->setProportion(clientHeight, m_scrollHeight);
}
- if (m_object->element() && m_object->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
+ if (renderer()->element() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(horizontalOverflow, verticalOverflow);
}
void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
{
// Don't do anything if we have no overflow.
- if (!m_object->hasOverflowClip())
+ if (!renderer()->hasOverflowClip())
return;
// Move the scrollbar widgets if necessary. We normally move and resize widgets during layout, but sometimes
@@ -1479,7 +1501,7 @@ void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty
void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
{
- IntRect cornerRect = scrollCornerRect(this, m_object->borderBox());
+ IntRect cornerRect = scrollCornerRect(this, renderer()->borderBoxRect());
IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height());
if (!absRect.intersects(damageRect))
return;
@@ -1499,10 +1521,10 @@ void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, co
void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
{
- if (m_object->style()->resize() == RESIZE_NONE)
+ if (renderer()->style()->resize() == RESIZE_NONE)
return;
- IntRect cornerRect = resizerCornerRect(this, m_object->borderBox());
+ IntRect cornerRect = resizerCornerRect(this, renderer()->borderBoxRect());
IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height());
if (!absRect.intersects(damageRect))
return;
@@ -1518,9 +1540,7 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
}
// Paint the resizer control.
- static RefPtr<Image> resizeCornerImage;
- if (!resizeCornerImage)
- resizeCornerImage = Image::loadPlatformResource("textAreaResizeCorner");
+ DEFINE_STATIC_LOCAL(RefPtr<Image>, resizeCornerImage, (Image::loadPlatformResource("textAreaResizeCorner")));
IntPoint imagePoint(absRect.right() - resizeCornerImage->width(), absRect.bottom() - resizeCornerImage->height());
context->drawImage(resizeCornerImage.get(), imagePoint);
@@ -1538,16 +1558,15 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
}
}
-bool RenderLayer::isPointInResizeControl(const IntPoint& point)
+bool RenderLayer::isPointInResizeControl(const IntPoint& absolutePoint) const
{
- if (!m_object->hasOverflowClip() || m_object->style()->resize() == RESIZE_NONE)
+ if (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE)
return false;
- int x = 0;
- int y = 0;
- convertToLayerCoords(root(), x, y);
- IntRect absBounds(x, y, m_object->width(), m_object->height());
- return resizerCornerRect(this, absBounds).contains(point);
+ IntPoint localPoint = absoluteToContents(absolutePoint);
+
+ IntRect localBounds(0, 0, renderer()->width(), renderer()->height());
+ return resizerCornerRect(this, localBounds).contains(localPoint);
}
bool RenderLayer::hitTestOverflowControls(HitTestResult& result)
@@ -1633,7 +1652,7 @@ static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const
void
RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
const IntRect& paintDirtyRect, bool haveTransparency, PaintRestriction paintRestriction,
- RenderObject* paintingRoot, bool appliedTransform)
+ RenderObject* paintingRoot, bool appliedTransform, bool temporaryClipRects)
{
// Avoid painting layers when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
@@ -1642,7 +1661,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
return;
// If this layer is totally invisible then there is nothing to paint.
- if (!m_object->opacity())
+ if (!renderer()->opacity())
return;
if (isTransparent())
@@ -1662,8 +1681,14 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Make sure the parent's clip rects have been calculated.
IntRect clipRect = paintDirtyRect;
if (parent()) {
- parent()->calculateClipRects(rootLayer);
- clipRect = parent()->clipRects()->overflowClipRect();
+ if (temporaryClipRects) {
+ ClipRects parentClipRects;
+ parent()->calculateClipRects(rootLayer, parentClipRects);
+ clipRect = parentClipRects.overflowClipRect();
+ } else {
+ parent()->updateClipRects(rootLayer);
+ clipRect = parent()->clipRects()->overflowClipRect();
+ }
clipRect.intersect(paintDirtyRect);
}
@@ -1675,7 +1700,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
int x = 0;
int y = 0;
convertToLayerCoords(rootLayer, x, y);
- AffineTransform transform;
+ TransformationMatrix transform;
transform.translate(x, y);
transform = *m_transform * transform;
@@ -1684,7 +1709,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
p->concatCTM(transform);
// Now do a paint with the root layer shifted to be us.
- paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), haveTransparency, paintRestriction, paintingRoot, true);
+ paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), haveTransparency, paintRestriction, paintingRoot, true, temporaryClipRects);
p->restore();
@@ -1698,17 +1723,17 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (m_reflection && !m_paintingInsideReflection && (!m_transform || appliedTransform)) {
// Mark that we are now inside replica painting.
m_paintingInsideReflection = true;
- reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
+ reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot, false, temporaryClipRects);
m_paintingInsideReflection = false;
}
// Calculate the clip rects we should use.
IntRect layerBounds, damageRect, clipRectToApply, outlineRect;
- calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
+ calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, temporaryClipRects);
int x = layerBounds.x();
int y = layerBounds.y();
- int tx = x - renderer()->xPos();
- int ty = y - renderer()->yPos() + renderer()->borderTopExtra();
+ int tx = x - renderer()->x();
+ int ty = y - renderer()->y();
// Ensure our lists are up-to-date.
updateZOrderLists();
@@ -1722,7 +1747,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Else, our renderer tree may or may not contain the painting root, so we pass that root along
// so it will be tested against as we decend through the renderers.
RenderObject* paintingRootForRenderer = 0;
- if (paintingRoot && !m_object->isDescendantOf(paintingRoot))
+ if (paintingRoot && !renderer()->isDescendantOf(paintingRoot))
paintingRootForRenderer = paintingRoot;
// We want to paint our layer, but only if we intersect the damage rect.
@@ -1752,7 +1777,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Now walk the sorted list of children with negative z-indices.
if (m_negZOrderList)
for (Vector<RenderLayer*>::iterator it = m_negZOrderList->begin(); it != m_negZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot, false, temporaryClipRects);
// Now establish the appropriate clip and paint our child RenderObjects.
if (shouldPaint && !clipRectToApply.isEmpty()) {
@@ -1790,12 +1815,12 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Paint any child layers that have overflow.
if (m_overflowList)
for (Vector<RenderLayer*>::iterator it = m_overflowList->begin(); it != m_overflowList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot, false, temporaryClipRects);
// Now walk the sorted list of children with positive z-indices.
if (m_posZOrderList)
for (Vector<RenderLayer*>::iterator it = m_posZOrderList->begin(); it != m_posZOrderList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot, false, temporaryClipRects);
if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
setClip(p, paintDirtyRect, damageRect);
@@ -1873,7 +1898,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequ
// Make sure the parent's clip rects have been calculated.
if (parent()) {
- parent()->calculateClipRects(rootLayer);
+ parent()->updateClipRects(rootLayer);
// Go ahead and test the enclosing clip now.
IntRect clipRect = parent()->clipRects()->overflowClipRect();
@@ -1886,7 +1911,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequ
int x = 0;
int y = 0;
convertToLayerCoords(rootLayer, x, y);
- AffineTransform transform;
+ TransformationMatrix transform;
transform.translate(x, y);
transform = *m_transform * transform;
@@ -1931,8 +1956,8 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequ
// Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
if (fgRect.contains(hitTestPoint) &&
renderer()->hitTest(request, result, hitTestPoint,
- layerBounds.x() - renderer()->xPos(),
- layerBounds.y() - renderer()->yPos() + m_object->borderTopExtra(),
+ layerBounds.x() - renderer()->x(),
+ layerBounds.y() - renderer()->y(),
HitTestDescendants)) {
// For positioned generated content, we might still not have a
// node by the time we get to the layer level, since none of
@@ -1961,8 +1986,8 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequ
// Next we want to see if the mouse is inside this layer but not any of its children.
if (bgRect.contains(hitTestPoint) &&
renderer()->hitTest(request, result, hitTestPoint,
- layerBounds.x() - renderer()->xPos(),
- layerBounds.y() - renderer()->yPos() + m_object->borderTopExtra(),
+ layerBounds.x() - renderer()->x(),
+ layerBounds.y() - renderer()->y(),
HitTestSelf)) {
if (!result.innerNode() || !result.innerNonSharedNode()) {
Node* e = enclosingElement();
@@ -1986,16 +2011,38 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequ
return 0;
}
-void RenderLayer::calculateClipRects(const RenderLayer* rootLayer)
+void RenderLayer::updateClipRects(const RenderLayer* rootLayer)
{
- if (m_clipRects)
+ if (m_clipRects) {
+ ASSERT(rootLayer == m_clipRectsRoot);
return; // We have the correct cached value.
+ }
+
+ // For transformed layers, the root layer was shifted to be us, so there is no need to
+ // examine the parent. We want to cache clip rects with us as the root.
+ RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
+ if (parentLayer)
+ parentLayer->updateClipRects(rootLayer);
+ ClipRects clipRects;
+ calculateClipRects(rootLayer, clipRects, true);
+
+ if (parentLayer && parentLayer->clipRects() && clipRects == *parentLayer->clipRects())
+ m_clipRects = parentLayer->clipRects();
+ else
+ m_clipRects = new (renderer()->renderArena()) ClipRects(clipRects);
+ m_clipRects->ref();
+#ifndef NDEBUG
+ m_clipRectsRoot = rootLayer;
+#endif
+}
+
+void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool useCached) const
+{
IntRect infiniteRect(INT_MIN/2, INT_MIN/2, INT_MAX, INT_MAX);
if (!parent()) {
// The root layer's clip rect is always infinite.
- m_clipRects = new (m_object->renderArena()) ClipRects(infiniteRect);
- m_clipRects->ref();
+ clipRects.reset(infiniteRect);
return;
}
@@ -2004,100 +2051,95 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer)
RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
// Ensure that our parent's clip has been calculated so that we can examine the values.
- if (parentLayer)
- parentLayer->calculateClipRects(rootLayer);
-
- // Set up our three rects to initially match the parent rects.
- IntRect posClipRect(parentLayer ? parentLayer->clipRects()->posClipRect() : infiniteRect);
- IntRect overflowClipRect(parentLayer ? parentLayer->clipRects()->overflowClipRect() : infiniteRect);
- IntRect fixedClipRect(parentLayer ? parentLayer->clipRects()->fixedClipRect() : infiniteRect);
- bool fixed = parentLayer ? parentLayer->clipRects()->fixed() : false;
+ if (parentLayer) {
+ if (useCached && parentLayer->clipRects())
+ clipRects = *parentLayer->clipRects();
+ else
+ parentLayer->calculateClipRects(rootLayer, clipRects);
+ }
+ else
+ clipRects.reset(infiniteRect);
// A fixed object is essentially the root of its containing block hierarchy, so when
// we encounter such an object, we reset our clip rects to the fixedClipRect.
- if (m_object->style()->position() == FixedPosition) {
- posClipRect = fixedClipRect;
- overflowClipRect = fixedClipRect;
- fixed = true;
+ if (renderer()->style()->position() == FixedPosition) {
+ clipRects.setPosClipRect(clipRects.fixedClipRect());
+ clipRects.setOverflowClipRect(clipRects.fixedClipRect());
+ clipRects.setFixed(true);
}
- else if (m_object->style()->position() == RelativePosition)
- posClipRect = overflowClipRect;
- else if (m_object->style()->position() == AbsolutePosition)
- overflowClipRect = posClipRect;
+ else if (renderer()->style()->position() == RelativePosition)
+ clipRects.setPosClipRect(clipRects.overflowClipRect());
+ else if (renderer()->style()->position() == AbsolutePosition)
+ clipRects.setOverflowClipRect(clipRects.posClipRect());
// Update the clip rects that will be passed to child layers.
- if (m_object->hasOverflowClip() || m_object->hasClip()) {
+ if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
// This layer establishes a clip of some kind.
int x = 0;
int y = 0;
convertToLayerCoords(rootLayer, x, y);
RenderView* view = renderer()->view();
ASSERT(view);
- if (view && fixed && rootLayer->renderer() == view) {
+ if (view && clipRects.fixed() && rootLayer->renderer() == view) {
x -= view->frameView()->scrollX();
y -= view->frameView()->scrollY();
}
- if (m_object->hasOverflowClip()) {
- IntRect newOverflowClip = m_object->getOverflowClipRect(x,y);
- overflowClipRect.intersect(newOverflowClip);
- if (m_object->isPositioned() || m_object->isRelPositioned())
- posClipRect.intersect(newOverflowClip);
+ if (renderer()->hasOverflowClip()) {
+ IntRect newOverflowClip = renderer()->getOverflowClipRect(x,y);
+ clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
+ if (renderer()->isPositioned() || renderer()->isRelPositioned())
+ clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
}
- if (m_object->hasClip()) {
- IntRect newPosClip = m_object->getClipRect(x,y);
- posClipRect.intersect(newPosClip);
- overflowClipRect.intersect(newPosClip);
- fixedClipRect.intersect(newPosClip);
+ if (renderer()->hasClip()) {
+ IntRect newPosClip = renderer()->getClipRect(x,y);
+ clipRects.setPosClipRect(intersection(newPosClip, clipRects.posClipRect()));
+ clipRects.setOverflowClipRect(intersection(newPosClip, clipRects.overflowClipRect()));
+ clipRects.setFixedClipRect(intersection(newPosClip, clipRects.fixedClipRect()));
}
}
-
- // If our clip rects match our parent's clip, then we can just share its data structure and
- // ref count.
- if (parent()->clipRects() &&
- fixed == parent()->clipRects()->fixed() &&
- posClipRect == parent()->clipRects()->posClipRect() &&
- overflowClipRect == parent()->clipRects()->overflowClipRect() &&
- fixedClipRect == parent()->clipRects()->fixedClipRect())
- m_clipRects = parent()->clipRects();
- else
- m_clipRects = new (m_object->renderArena()) ClipRects(overflowClipRect, fixedClipRect, posClipRect, fixed);
- m_clipRects->ref();
}
void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds,
- IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect) const
+ IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects) const
{
if (rootLayer != this && parent()) {
- parent()->calculateClipRects(rootLayer);
+ ClipRects parentClipRects;
+ if (temporaryClipRects)
+ parent()->calculateClipRects(rootLayer, parentClipRects);
+ else {
+ parent()->updateClipRects(rootLayer);
+ parentClipRects = *parent()->clipRects();
+ }
- backgroundRect = m_object->style()->position() == FixedPosition ? parent()->clipRects()->fixedClipRect() :
- (m_object->isPositioned() ? parent()->clipRects()->posClipRect() :
- parent()->clipRects()->overflowClipRect());
+ backgroundRect = renderer()->style()->position() == FixedPosition ? parentClipRects.fixedClipRect() :
+ (renderer()->isPositioned() ? parentClipRects.posClipRect() :
+ parentClipRects.overflowClipRect());
RenderView* view = renderer()->view();
ASSERT(view);
- if (view && parent()->clipRects()->fixed() && rootLayer->renderer() == view)
+ if (view && parentClipRects.fixed() && rootLayer->renderer() == view)
backgroundRect.move(view->frameView()->scrollX(), view->frameView()->scrollY());
backgroundRect.intersect(paintDirtyRect);
} else
backgroundRect = paintDirtyRect;
+
foregroundRect = backgroundRect;
outlineRect = backgroundRect;
int x = 0;
int y = 0;
convertToLayerCoords(rootLayer, x, y);
- layerBounds = IntRect(x,y,width(),height());
+ layerBounds = IntRect(x, y, width(), height());
// Update the clip rects that will be passed to child layers.
- if (m_object->hasOverflowClip() || m_object->hasClip()) {
+ if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
// This layer establishes a clip of some kind.
- if (m_object->hasOverflowClip())
- foregroundRect.intersect(m_object->getOverflowClipRect(x,y));
- if (m_object->hasClip()) {
+ if (renderer()->hasOverflowClip())
+ foregroundRect.intersect(renderer()->getOverflowClipRect(x,y));
+ if (renderer()->hasClip()) {
// Clip applies to *us* as well, so go ahead and update the damageRect.
- IntRect newPosClip = m_object->getClipRect(x,y);
+ IntRect newPosClip = renderer()->getClipRect(x,y);
backgroundRect.intersect(newPosClip);
foregroundRect.intersect(newPosClip);
outlineRect.intersect(newPosClip);
@@ -2122,7 +2164,7 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa
IntRect RenderLayer::childrenClipRect() const
{
- RenderLayer* rootLayer = renderer()->document()->renderer()->layer();
+ RenderLayer* rootLayer = renderer()->view()->layer();
IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
calculateRects(rootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
return foregroundRect;
@@ -2130,7 +2172,7 @@ IntRect RenderLayer::childrenClipRect() const
IntRect RenderLayer::selfClipRect() const
{
- RenderLayer* rootLayer = renderer()->document()->renderer()->layer();
+ RenderLayer* rootLayer = renderer()->view()->layer();
IntRect layerBounds, backgroundRect, foregroundRect, outlineRect;
calculateRects(rootLayer, rootLayer->boundingBox(rootLayer), layerBounds, backgroundRect, foregroundRect, outlineRect);
return backgroundRect;
@@ -2148,7 +2190,7 @@ bool RenderLayer::intersectsDamageRect(const IntRect& layerBounds, const IntRect
// can go ahead and return true.
RenderView* view = renderer()->view();
ASSERT(view);
- if (view && !renderer()->isInlineFlow()) {
+ if (view && !renderer()->isRenderInline()) {
IntRect b = layerBounds;
b.inflate(view->maximalOutlineSize());
if (b.intersects(damageRect))
@@ -2172,7 +2214,7 @@ IntRect RenderLayer::boundingBox(const RenderLayer* rootLayer) const
// as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
// floats.
IntRect result;
- if (renderer()->isInlineFlow()) {
+ if (renderer()->isRenderInline()) {
// Go from our first line box to our last line box.
RenderInline* inlineFlow = static_cast<RenderInline*>(renderer());
InlineFlowBox* firstBox = inlineFlow->firstLineBox();
@@ -2183,16 +2225,14 @@ IntRect RenderLayer::boundingBox(const RenderLayer* rootLayer) const
int left = firstBox->xPos();
for (InlineRunBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
left = min(left, curr->xPos());
- result = IntRect(m_x + left, m_y + (top - renderer()->yPos()), width(), bottom - top);
+ result = IntRect(m_x + left, m_y + (top - renderer()->y()), width(), bottom - top);
} else if (renderer()->isTableRow()) {
// Our bounding box is just the union of all of our cells' border/overflow rects.
for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
- IntRect bbox = child->borderBox();
- bbox.move(0, child->borderTopExtra());
+ IntRect bbox = toRenderBox(child)->borderBoxRect();
result.unite(bbox);
IntRect overflowRect = renderer()->overflowRect(false);
- overflowRect.move(0, child->borderTopExtra());
if (bbox != overflowRect)
result.unite(overflowRect);
}
@@ -2202,7 +2242,7 @@ IntRect RenderLayer::boundingBox(const RenderLayer* rootLayer) const
if (renderer()->hasMask())
result = renderer()->maskClipRect();
else {
- IntRect bbox = renderer()->borderBox();
+ IntRect bbox = renderer()->borderBoxRect();
result = bbox;
IntRect overflowRect = renderer()->overflowRect(false);
if (bbox != overflowRect)
@@ -2210,11 +2250,7 @@ IntRect RenderLayer::boundingBox(const RenderLayer* rootLayer) const
}
// We have to adjust the x/y of this result so that it is in the coordinate space of the layer.
- // We also have to add in borderTopExtra here, since borderBox(), in order to play well with methods like
- // floatRect that deal with child content, uses an origin of (0,0) that is at the child content box (so
- // border box returns a y coord of -borderTopExtra(). The layer, however, uses the outer box. This is all
- // really confusing.
- result.move(m_x, m_y + renderer()->borderTopExtra());
+ result.move(m_x, m_y);
}
// Convert the bounding box to an absolute position. We can do this easily by looking at the delta
@@ -2230,22 +2266,25 @@ IntRect RenderLayer::boundingBox(const RenderLayer* rootLayer) const
return result;
}
-void RenderLayer::clearClipRects()
+void RenderLayer::clearClipRectsIncludingDescendants()
{
if (!m_clipRects)
return;
- clearClipRect();
+ clearClipRects();
for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
- l->clearClipRects();
+ l->clearClipRectsIncludingDescendants();
}
-void RenderLayer::clearClipRect()
+void RenderLayer::clearClipRects()
{
if (m_clipRects) {
- m_clipRects->deref(m_object->renderArena());
+ m_clipRects->deref(renderer()->renderArena());
m_clipRects = 0;
+#ifndef NDEBUG
+ m_clipRectsRoot = 0;
+#endif
}
}
@@ -2425,7 +2464,7 @@ void RenderLayer::collectLayers(Vector<RenderLayer*>*& posBuffer, Vector<RenderL
void RenderLayer::repaintIncludingDescendants()
{
- m_object->repaint();
+ renderer()->repaint();
for (RenderLayer* curr = firstChild(); curr; curr = curr->nextSibling())
curr->repaintIncludingDescendants();
}
@@ -2439,7 +2478,7 @@ bool RenderLayer::shouldBeOverflowOnly() const
!isTransparent();
}
-void RenderLayer::styleChanged(RenderStyle::Diff, const RenderStyle* oldStyle)
+void RenderLayer::styleChanged(RenderStyle::Diff, const RenderStyle*)
{
bool isOverflowOnly = shouldBeOverflowOnly();
if (isOverflowOnly != m_isOverflowOnly) {
@@ -2450,7 +2489,7 @@ void RenderLayer::styleChanged(RenderStyle::Diff, const RenderStyle* oldStyle)
dirtyStackingContextZOrderLists();
}
- if (m_object->style()->overflowX() == OMARQUEE && m_object->style()->marqueeBehavior() != MNONE) {
+ if (renderer()->style()->overflowX() == OMARQUEE && renderer()->style()->marqueeBehavior() != MNONE) {
if (!m_marquee)
m_marquee = new RenderMarquee(this);
m_marquee->updateMarqueeStyle();
@@ -2481,12 +2520,12 @@ void RenderLayer::styleChanged(RenderStyle::Diff, const RenderStyle* oldStyle)
void RenderLayer::updateScrollCornerStyle()
{
- RenderObject* actualRenderer = m_object->node()->isElementNode() ? m_object->node()->shadowAncestorNode()->renderer() : m_object;
- RefPtr<RenderStyle> corner = m_object->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RenderStyle::SCROLLBAR_CORNER, actualRenderer->style()) : 0;
+ RenderObject* actualRenderer = renderer()->node()->isElementNode() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
+ RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RenderStyle::SCROLLBAR_CORNER, actualRenderer->style()) : 0;
if (corner) {
if (!m_scrollCorner) {
- m_scrollCorner = new (m_object->renderArena()) RenderScrollbarPart(m_object->document());
- m_scrollCorner->setParent(m_object);
+ m_scrollCorner = new (renderer()->renderArena()) RenderScrollbarPart(renderer()->document());
+ m_scrollCorner->setParent(renderer());
}
m_scrollCorner->setStyle(corner.release());
} else if (m_scrollCorner) {
@@ -2497,12 +2536,12 @@ void RenderLayer::updateScrollCornerStyle()
void RenderLayer::updateResizerStyle()
{
- RenderObject* actualRenderer = m_object->node()->isElementNode() ? m_object->node()->shadowAncestorNode()->renderer() : m_object;
- RefPtr<RenderStyle> resizer = m_object->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RenderStyle::RESIZER, actualRenderer->style()) : 0;
+ RenderObject* actualRenderer = renderer()->node()->isElementNode() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
+ RefPtr<RenderStyle> resizer = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RenderStyle::RESIZER, actualRenderer->style()) : 0;
if (resizer) {
if (!m_resizer) {
- m_resizer = new (m_object->renderArena()) RenderScrollbarPart(m_object->document());
- m_resizer->setParent(m_object);
+ m_resizer = new (renderer()->renderArena()) RenderScrollbarPart(renderer()->document());
+ m_resizer->setParent(renderer());
}
m_resizer->setStyle(resizer.release());
} else if (m_resizer) {