Bug 1317636 - Part 3. Extract PaintFrameIntoMask from nsSVGClipPathFrame::PaintClipMask. draft
authorcku <cku@mozilla.com>
Wed, 16 Nov 2016 16:58:59 +0800
changeset 440350 027806777c42bf3efcb753508e19021c57b169b5
parent 440349 a4f277cf1b996103ef295b907e939f9ccf6616d1
child 440351 5242fe790d86a99f0ca62589e79436b6f8da356b
push id36210
push userbmo:cku@mozilla.com
push dateThu, 17 Nov 2016 12:38:18 +0000
bugs1317636
milestone53.0a1
Bug 1317636 - Part 3. Extract PaintFrameIntoMask from nsSVGClipPathFrame::PaintClipMask. MozReview-Commit-ID: LgrortpuwN5
layout/svg/nsSVGClipPathFrame.cpp
layout/svg/nsSVGClipPathFrame.h
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -161,70 +161,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();
@@ -250,16 +197,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
@@ -154,16 +154,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