bool SVGClipPainter::drawClipAsMask( GraphicsContext& context, const LayoutObject& layoutObject, const FloatRect& targetBoundingBox, const FloatRect& targetPaintInvalidationRect, const AffineTransform& localTransform, const FloatPoint& layerPositionOffset) { if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible( context, layoutObject, DisplayItem::kSVGClip)) return true; SkPictureBuilder maskPictureBuilder(targetPaintInvalidationRect, nullptr, &context); GraphicsContext& maskContext = maskPictureBuilder.context(); { TransformRecorder recorder(maskContext, layoutObject, localTransform); // Apply any clip-path clipping this clipPath (nested shape/clipPath.) Optional<ClipPathClipper> nestedClipPathClipper; if (ClipPathOperation* clipPathOperation = m_clip.styleRef().clipPath()) nestedClipPathClipper.emplace(maskContext, *clipPathOperation, m_clip, targetBoundingBox, layerPositionOffset); { AffineTransform contentTransform; if (m_clip.clipPathUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox) { contentTransform.translate(targetBoundingBox.x(), targetBoundingBox.y()); contentTransform.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height()); } SubtreeContentTransformScope contentTransformScope(contentTransform); TransformRecorder contentTransformRecorder(maskContext, layoutObject, contentTransform); maskContext.getPaintController().createAndAppend<DrawingDisplayItem>( layoutObject, DisplayItem::kSVGClip, m_clip.createContentPicture()); } } LayoutObjectDrawingRecorder drawingRecorder(context, layoutObject, DisplayItem::kSVGClip, targetPaintInvalidationRect); sk_sp<SkPicture> maskPicture = maskPictureBuilder.endRecording(); context.drawPicture(maskPicture.get()); return true; }
bool SVGClipPainter::drawClipAsMask(GraphicsContext& context, const LayoutObject& layoutObject, const FloatRect& targetBoundingBox, const FloatRect& targetPaintInvalidationRect, const AffineTransform& localTransform) { if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, layoutObject, DisplayItem::SVGClip)) return true; SkPictureBuilder maskPictureBuilder(targetPaintInvalidationRect, nullptr, &context); GraphicsContext& maskContext = maskPictureBuilder.context(); { TransformRecorder recorder(maskContext, layoutObject, localTransform); // Create a clipPathClipper if this clipPath is clipped by another clipPath. SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(&m_clip); LayoutSVGResourceClipper* clipPathClipper = resources ? resources->clipper() : nullptr; ClipperState clipPathClipperState = ClipperNotApplied; if (clipPathClipper && !SVGClipPainter(*clipPathClipper).prepareEffect(m_clip, targetBoundingBox, targetPaintInvalidationRect, maskContext, clipPathClipperState)) return false; { AffineTransform contentTransform; if (m_clip.clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { contentTransform.translate(targetBoundingBox.x(), targetBoundingBox.y()); contentTransform.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height()); } SubtreeContentTransformScope contentTransformScope(contentTransform); TransformRecorder contentTransformRecorder(maskContext, layoutObject, contentTransform); RefPtr<const SkPicture> clipContentPicture = m_clip.createContentPicture(); maskContext.getPaintController().createAndAppend<DrawingDisplayItem>(layoutObject, DisplayItem::SVGClip, clipContentPicture.get()); } if (clipPathClipper) SVGClipPainter(*clipPathClipper).finishEffect(m_clip, maskContext, clipPathClipperState); } LayoutObjectDrawingRecorder drawingRecorder(context, layoutObject, DisplayItem::SVGClip, targetPaintInvalidationRect); RefPtr<SkPicture> maskPicture = maskPictureBuilder.endRecording(); context.drawPicture(maskPicture.get()); return true; }