Index: Source/core/layout/svg/LayoutSVGResourceClipper.cpp |
diff --git a/Source/core/layout/svg/LayoutSVGResourceClipper.cpp b/Source/core/layout/svg/LayoutSVGResourceClipper.cpp |
index eaccf03569b889c5f0d24517eba4a361f04ffba3..04c460e1cb828e2cdeefa83ebf26688c624e6e33 100644 |
--- a/Source/core/layout/svg/LayoutSVGResourceClipper.cpp |
+++ b/Source/core/layout/svg/LayoutSVGResourceClipper.cpp |
@@ -39,7 +39,6 @@ |
#include "platform/graphics/paint/DisplayItemList.h" |
#include "platform/graphics/paint/DrawingDisplayItem.h" |
#include "third_party/skia/include/core/SkPicture.h" |
-#include "wtf/TemporaryChange.h" |
namespace blink { |
@@ -66,16 +65,6 @@ void LayoutSVGResourceClipper::removeClientFromCache(LayoutObject* client, bool |
markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation); |
} |
-bool LayoutSVGResourceClipper::applyStatefulResource(LayoutObject* object, GraphicsContext*& context, ClipperState& clipperState) |
-{ |
- ASSERT(object); |
- ASSERT(context); |
- |
- clearInvalidationMask(); |
- |
- return applyClippingToContext(object, object->objectBoundingBox(), object->paintInvalidationRectInLocalCoordinates(), context, clipperState); |
-} |
- |
bool LayoutSVGResourceClipper::tryPathOnlyClipping(DisplayItemClient client, GraphicsContext* context, |
const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox) { |
// If the current clip-path gets clipped itself, we have to fallback to masking. |
@@ -146,117 +135,19 @@ bool LayoutSVGResourceClipper::tryPathOnlyClipping(DisplayItemClient client, Gra |
return true; |
} |
-bool LayoutSVGResourceClipper::applyClippingToContext(LayoutObject* target, const FloatRect& targetBoundingBox, |
- const FloatRect& paintInvalidationRect, GraphicsContext* context, ClipperState& clipperState) |
-{ |
- ASSERT(target); |
- ASSERT(context); |
- ASSERT(clipperState == ClipperNotApplied); |
- ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout()); |
- |
- if (paintInvalidationRect.isEmpty() || m_inClipExpansion) |
- return false; |
- TemporaryChange<bool> inClipExpansionChange(m_inClipExpansion, true); |
- |
- AffineTransform animatedLocalTransform = toSVGClipPathElement(element())->calculateAnimatedLocalTransform(); |
- // When drawing a clip for non-SVG elements, the CTM does not include the zoom factor. |
- // In this case, we need to apply the zoom scale explicitly - but only for clips with |
- // userSpaceOnUse units (the zoom is accounted for objectBoundingBox-resolved lengths). |
- if (!target->isSVG() && clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { |
- ASSERT(style()); |
- animatedLocalTransform.scale(style()->effectiveZoom()); |
- } |
- |
- // First, try to apply the clip as a clipPath. |
- if (tryPathOnlyClipping(target->displayItemClient(), context, animatedLocalTransform, targetBoundingBox)) { |
- clipperState = ClipperAppliedPath; |
- return true; |
- } |
- |
- // Fall back to masking. |
- clipperState = ClipperAppliedMask; |
- |
- // Begin compositing the clip mask. |
- CompositingRecorder::beginCompositing(context, target->displayItemClient(), SkXfermode::kSrcOver_Mode, 1, &paintInvalidationRect); |
- { |
- TransformRecorder recorder(*context, target->displayItemClient(), animatedLocalTransform); |
- |
- // clipPath can also be clipped by another clipPath. |
- SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(this); |
- LayoutSVGResourceClipper* clipPathClipper = resources ? resources->clipper() : 0; |
- ClipperState clipPathClipperState = ClipperNotApplied; |
- if (clipPathClipper && !clipPathClipper->applyClippingToContext(this, targetBoundingBox, paintInvalidationRect, context, clipPathClipperState)) { |
- // End the clip mask's compositor. |
- CompositingRecorder::endCompositing(context, target->displayItemClient()); |
- return false; |
- } |
- |
- drawClipMaskContent(context, target->displayItemClient(), targetBoundingBox); |
- |
- if (clipPathClipper) |
- clipPathClipper->postApplyStatefulResource(this, context, clipPathClipperState); |
- } |
- |
- // Masked content layer start. |
- CompositingRecorder::beginCompositing(context, target->displayItemClient(), SkXfermode::kSrcIn_Mode, 1, &paintInvalidationRect); |
- |
- return true; |
-} |
- |
-void LayoutSVGResourceClipper::postApplyStatefulResource(LayoutObject* target, GraphicsContext*& context, ClipperState& clipperState) |
-{ |
- switch (clipperState) { |
- case ClipperAppliedPath: |
- // Path-only clipping, no layers to restore but we need to emit an end to the clip path display item. |
- { |
- if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { |
- context->displayItemList()->add(EndClipPathDisplayItem::create(target->displayItemClient())); |
- } else { |
- EndClipPathDisplayItem endClipPathDisplayItem(target->displayItemClient()); |
- endClipPathDisplayItem.replay(context); |
- } |
- } |
- break; |
- case ClipperAppliedMask: |
- // Transfer content -> clip mask (SrcIn) |
- CompositingRecorder::endCompositing(context, target->displayItemClient()); |
- |
- // Transfer clip mask -> bg (SrcOver) |
- CompositingRecorder::endCompositing(context, target->displayItemClient()); |
- break; |
- default: |
- ASSERT_NOT_REACHED(); |
- } |
-} |
- |
-void LayoutSVGResourceClipper::drawClipMaskContent(GraphicsContext* context, DisplayItemClient client, const FloatRect& targetBoundingBox) |
+PassRefPtr<const SkPicture> LayoutSVGResourceClipper::createContentPicture(AffineTransform& contentTransformation, const FloatRect& targetBoundingBox) |
{ |
- ASSERT(context); |
+ ASSERT(frame()); |
- AffineTransform contentTransformation; |
if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { |
contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox.y()); |
contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height()); |
} |
- if (!m_clipContentPicture) { |
- SubtreeContentTransformScope contentTransformScope(contentTransformation); |
- m_clipContentPicture = createPicture(); |
- } |
+ if (m_clipContentPicture) |
+ return m_clipContentPicture; |
- TransformRecorder recorder(*context, client, contentTransformation); |
- if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { |
- ASSERT(context->displayItemList()); |
- context->displayItemList()->add(DrawingDisplayItem::create(client, DisplayItem::SVGClip, m_clipContentPicture)); |
- } else { |
- DrawingDisplayItem clipPicture(client, DisplayItem::SVGClip, m_clipContentPicture); |
- clipPicture.replay(context); |
- } |
-} |
- |
-PassRefPtr<const SkPicture> LayoutSVGResourceClipper::createPicture() |
-{ |
- ASSERT(frame()); |
+ SubtreeContentTransformScope contentTransformScope(contentTransformation); |
// Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection |
// with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and |
@@ -309,7 +200,8 @@ PassRefPtr<const SkPicture> LayoutSVGResourceClipper::createPicture() |
if (displayItemList) |
displayItemList->replay(&context); |
- return context.endRecording(); |
+ m_clipContentPicture = context.endRecording(); |
+ return m_clipContentPicture; |
} |
void LayoutSVGResourceClipper::calculateClipContentPaintInvalidationRect() |