Bug 1322330 - Remove EffectProperties::GetFirstMaskFrame and implement EffectProperties::HasInvalidMaskOrClipPathResource. draft
authorcku <cku@mozilla.com>
Tue, 06 Dec 2016 16:12:36 -1000
changeset 447682 5d7036b5fa5cf1bb9743a402151235385a509b42
parent 447633 ad993783599ab2ede0cf931fdec02f4df40a7a6d
child 447683 56a5aaf89f89c0f68e849021ad6a85e8a33ce180
push id38121
push userbmo:cku@mozilla.com
push dateWed, 07 Dec 2016 06:45:05 +0000
bugs1322330
milestone53.0a1
Bug 1322330 - Remove EffectProperties::GetFirstMaskFrame and implement EffectProperties::HasInvalidMaskOrClipPathResource. MozReview-Commit-ID: 4nfhL7btNFT
layout/painting/nsDisplayList.cpp
layout/svg/nsSVGEffects.cpp
layout/svg/nsSVGEffects.h
layout/svg/nsSVGUtils.cpp
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -7457,17 +7457,18 @@ nsDisplayMask::PrintEffects(nsACString& 
   if (style->HasClipPath() && !clipPathFrame) {
     if (!first) {
       aTo += ", ";
     }
     aTo += "clip(basic-shape)";
     first = false;
   }
 
-  if (effectProperties.GetFirstMaskFrame()) {
+  nsTArray<nsSVGMaskFrame*> masks = effectProperties.GetMaskFrames();
+  if (masks.Length() > 0 && masks[0]) {
     if (!first) {
       aTo += ", ";
     }
     aTo += "mask";
   }
   aTo += ")";
 }
 #endif
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -642,52 +642,60 @@ nsSVGEffects::EffectProperties::GetClipP
   nsSVGClipPathFrame *frame = static_cast<nsSVGClipPathFrame *>
     (mClipPath->GetReferencedFrame(nsGkAtoms::svgClipPathFrame, aOK));
   if (frame && aOK && *aOK) {
     *aOK = frame->IsValid();
   }
   return frame;
 }
 
-nsSVGMaskFrame *
-nsSVGEffects::EffectProperties::GetFirstMaskFrame(bool* aOK)
-{
-  if (!mMask) {
-    return nullptr;
-  }
-
-  const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
-
-  if (props.IsEmpty()) {
-    return nullptr;
-  }
-
-  return static_cast<nsSVGMaskFrame *>
-    (props[0]->GetReferencedFrame(nsGkAtoms::svgMaskFrame, aOK));
-}
-
 nsTArray<nsSVGMaskFrame *>
 nsSVGEffects::EffectProperties::GetMaskFrames()
 {
   nsTArray<nsSVGMaskFrame *> result;
   if (!mMask)
     return result;
 
   bool ok = false;
   const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
   for (size_t i = 0; i < props.Length(); i++) {
     nsSVGMaskFrame* maskFrame =
       static_cast<nsSVGMaskFrame *>(props[i]->GetReferencedFrame(
                                                 nsGkAtoms::svgMaskFrame, &ok));
-    result.AppendElement(maskFrame);
+    result.AppendElement(ok ? maskFrame : nullptr);
   }
 
   return result;
 }
 
+bool
+nsSVGEffects::EffectProperties::HasInvalidMaskOrClipPathResource()
+{
+  if (mClipPath) {
+    bool ok = true;
+    mClipPath->GetReferencedFrame(nsGkAtoms::svgClipPathFrame, &ok);
+    if (!ok) {
+      return true;
+    }
+  }
+
+  if (mMask) {
+    bool ok = true;
+    const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
+    for (size_t i = 0; i < props.Length(); i++) {
+      props[i]->GetReferencedFrame(nsGkAtoms::svgMaskFrame, &ok);
+      if (!ok) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
 void
 nsSVGEffects::UpdateEffects(nsIFrame* aFrame)
 {
   NS_ASSERTION(aFrame->GetContent()->IsElement(),
                "aFrame's content should be an element");
 
   FrameProperties props = aFrame->Properties();
   props.Delete(FilterProperty());
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -475,29 +475,27 @@ public:
 
     /**
      * @return the clip-path frame, or null if there is no clip-path frame
      * @param aOK if a clip-path was specified and the designated element
      * exists but is an element of the wrong type, *aOK is set to false.
      * Otherwise *aOK is untouched.
      */
     nsSVGClipPathFrame *GetClipPathFrame(bool* aOK);
-    /**
-     * @return the first mask frame, or null if there is no mask frame
-     * @param aOK if a mask was specified and the designated element
-     * exists but is an element of the wrong type, *aOK is set to false.
-     * Otherwise *aOK is untouched.
-     */
-    nsSVGMaskFrame *GetFirstMaskFrame(bool* aOK = nullptr);
 
     /**
      * @return an array which contains all SVG mask frames.
      */
     nsTArray<nsSVGMaskFrame*> GetMaskFrames();
 
+    /*
+     * @return true if we have any invalid mask or clip-path resource.
+     */
+    bool HasInvalidMaskOrClipPathResource();
+
     bool HasValidFilter() {
       return mFilter && mFilter->ReferencesValidResources();
     }
 
     bool HasNoFilterOrHasValidFilter() {
       return !mFilter || mFilter->ReferencesValidResources();
     }
   };
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -735,24 +735,26 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
    *f
    * + Merge opacity and masking if both used together.
    */
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(aFrame);
-  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
-  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
-  nsSVGMaskFrame *maskFrame = effectProperties.GetFirstMaskFrame(&isOK);
-  if (!isOK) {
+  if (effectProperties.HasInvalidMaskOrClipPathResource()) {
     // Some resource is invalid. We shouldn't paint anything.
     return DrawResult::SUCCESS;
   }
 
+  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
+  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
+  nsTArray<nsSVGMaskFrame*> masks = effectProperties.GetMaskFrames();
+  nsSVGMaskFrame *maskFrame = masks.Length() > 0 ? masks[0] : nullptr;
+
   MixModeBlender blender(aFrame, &aContext);
   gfxContext* target = blender.ShouldCreateDrawTargetForBlend()
                        ? blender.CreateBlendTarget(aTransform) : &aContext;
 
   if (!target) {
     return DrawResult::TEMPORARY_ERROR;
   }