| Index: third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
|
| diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
|
| index ac670bf730d2374730a42870f98319e2bd4f9368..7e61ece73a22c3b7f72d0d65f7e96d894e6bd1a5 100644
|
| --- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
|
| @@ -201,8 +201,7 @@ LayoutRect PaintLayerClipper::localClipRect(
|
| ClipRectsContext context(&clippingRootLayer, PaintingClipRects);
|
| if (m_geometryMapper) {
|
| ClipRect clipRect;
|
| - calculateClipRectWithGeometryMapper(context, false, clipRect);
|
| - applyOverflowClipToBackgroundRectWithGeometryMapper(context, clipRect);
|
| + calculateBackgroundClipRectWithGeometryMapper(context, clipRect);
|
| LayoutRect premappedRect = clipRect.rect();
|
|
|
| // The rect now needs to be transformed to the local space of this
|
| @@ -257,29 +256,6 @@ LayoutRect PaintLayerClipper::localClipRect(
|
| } while (false);
|
| #endif
|
|
|
| -void PaintLayerClipper::mapLocalToRootWithGeometryMapper(
|
| - const ClipRectsContext& context,
|
| - LayoutRect& rectToMap) const {
|
| - DCHECK(m_geometryMapper);
|
| -
|
| - const auto* layerTransform = m_layer.layoutObject()
|
| - .paintProperties()
|
| - ->localBorderBoxProperties()
|
| - ->transform();
|
| - const auto* rootTransform = context.rootLayer->layoutObject()
|
| - .paintProperties()
|
| - ->localBorderBoxProperties()
|
| - ->transform();
|
| -
|
| - FloatRect floatRect(rectToMap);
|
| - floatRect.moveBy(FloatPoint(m_layer.layoutObject().paintOffset()));
|
| - m_geometryMapper->sourceToDestinationRect(layerTransform, rootTransform,
|
| - floatRect);
|
| - rectToMap = LayoutRect(floatRect);
|
| - rectToMap.moveBy(-context.rootLayer->layoutObject().paintOffset());
|
| - rectToMap.move(context.subPixelAccumulation);
|
| -}
|
| -
|
| void PaintLayerClipper::calculateRectsWithGeometryMapper(
|
| const ClipRectsContext& context,
|
| const LayoutRect& paintDirtyRect,
|
| @@ -293,15 +269,11 @@ void PaintLayerClipper::calculateRectsWithGeometryMapper(
|
| backgroundRect = ClipRect(LayoutRect(LayoutRect::infiniteIntRect()));
|
| foregroundRect = ClipRect(LayoutRect(LayoutRect::infiniteIntRect()));
|
| } else {
|
| - calculateClipRectWithGeometryMapper(context, false, backgroundRect);
|
| -
|
| + calculateBackgroundClipRectWithGeometryMapper(context, backgroundRect);
|
| backgroundRect.move(context.subPixelAccumulation);
|
| backgroundRect.intersect(paintDirtyRect);
|
|
|
| - applyOverflowClipToBackgroundRectWithGeometryMapper(context,
|
| - backgroundRect);
|
| -
|
| - calculateClipRectWithGeometryMapper(context, true, foregroundRect);
|
| + calculateForegroundClipRectWithGeometryMapper(context, foregroundRect);
|
| foregroundRect.move(context.subPixelAccumulation);
|
| foregroundRect.intersect(paintDirtyRect);
|
| }
|
| @@ -370,15 +342,7 @@ void PaintLayerClipper::calculateRects(
|
| // FIXME: Does not do the right thing with columns yet, since we don't yet
|
| // factor in the individual column boxes as overflow.
|
|
|
| - // The LayoutView is special since its overflow clipping rect may be larger
|
| - // than its box rect (crbug.com/492871).
|
| - LayoutRect layerBoundsWithVisualOverflow =
|
| - layoutObject.isLayoutView()
|
| - ? toLayoutView(layoutObject).viewRect()
|
| - : toLayoutBox(layoutObject).visualOverflowRect();
|
| - // PaintLayer are in physical coordinates, so the overflow has to be
|
| - // flipped.
|
| - toLayoutBox(layoutObject).flipForWritingMode(layerBoundsWithVisualOverflow);
|
| + LayoutRect layerBoundsWithVisualOverflow = localVisualRect();
|
| layerBoundsWithVisualOverflow.moveBy(offset);
|
| backgroundRect.intersect(layerBoundsWithVisualOverflow);
|
| }
|
| @@ -443,19 +407,60 @@ static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects,
|
| return parentRects.overflowClipRect();
|
| }
|
|
|
| -void PaintLayerClipper::calculateClipRectWithGeometryMapper(
|
| +void PaintLayerClipper::calculateBackgroundClipRectWithGeometryMapper(
|
| const ClipRectsContext& context,
|
| - bool isForeground,
|
| ClipRect& output) const {
|
| DCHECK(m_geometryMapper);
|
| + PropertyTreeState sourcePropertyTreeState(nullptr, nullptr, nullptr);
|
| + PropertyTreeState destinationPropertyTreeState(nullptr, nullptr, nullptr);
|
| + initializeCommonClipRectState(context, sourcePropertyTreeState,
|
| + destinationPropertyTreeState);
|
| + const auto* ancestorProperties =
|
| + context.rootLayer->layoutObject().paintProperties();
|
| +
|
| + if (&m_layer != context.rootLayer) {
|
| + // Set the clip of |destinationPropertyTreeState| to be inside the
|
| + // ancestor's overflow clip, so that that clip is not applied.
|
| + if (context.respectOverflowClip == IgnoreOverflowClip &&
|
| + ancestorProperties->overflowClip())
|
| + destinationPropertyTreeState.setClip(ancestorProperties->overflowClip());
|
| + }
|
| +
|
| + // The background rect applies all clips *above* m_layer, but not the overflow
|
| + // clip of m_layer. It also applies a clip to the total painting bounds
|
| + // of m_layer, because nothing in m_layer or its children within the clip can
|
| + // paint outside of those bounds.
|
| + // The total painting bounds includes any visual overflow (such as shadow) and
|
| + // filter bounds.
|
| + if (shouldClipOverflow(context)) {
|
| + FloatRect clipRect(localVisualRect());
|
| + clipRect.moveBy(FloatPoint(m_layer.layoutObject().paintOffset()));
|
| + m_geometryMapper->sourceToDestinationVisualRect(
|
| + sourcePropertyTreeState, destinationPropertyTreeState, clipRect);
|
| + output.setRect(FloatClipRect(clipRect));
|
| + } else {
|
| + const FloatClipRect& clippedRectInRootLayerSpace =
|
| + m_geometryMapper->sourceToDestinationClipRect(
|
| + sourcePropertyTreeState, destinationPropertyTreeState);
|
| + output.setRect(clippedRectInRootLayerSpace);
|
| + }
|
| +
|
| + output.moveBy(-context.rootLayer->layoutObject().paintOffset());
|
| +}
|
| +
|
| +void PaintLayerClipper::initializeCommonClipRectState(
|
| + const ClipRectsContext& context,
|
| + PropertyTreeState& sourcePropertyTreeState,
|
| + PropertyTreeState& destinationPropertyTreeState) const {
|
| + DCHECK(m_geometryMapper);
|
| const auto* properties = m_layer.layoutObject().paintProperties();
|
| DCHECK(properties && properties->localBorderBoxProperties());
|
|
|
| - PropertyTreeState propertyTreeState = *properties->localBorderBoxProperties();
|
| + sourcePropertyTreeState = *properties->localBorderBoxProperties();
|
| const auto* ancestorProperties =
|
| context.rootLayer->layoutObject().paintProperties();
|
| DCHECK(ancestorProperties && ancestorProperties->localBorderBoxProperties());
|
| - PropertyTreeState destinationPropertyTreeState =
|
| + destinationPropertyTreeState =
|
| *ancestorProperties->localBorderBoxProperties();
|
| // CSS clip of the root is always applied.
|
| if (ancestorProperties->cssClip()) {
|
| @@ -464,13 +469,26 @@ void PaintLayerClipper::calculateClipRectWithGeometryMapper(
|
| destinationPropertyTreeState.setClip(
|
| ancestorProperties->cssClip()->parent());
|
| }
|
| +}
|
| +
|
| +void PaintLayerClipper::calculateForegroundClipRectWithGeometryMapper(
|
| + const ClipRectsContext& context,
|
| + ClipRect& output) const {
|
| + DCHECK(m_geometryMapper);
|
| + PropertyTreeState sourcePropertyTreeState(nullptr, nullptr, nullptr);
|
| + PropertyTreeState destinationPropertyTreeState(nullptr, nullptr, nullptr);
|
| + initializeCommonClipRectState(context, sourcePropertyTreeState,
|
| + destinationPropertyTreeState);
|
| + const auto* properties = m_layer.layoutObject().paintProperties();
|
| + const auto* ancestorProperties =
|
| + context.rootLayer->layoutObject().paintProperties();
|
|
|
| if (&m_layer == context.rootLayer) {
|
| - // Set the overflow clip for |propertyTreeState| so that it differs from
|
| - // |destinationPropertyTreeState| in its clip.
|
| - if (isForeground && context.respectOverflowClip == RespectOverflowClip &&
|
| + // Set the overflow clip for |sourcePropertyTreeState| so that it differs
|
| + // from |destinationPropertyTreeState| in its clip.
|
| + if (context.respectOverflowClip == RespectOverflowClip &&
|
| properties->overflowClip())
|
| - propertyTreeState.setClip(properties->overflowClip());
|
| + sourcePropertyTreeState.setClip(properties->overflowClip());
|
| } else {
|
| // Set the clip of |destinationPropertyTreeState| to be inside the
|
| // ancestor's overflow clip, so that that clip is not applied.
|
| @@ -478,26 +496,24 @@ void PaintLayerClipper::calculateClipRectWithGeometryMapper(
|
| ancestorProperties->overflowClip())
|
| destinationPropertyTreeState.setClip(ancestorProperties->overflowClip());
|
|
|
| - // Set the overflow clip for |propertyTreeState| so that it differs from
|
| - // destinationPropertyTreeState| in its clip.
|
| - if (isForeground && properties->overflowClip())
|
| - propertyTreeState.setClip(properties->overflowClip());
|
| + // Set the overflow clip for |sourcePropertyTreeState| so that it differs
|
| + // from destinationPropertyTreeState| in its clip.
|
| + if (properties->overflowClip())
|
| + sourcePropertyTreeState.setClip(properties->overflowClip());
|
| }
|
|
|
| const FloatClipRect& clippedRectInRootLayerSpace =
|
| m_geometryMapper->sourceToDestinationClipRect(
|
| - propertyTreeState, destinationPropertyTreeState);
|
| + sourcePropertyTreeState, destinationPropertyTreeState);
|
| output.setRect(clippedRectInRootLayerSpace);
|
|
|
| output.moveBy(-context.rootLayer->layoutObject().paintOffset());
|
| }
|
|
|
| -void PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper(
|
| - const ClipRectsContext& context,
|
| - ClipRect& clip) const {
|
| +LayoutRect PaintLayerClipper::localVisualRect() const {
|
| const LayoutObject& layoutObject = m_layer.layoutObject();
|
| - if (!shouldClipOverflow(context))
|
| - return;
|
| + // The LayoutView is special since its overflow clipping rect may be larger
|
| + // than its box rect (crbug.com/492871).
|
| LayoutRect layerBoundsWithVisualOverflow =
|
| layoutObject.isLayoutView()
|
| ? toLayoutView(layoutObject).viewRect()
|
| @@ -507,8 +523,11 @@ void PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper(
|
| // PaintLayer are in physical coordinates, so the overflow has to be
|
| // flipped.
|
| layerBoundsWithVisualOverflow);
|
| - mapLocalToRootWithGeometryMapper(context, layerBoundsWithVisualOverflow);
|
| - clip.intersect(layerBoundsWithVisualOverflow);
|
| + if (m_layer.paintsWithFilters()) {
|
| + layerBoundsWithVisualOverflow =
|
| + m_layer.mapLayoutRectForFilter(layerBoundsWithVisualOverflow);
|
| + }
|
| + return layerBoundsWithVisualOverflow;
|
| }
|
|
|
| void PaintLayerClipper::calculateBackgroundClipRect(
|
| @@ -521,7 +540,7 @@ void PaintLayerClipper::calculateBackgroundClipRect(
|
| return;
|
| }
|
|
|
| - calculateClipRectWithGeometryMapper(context, false, output);
|
| + calculateBackgroundClipRectWithGeometryMapper(context, output);
|
| #ifdef CHECK_CLIP_RECTS
|
| ClipRect testBackgroundClipRect =
|
| PaintLayerClipper(m_layer, nullptr).backgroundClipRect(context);
|
|
|