Bug 1317636 - Part 2. Extract PaintFrameIntoMask from nsSVGClipPathFrame::PaintClipMask.
MozReview-Commit-ID: LgrortpuwN5
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -160,70 +160,17 @@ nsSVGClipPathFrame::PaintClipMask(gfxCon
// The corresponding PopGroupAndBlend call below will mask the
// blend using |mask|.
}
}
// Paint our children into the mask:
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
- nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
- if (SVGFrame) {
- // The CTM of each frame referencing us can be different.
- SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
-
- bool isOK = true;
- // Children of this clipPath may themselves be clipped.
- nsSVGClipPathFrame *clipPathThatClipsChild =
- nsSVGEffects::GetEffectProperties(kid).GetClipPathFrame(&isOK);
- if (!isOK) {
- continue;
- }
-
- bool childsClipPathRequiresMasking;
-
- if (clipPathThatClipsChild) {
- childsClipPathRequiresMasking = !clipPathThatClipsChild->IsTrivial();
- aMaskContext.Save();
- if (!childsClipPathRequiresMasking) {
- clipPathThatClipsChild->ApplyClipPath(aMaskContext, aClippedFrame,
- aMatrix);
- } else {
- Matrix maskTransform;
- RefPtr<SourceSurface> mask =
- clipPathThatClipsChild->GetClipMask(aMaskContext, aClippedFrame,
- aMatrix, &maskTransform);
- aMaskContext.PushGroupForBlendBack(gfxContentType::ALPHA, 1.0,
- mask, maskTransform);
- // The corresponding PopGroupAndBlend call below will mask the
- // blend using |mask|.
- }
- }
-
- gfxMatrix toChildsUserSpace = mMatrixForChildren;
- nsIFrame* child = do_QueryFrame(SVGFrame);
- nsIContent* childContent = child->GetContent();
- if (childContent->IsSVGElement()) {
- toChildsUserSpace =
- static_cast<const nsSVGElement*>(childContent)->
- PrependLocalTransformsTo(mMatrixForChildren, eUserSpaceToParent);
- }
-
- // Our children have NS_STATE_SVG_CLIPPATH_CHILD set on them, and
- // nsSVGPathGeometryFrame::Render checks for that state bit and paints
- // only the geometry (opaque black) if set.
- result &= SVGFrame->PaintSVG(aMaskContext, toChildsUserSpace);
-
- if (clipPathThatClipsChild) {
- if (childsClipPathRequiresMasking) {
- aMaskContext.PopGroupAndBlend();
- }
- aMaskContext.Restore();
- }
- }
+ result &= PaintFrameIntoMask(kid, aClippedFrame, aMaskContext, aMatrix);
}
if (clipPathThatClipsClipPath) {
if (clippingOfClipPathRequiredMasking) {
aMaskContext.PopGroupAndBlend();
}
aMaskContext.Restore();
@@ -249,16 +196,81 @@ nsSVGClipPathFrame::PaintClipMask(gfxCon
aExtraMask,
Point(0, 0));
}
*aMaskTransform = ToMatrix(maskTransfrom);
return result;
}
+DrawResult
+nsSVGClipPathFrame::PaintFrameIntoMask(nsIFrame *aFrame,
+ nsIFrame* aClippedFrame,
+ gfxContext& aTarget,
+ const gfxMatrix& aMatrix)
+{
+ nsISVGChildFrame* frame = do_QueryFrame(aFrame);
+ if (!frame) {
+ return DrawResult::SUCCESS;
+ }
+
+ // The CTM of each frame referencing us can be different.
+ frame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
+
+ bool isOK = true;
+ // Children of this clipPath may themselves be clipped.
+ nsSVGClipPathFrame *clipPathThatClipsChild =
+ nsSVGEffects::GetEffectProperties(aFrame).GetClipPathFrame(&isOK);
+ if (!isOK) {
+ return DrawResult::SUCCESS;
+ }
+
+ bool childsClipPathRequiresMasking;
+
+ if (clipPathThatClipsChild) {
+ childsClipPathRequiresMasking = !clipPathThatClipsChild->IsTrivial();
+ aTarget.Save();
+ if (!childsClipPathRequiresMasking) {
+ clipPathThatClipsChild->ApplyClipPath(aTarget, aClippedFrame, aMatrix);
+ } else {
+ Matrix maskTransform;
+ RefPtr<SourceSurface> mask =
+ clipPathThatClipsChild->GetClipMask(aTarget, aClippedFrame,
+ aMatrix, &maskTransform);
+ aTarget.PushGroupForBlendBack(gfxContentType::ALPHA, 1.0,
+ mask, maskTransform);
+ // The corresponding PopGroupAndBlend call below will mask the
+ // blend using |mask|.
+ }
+ }
+
+ gfxMatrix toChildsUserSpace = mMatrixForChildren;
+ nsIFrame* child = do_QueryFrame(frame);
+ nsIContent* childContent = child->GetContent();
+ if (childContent->IsSVGElement()) {
+ toChildsUserSpace =
+ static_cast<const nsSVGElement*>(childContent)->
+ PrependLocalTransformsTo(mMatrixForChildren, eUserSpaceToParent);
+ }
+
+ // Our children have NS_STATE_SVG_CLIPPATH_CHILD set on them, and
+ // nsSVGPathGeometryFrame::Render checks for that state bit and paints
+ // only the geometry (opaque black) if set.
+ DrawResult result = frame->PaintSVG(aTarget, toChildsUserSpace);
+
+ if (clipPathThatClipsChild) {
+ if (childsClipPathRequiresMasking) {
+ aTarget.PopGroupAndBlend();
+ }
+ aTarget.Restore();
+ }
+
+ return result;
+}
+
already_AddRefed<SourceSurface>
nsSVGClipPathFrame::GetClipMask(gfxContext& aReferenceContext,
nsIFrame* aClippedFrame,
const gfxMatrix& aMatrix,
Matrix* aMaskTransform,
SourceSurface* aExtraMask,
const Matrix& aExtraMasksTransform,
DrawResult* aResult)
--- a/layout/svg/nsSVGClipPathFrame.h
+++ b/layout/svg/nsSVGClipPathFrame.h
@@ -155,16 +155,19 @@ public:
private:
// nsSVGContainerFrame methods:
virtual gfxMatrix GetCanvasTM() override;
already_AddRefed<DrawTarget>
CreateClipMask(gfxContext& aReferenceContext, IntPoint& aOffset);
+ DrawResult PaintFrameIntoMask(nsIFrame *aFrame, nsIFrame* aClippedFrame,
+ gfxContext& aTarget, const gfxMatrix& aMatrix);
+
// Set, during a GetClipMask() call, to the transform that still needs to be
// concatenated to the transform of the DrawTarget that was passed to
// GetClipMask in order to establish the coordinate space that the clipPath
// establishes for its contents (i.e. including applying 'clipPathUnits' and
// any 'transform' attribute set on the clipPath) specifically for clipping
// the frame that was passed to GetClipMask at that moment in time. This is
// set so that if our GetCanvasTM method is called while GetClipMask is
// painting its children, the returned matrix will include the transforms