summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderLayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderLayer.cpp')
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp110
1 files changed, 67 insertions, 43 deletions
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 75986335e..c850a2f4d 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -80,6 +80,7 @@
#include "RenderInline.h"
#include "RenderMarquee.h"
#include "RenderReplica.h"
+#include "RenderSVGResourceClipper.h"
#include "RenderScrollbar.h"
#include "RenderScrollbarPart.h"
#include "RenderTheme.h"
@@ -109,9 +110,7 @@
#include "SVGNames.h"
#endif
-#if PLATFORM(CHROMIUM) || PLATFORM(BLACKBERRY)
-// FIXME: border radius clipping triggers too-slow path on Chromium
-// https://bugs.webkit.org/show_bug.cgi?id=69866
+#if PLATFORM(BLACKBERRY)
#define DISABLE_ROUNDED_CORNER_CLIPPING
#endif
@@ -131,7 +130,7 @@ bool ClipRect::intersects(const HitTestLocation& hitTestLocation)
return hitTestLocation.intersects(m_rect);
}
-RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
+RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
: m_inResizeMode(false)
, m_scrollDimensionsDirty(true)
, m_normalFlowListDirty(true)
@@ -392,7 +391,7 @@ void RenderLayer::updateLayerPositions(LayoutPoint* offsetFromRoot, UpdateLayerP
// LayoutState outside the layout() phase and use it here.
ASSERT(!view->layoutStateEnabled());
- RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
+ RenderLayerModelObject* repaintContainer = renderer()->containerForRepaint();
LayoutRect oldRepaintRect = m_repaintRect;
LayoutRect oldOutlineBox = m_outlineBox;
computeRepaintRects(offsetFromRoot);
@@ -489,7 +488,7 @@ void RenderLayer::computeRepaintRects(LayoutPoint* offsetFromRoot)
{
ASSERT(!m_visibleContentStatusDirty);
- RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
+ RenderLayerModelObject* repaintContainer = renderer()->containerForRepaint();
m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer, offsetFromRoot);
}
@@ -630,10 +629,10 @@ TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavio
return *m_transform;
}
-static bool checkContainingBlockChainForPagination(RenderBoxModelObject* renderer, RenderBox* ancestorColumnsRenderer)
+static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
{
RenderView* view = renderer->view();
- RenderBoxModelObject* prevBlock = renderer;
+ RenderLayerModelObject* prevBlock = renderer;
RenderBlock* containingBlock;
for (containingBlock = renderer->containingBlock();
containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer;
@@ -894,7 +893,7 @@ void RenderLayer::updateLayerPosition()
}
if (renderer()->isInFlowPositioned()) {
- m_offsetForInFlowPosition = renderer()->offsetForInFlowPosition();
+ m_offsetForInFlowPosition = toRenderBoxModelObject(renderer())->offsetForInFlowPosition();
localPoint.move(m_offsetForInFlowPosition);
} else {
m_offsetForInFlowPosition = LayoutSize();
@@ -957,7 +956,7 @@ RenderLayer* RenderLayer::stackingContext() const
static inline bool isPositionedContainer(RenderLayer* layer)
{
- RenderBoxModelObject* layerRenderer = layer->renderer();
+ RenderLayerModelObject* layerRenderer = layer->renderer();
return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTransform();
}
@@ -1135,7 +1134,7 @@ void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect,
bool RenderLayer::hasAncestorWithFilterOutsets() const
{
for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
- RenderBoxModelObject* renderer = curr->renderer();
+ RenderLayerModelObject* renderer = curr->renderer();
if (renderer->style()->hasFilterOutsets())
return true;
}
@@ -1172,7 +1171,7 @@ RenderLayer* RenderLayer::clippingRootForPainting() const
LayoutPoint RenderLayer::absoluteToContents(const LayoutPoint& absolutePoint) const
{
// We don't use convertToLayerCoords because it doesn't know about transforms
- return roundedLayoutPoint(renderer()->absoluteToLocal(absolutePoint, false, true));
+ return roundedLayoutPoint(renderer()->absoluteToLocal(absolutePoint, UseTransforms | SnapOffsetForTransforms));
}
bool RenderLayer::cannotBlitToWindow() const
@@ -1481,7 +1480,7 @@ void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutP
if (position == FixedPosition && !renderer()->inRenderFlowThread() && (!ancestorLayer || ancestorLayer == renderer()->view()->layer())) {
// If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
// localToAbsolute() on the RenderView.
- FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
+ FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), IsFixed);
location += LayoutSize(absPos.x(), absPos.y());
return;
}
@@ -1718,10 +1717,9 @@ void RenderLayer::scrollTo(int x, int y)
// We should have a RenderView if we're trying to scroll.
ASSERT(view);
if (view) {
-#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION)
- // Update dashboard regions, scrolling may change the clip of a
- // particular region.
- view->frameView()->updateDashboardRegions();
+ // Update regions, scrolling may change the clip of a particular region.
+#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
+ view->frameView()->updateAnnotatedRegions();
#endif
view->updateWidgetPositions();
@@ -1735,7 +1733,7 @@ void RenderLayer::scrollTo(int x, int y)
updateCompositingLayersAfterScroll();
}
- RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
+ RenderLayerModelObject* repaintContainer = renderer()->containerForRepaint();
Frame* frame = renderer()->frame();
if (frame) {
// The caret rect needs to be invalidated after scrolling
@@ -1743,7 +1741,7 @@ void RenderLayer::scrollTo(int x, int y)
FloatQuad quadForFakeMouseMoveEvent = FloatQuad(m_repaintRect);
if (repaintContainer)
- quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
+ quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent, SnapOffsetForTransforms);
frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
}
@@ -1756,6 +1754,21 @@ void RenderLayer::scrollTo(int x, int y)
renderer()->node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(renderer()->node(), DocumentEventQueue::ScrollEventElementTarget);
}
+static inline bool frameElementAndViewPermitScroll(HTMLFrameElement* frameElement, FrameView* frameView)
+{
+ // If scrollbars aren't explicitly forbidden, permit scrolling.
+ if (frameElement && frameElement->scrollingMode() != ScrollbarAlwaysOff)
+ return true;
+
+ // If scrollbars are forbidden, user initiated scrolls should obviously be ignored.
+ if (frameView->wasScrolledByUser())
+ return false;
+
+ // Forbid autoscrolls when scrollbars are off, but permits other programmatic scrolls,
+ // like navigation to an anchor.
+ return !frameView->frame()->eventHandler()->autoscrollInProgress();
+}
+
void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
{
RenderLayer* parentLayer = 0;
@@ -1806,7 +1819,7 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignm
if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))
frameElement = static_cast<HTMLFrameElement*>(ownerElement);
- if (frameElement && frameElement->scrollingMode() != ScrollbarAlwaysOff) {
+ if (frameElementAndViewPermitScroll(frameElement, frameView)) {
LayoutRect viewRect = frameView->visibleContentRect();
LayoutRect exposeRect = getRectToExpose(viewRect, rect, alignX, alignY);
@@ -2378,10 +2391,10 @@ void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
if (m_vBar)
m_vBar->styleChanged();
-#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION)
// Force an update since we know the scrollbars have changed things.
- if (renderer()->document()->hasDashboardRegions())
- renderer()->document()->setDashboardRegionsDirty(true);
+#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
+ if (renderer()->document()->hasAnnotatedRegions())
+ renderer()->document()->setAnnotatedRegionsDirty(true);
#endif
}
@@ -2401,10 +2414,10 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
if (m_vBar)
m_vBar->styleChanged();
-#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION)
// Force an update since we know the scrollbars have changed things.
- if (renderer()->document()->hasDashboardRegions())
- renderer()->document()->setDashboardRegionsDirty(true);
+#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
+ if (renderer()->document()->hasAnnotatedRegions())
+ renderer()->document()->setAnnotatedRegionsDirty(true);
#endif
}
@@ -2591,10 +2604,10 @@ void RenderLayer::updateScrollbarsAfterLayout()
updateSelfPaintingLayer();
-#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION)
// Force an update since we know the scrollbars have changed things.
- if (renderer()->document()->hasDashboardRegions())
- renderer()->document()->setDashboardRegionsDirty(true);
+#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
+ if (renderer()->document()->hasAnnotatedRegions())
+ renderer()->document()->setAnnotatedRegionsDirty(true);
#endif
renderer()->repaint();
@@ -2629,7 +2642,7 @@ void RenderLayer::updateScrollbarsAfterLayout()
m_vBar->setProportion(clientHeight, m_scrollSize.height());
}
- updateScrollableAreaSet((hasHorizontalOverflow || hasVerticalOverflow) && scrollsOverflow());
+ updateScrollableAreaSet((hasHorizontalOverflow || hasVerticalOverflow) && scrollsOverflow() && allowsScrolling());
}
void RenderLayer::updateScrollInfoAfterLayout()
@@ -2890,7 +2903,7 @@ void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect,
paintLayer(this, context, enclosingIntRect(damageRect), LayoutSize(), paintBehavior, paintingRoot, region, &overlapTestRequests, paintFlags);
OverlapTestRequestMap::iterator end = overlapTestRequests.end();
for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
- it->first->setOverlapTestResult(false);
+ it->key->setOverlapTestResult(false);
}
void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot)
@@ -2959,11 +2972,11 @@ static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, cons
OverlapTestRequestMap::iterator end = overlapTestRequests.end();
LayoutRect boundingBox = layer->boundingBox(rootLayer);
for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) {
- if (!boundingBox.intersects(it->second))
+ if (!boundingBox.intersects(it->value))
continue;
- it->first->setOverlapTestResult(true);
- overlappedRequestClients.append(it->first);
+ it->key->setOverlapTestResult(true);
+ overlappedRequestClients.append(it->key);
}
for (size_t i = 0; i < overlappedRequestClients.size(); ++i)
overlapTestRequests.remove(overlappedRequestClients[i]);
@@ -3140,6 +3153,16 @@ void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* co
ShapeClipPathOperation* clipPath = static_cast<ShapeClipPathOperation*>(style->clipPath());
context->clipPath(clipPath->path(calculateLayerBounds(this, rootLayer, 0)), clipPath->windRule());
}
+#if ENABLE(SVG)
+ else if (style->clipPath()->getOperationType() == ClipPathOperation::REFERENCE) {
+ ReferenceClipPathOperation* referenceClipPathOperation = static_cast<ReferenceClipPathOperation*>(style->clipPath());
+ Document* document = renderer()->document();
+ // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
+ Element* clipPath = document ? document->getElementById(referenceClipPathOperation->fragment()) : 0;
+ if (clipPath && clipPath->renderer() && clipPath->renderer()->isSVGResourceContainer())
+ static_cast<RenderSVGResourceClipper*>(clipPath->renderer())->applyClippingToContext(renderer(), calculateLayerBounds(this, rootLayer, 0), paintDirtyRect, context);
+ }
+#endif
}
#if ENABLE(CSS_FILTERS)
@@ -3177,6 +3200,8 @@ void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* co
calculateRects(rootLayer, region, (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect,
IgnoreOverlayScrollbarSize, localPaintFlags & PaintLayerPaintingOverflowContents ? IgnoreOverflowClip : RespectOverflowClip);
paintOffset = toPoint(layerBounds.location() - renderBoxLocation() + subPixelAccumulation);
+ if (this == rootLayer)
+ paintOffset = roundedIntPoint(paintOffset);
}
bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText;
@@ -4017,7 +4042,7 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion*
// some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where
// clipRects are needed in view space.
LayoutPoint offset;
- offset = roundedLayoutPoint(renderer()->localToContainerPoint(FloatPoint(), rootLayer->renderer(), false, false, 0));
+ offset = roundedLayoutPoint(renderer()->localToContainerPoint(FloatPoint(), rootLayer->renderer()));
RenderView* view = renderer()->view();
ASSERT(view);
if (view && clipRects.fixed() && rootLayer->renderer() == view) {
@@ -4144,7 +4169,7 @@ LayoutRect RenderLayer::childrenClipRect() const
ClipRect backgroundRect, foregroundRect, outlineRect;
// Need to use temporary clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>).
calculateRects(clippingRootLayer, 0, TemporaryClipRects, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
- return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
+ return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect()), SnapOffsetForTransforms).enclosingBoundingBox();
}
LayoutRect RenderLayer::selfClipRect() const
@@ -4156,7 +4181,7 @@ LayoutRect RenderLayer::selfClipRect() const
LayoutRect layerBounds;
ClipRect backgroundRect, foregroundRect, outlineRect;
calculateRects(clippingRootLayer, 0, PaintingClipRects, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
- return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox();
+ return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect()), SnapOffsetForTransforms).enclosingBoundingBox();
}
LayoutRect RenderLayer::localClipRect() const
@@ -4704,7 +4729,7 @@ void RenderLayer::setBackingNeedsRepaintInRect(const LayoutRect& r)
}
// Since we're only painting non-composited layers, we know that they all share the same repaintContainer.
-void RenderLayer::repaintIncludingNonCompositingDescendants(RenderBoxModelObject* repaintContainer)
+void RenderLayer::repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer)
{
renderer()->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(renderer()->clippedOverflowRectForRepaint(repaintContainer)));
@@ -4835,7 +4860,7 @@ void RenderLayer::updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle)
}
if (!m_scrollDimensionsDirty)
- updateScrollableAreaSet((hasHorizontalOverflow() || hasVerticalOverflow()) && scrollsOverflow());
+ updateScrollableAreaSet((hasHorizontalOverflow() || hasVerticalOverflow()) && scrollsOverflow() && allowsScrolling());
}
void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
@@ -4882,10 +4907,6 @@ void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
updateScrollCornerStyle();
updateResizerStyle();
-#if ENABLE(CSS_FILTERS)
- bool backingDidCompositeLayers = isComposited() && backing()->canCompositeFilters();
-#endif
-
updateDescendantDependentFlags();
updateTransform();
#if ENABLE(CSS_COMPOSITING)
@@ -4907,12 +4928,15 @@ void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
#if ENABLE(CSS_FILTERS)
updateOrRemoveFilterEffect();
+#if USE(ACCELERATED_COMPOSITING)
+ bool backingDidCompositeLayers = isComposited() && backing()->canCompositeFilters();
if (isComposited() && backingDidCompositeLayers && !backing()->canCompositeFilters()) {
// The filters used to be drawn by platform code, but now the platform cannot draw them anymore.
// Fallback to drawing them in software.
setBackingNeedsRepaint();
}
#endif
+#endif
}
void RenderLayer::updateScrollableAreaSet(bool hasOverflow)