Bug 1301245 - Part 3. Resolve a style image if nsSVGPaintingProperty can not handle it. r=heycam
authorcku <cku@mozilla.com>
Wed, 26 Jul 2017 12:02:44 +0800
changeset 419800 319bc66e5d3a6599a61b686bc58ee399dac77b65
parent 419799 ebe4713f3fbac2e08c36ab6b85bec40d198ce719
child 419801 36df21c0cba7b5ce6940d86a8efc7b10ab44be13
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1301245
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1301245 - Part 3. Resolve a style image if nsSVGPaintingProperty can not handle it. r=heycam MozReview-Commit-ID: 9m7yJ4CgCvr
layout/svg/nsSVGEffects.cpp
layout/svg/nsSVGEffects.h
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -14,16 +14,17 @@
 #include "nsSVGClipPathFrame.h"
 #include "nsSVGPaintServerFrame.h"
 #include "nsSVGFilterFrame.h"
 #include "nsSVGMaskFrame.h"
 #include "nsIReflowCallback.h"
 #include "nsCycleCollectionParticipant.h"
 #include "SVGGeometryElement.h"
 #include "SVGUseElement.h"
+#include "ImageLoader.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 void
 nsSVGRenderingObserver::StartListening()
 {
   Element* target = GetTarget();
@@ -387,16 +388,17 @@ nsSVGMarkerProperty::DoUpdate()
   }
   frame->PresContext()->RestyleManager()->PostRestyleEvent(
     frame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
 }
 
 NS_IMPL_ISUPPORTS(nsSVGMaskProperty, nsISupports)
 
 nsSVGMaskProperty::nsSVGMaskProperty(nsIFrame* aFrame)
+ : mFrame(aFrame)
 {
   const nsStyleSVGReset *svgReset = aFrame->StyleSVGReset();
 
   for (uint32_t i = 0; i < svgReset->mMask.mImageCount; i++) {
     nsCOMPtr<nsIURI> maskUri = nsSVGEffects::GetMaskURI(aFrame, i);
     bool hasRef = false;
     if (maskUri) {
       maskUri->GetHasRef(&hasRef);
@@ -410,16 +412,37 @@ nsSVGMaskProperty::nsSVGMaskProperty(nsI
     // a fragment.
     nsSVGPaintingProperty* prop =
       new nsSVGPaintingProperty(hasRef ? maskUri.get() : nullptr,
                                 aFrame, false);
     mProperties.AppendElement(prop);
   }
 }
 
+void
+nsSVGMaskProperty::ResolveImage(uint32_t aIndex)
+{
+  const nsStyleSVGReset* svgReset = mFrame->StyleSVGReset();
+  MOZ_ASSERT(aIndex < svgReset->mMask.mImageCount);
+
+  nsStyleImage& image =
+    const_cast<nsStyleImage&>(svgReset->mMask.mLayers[aIndex].mImage);
+
+  if (!image.IsResolved()) {
+    MOZ_ASSERT(image.GetType() == nsStyleImageType::eStyleImageType_Image);
+    image.ResolveImage(mFrame->PresContext());
+
+    mozilla::css::ImageLoader* imageLoader =
+      mFrame->PresContext()->Document()->StyleImageLoader();
+    if (imgRequestProxy* req = image.GetImageData()) {
+      imageLoader->AssociateRequestToFrame(req, mFrame);
+    }
+  }
+}
+
 bool
 nsSVGTextPathProperty::TargetIsValid()
 {
   Element* target = GetTarget();
   return target && target->IsSVGElement(nsGkAtoms::path);
 }
 
 void
@@ -666,16 +689,25 @@ nsSVGEffects::EffectProperties::GetMaskF
     return result;
 
   bool ok = true;
   const nsTArray<RefPtr<nsSVGPaintingProperty>>& props = mMask->GetProps();
   for (size_t i = 0; i < props.Length(); i++) {
     nsSVGMaskFrame* maskFrame = static_cast<nsSVGMaskFrame*>(
       props[i]->GetReferencedFrame(LayoutFrameType::SVGMask, &ok));
     MOZ_ASSERT(!maskFrame || ok);
+    if (!ok) {
+      // We can not find the specific SVG mask resource in the downloaded SVG
+      // document. There are two possibilities:
+      // 1. The given resource id is invalid.
+      // 2. The given resource id refers to a viewbox.
+      //
+      // Hand it over to the style image.
+      mMask->ResolveImage(i);
+    }
     result.AppendElement(maskFrame);
   }
 
   return result;
 }
 
 bool
 nsSVGEffects::EffectProperties::HasNoOrValidEffects()
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -350,19 +350,22 @@ public:
   // nsISupports
   NS_DECL_ISUPPORTS
 
   const nsTArray<RefPtr<nsSVGPaintingProperty>>& GetProps() const
   {
     return mProperties;
   }
 
+  void ResolveImage(uint32_t aIndex);
+
 private:
   virtual ~nsSVGMaskProperty() {}
   nsTArray<RefPtr<nsSVGPaintingProperty>> mProperties;
+  nsIFrame* mFrame;
 };
 
 /**
  * A manager for one-shot nsSVGRenderingObserver tracking.
  * nsSVGRenderingObservers can be added or removed. They are not strongly
  * referenced so an observer must be removed before it dies.
  * When InvalidateAll is called, all outstanding references get
  * InvalidateViaReferencedElement()