Bug 1320364 - Correct NS_ASSERTION failure condition in GetPreEffectsVisualOverflowRect. draft
authorcku <cku@mozilla.com>
Mon, 28 Nov 2016 16:26:34 +0800
changeset 447863 5e2bff0b7c3442ab04eaafc7e1760b89b4304675
parent 447742 c401d72933641748f3738e90e7bbe539705e2f1c
child 539157 52e4f7d906438d6428146d82beea2f3b7b3be83e
push id38199
push userbmo:cku@mozilla.com
push dateThu, 08 Dec 2016 05:58:31 +0000
bugs1320364
milestone53.0a1
Bug 1320364 - Correct NS_ASSERTION failure condition in GetPreEffectsVisualOverflowRect. MozReview-Commit-ID: 4675cFLehK4
layout/svg/nsSVGEffects.cpp
layout/svg/nsSVGEffects.h
layout/svg/nsSVGIntegrationUtils.cpp
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -678,16 +678,34 @@ nsSVGEffects::EffectProperties::GetMaskF
       static_cast<nsSVGMaskFrame *>(props[i]->GetReferencedFrame(
                                                 nsGkAtoms::svgMaskFrame, &ok));
     result.AppendElement(maskFrame);
   }
 
   return result;
 }
 
+bool
+nsSVGEffects::EffectProperties::MightHaveNoneSVGMask() const
+{
+  if (!mMask) {
+    return false;
+  }
+
+  const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
+  for (size_t i = 0; i < props.Length(); i++) {
+    if (!props[i] ||
+        !props[i]->GetReferencedFrame(nsGkAtoms::svgMaskFrame, nullptr)) {
+      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
@@ -488,16 +488,17 @@ public:
      */
     nsSVGMaskFrame *GetFirstMaskFrame(bool* aOK = nullptr);
 
     /**
      * @return an array which contains all SVG mask frames.
      */
     nsTArray<nsSVGMaskFrame*> GetMaskFrames();
 
+    bool MightHaveNoneSVGMask() const;
     bool HasValidFilter() {
       return mFilter && mFilter->ReferencesValidResources();
     }
 
     bool HasNoFilterOrHasValidFilter() {
       return !mFilter || mFilter->ReferencesValidResources();
     }
   };
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -105,19 +105,28 @@ private:
     //
     //  * reftests/svg/svg-integration/clipPath-html-06.xhtml
     //  * reftests/svg/svg-integration/clipPath-html-06-extref.xhtml
     //
     // If we ever got passed a frame with the PreTransformOverflowAreasProperty
     // property set, that would be bad, since then our GetVisualOverflowRect()
     // call would give us the post-effects, and post-transform, overflow rect.
     //
-    NS_ASSERTION(aFrame->GetParent()->StyleContext()->GetPseudo() ==
+    // With image masks, there is one more exception.
+    //
+    // In nsStyleImageLayers::Layer::CalcDifference, we do not add
+    // nsChangeHint_UpdateOverflow hint when image mask(not SVG mask) property
+    // value changed, since replace image mask does not cause layout change.
+    // So even if we apply a new mask image to this frame,
+    // PreEffectsBBoxProperty might still left empty.
+    NS_ASSERTION(nsSVGEffects::GetEffectProperties(aFrame).MightHaveNoneSVGMask() ||
+                 aFrame->GetParent()->StyleContext()->GetPseudo() ==
                    nsCSSAnonBoxes::mozAnonymousBlock,
                  "How did we getting here, then?");
+
     NS_ASSERTION(!aFrame->Properties().Get(
                    aFrame->PreTransformOverflowAreasProperty()),
                  "GetVisualOverflowRect() won't return the pre-effects rect!");
     return aFrame->GetVisualOverflowRect();
   }
 
   nsIFrame*     mFirstContinuation;
   nsIFrame*     mCurrentFrame;