bool SVGClipPainter::prepareEffect(const LayoutObject& target, const FloatRect& targetBoundingBox, const FloatRect& paintInvalidationRect, GraphicsContext& context, ClipperState& clipperState) { ASSERT(clipperState == ClipperNotApplied); ASSERT_WITH_SECURITY_IMPLICATION(!m_clip.needsLayout()); m_clip.clearInvalidationMask(); if (paintInvalidationRect.isEmpty() || m_clip.hasCycle()) return false; SVGClipExpansionCycleHelper inClipExpansionChange(m_clip); AffineTransform animatedLocalTransform = toSVGClipPathElement(m_clip.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() && m_clip.clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { ASSERT(m_clip.style()); animatedLocalTransform.scale(m_clip.style()->effectiveZoom()); } // First, try to apply the clip as a clipPath. Path clipPath; if (m_clip.asPath(animatedLocalTransform, targetBoundingBox, clipPath)) { clipperState = ClipperAppliedPath; context.getPaintController().createAndAppend<BeginClipPathDisplayItem>(target, clipPath); return true; } // Fall back to masking. clipperState = ClipperAppliedMask; // Begin compositing the clip mask. CompositingRecorder::beginCompositing(context, target, SkXfermode::kSrcOver_Mode, 1, &paintInvalidationRect); { if (!drawClipAsMask(context, target, targetBoundingBox, paintInvalidationRect, animatedLocalTransform)) { // End the clip mask's compositor. CompositingRecorder::endCompositing(context, target); return false; } } // Masked content layer start. CompositingRecorder::beginCompositing(context, target, SkXfermode::kSrcIn_Mode, 1, &paintInvalidationRect); return true; }
bool SVGClipPainter::prepareEffect(const LayoutObject& target, const FloatRect& targetBoundingBox, const FloatRect& visualRect, const FloatPoint& layerPositionOffset, GraphicsContext& context, ClipperState& clipperState) { DCHECK_EQ(clipperState, ClipperState::NotApplied); SECURITY_DCHECK(!m_clip.needsLayout()); m_clip.clearInvalidationMask(); if (m_clip.hasCycle()) return false; SVGClipExpansionCycleHelper inClipExpansionChange(m_clip); AffineTransform animatedLocalTransform = toSVGClipPathElement(m_clip.element()) ->calculateTransform(SVGElement::IncludeMotionTransform); // 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() && m_clip.clipPathUnits() == SVGUnitTypes::kSvgUnitTypeUserspaceonuse) { DCHECK(m_clip.style()); animatedLocalTransform.scale(m_clip.style()->effectiveZoom()); } // First, try to apply the clip as a clipPath. Path clipPath; if (m_clip.asPath(animatedLocalTransform, targetBoundingBox, clipPath)) { AffineTransform positionTransform; positionTransform.translate(layerPositionOffset.x(), layerPositionOffset.y()); clipPath.transform(positionTransform); clipperState = ClipperState::AppliedPath; context.getPaintController().createAndAppend<BeginClipPathDisplayItem>( target, clipPath); return true; } // Fall back to masking. clipperState = ClipperState::AppliedMask; // Begin compositing the clip mask. CompositingRecorder::beginCompositing(context, target, SkBlendMode::kSrcOver, 1, &visualRect); { if (!drawClipAsMask(context, target, targetBoundingBox, visualRect, animatedLocalTransform, layerPositionOffset)) { // End the clip mask's compositor. CompositingRecorder::endCompositing(context, target); return false; } } // Masked content layer start. CompositingRecorder::beginCompositing(context, target, SkBlendMode::kSrcIn, 1, &visualRect); return true; }