Bug 1365926, part 1 - Support 'context-fill-opacity'/'context-stroke-opacity' as SVG-as-an-image context properties. r=heycam
authorJonathan Watt <jwatt@jwatt.org>
Thu, 18 May 2017 12:47:20 +0100
changeset 361981 71669172faf131b0035297f09f82876a50deac73
parent 361980 a9f2f087d8242123e8d3f44d64e3f68d910903bb
child 361982 5f6d6bbd78904a917af50478442bbf1d889ed7a2
push id31953
push usercbook@mozilla.com
push dateFri, 02 Jun 2017 12:22:33 +0000
treeherdermozilla-central@2a8478029a0c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1365926
milestone55.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 1365926, part 1 - Support 'context-fill-opacity'/'context-stroke-opacity' as SVG-as-an-image context properties. r=heycam MozReview-Commit-ID: 2YHjwCB02jV
layout/style/nsRuleNode.cpp
layout/style/nsStyleConsts.h
layout/svg/SVGContextPaint.cpp
layout/svg/SVGContextPaint.h
layout/svg/SVGImageContext.cpp
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -9643,16 +9643,20 @@ nsRuleNode::ComputeSVGData(void* aStartS
          item; item = item->mNext)
     {
       nsIAtom* atom = item->mValue.GetAtomValue();
       svg->mContextProps.AppendElement(atom);
       if (atom == nsGkAtoms::fill) {
         svg->mContextPropsBits |= NS_STYLE_CONTEXT_PROPERTY_FILL;
       } else if (atom == nsGkAtoms::stroke) {
         svg->mContextPropsBits |= NS_STYLE_CONTEXT_PROPERTY_STROKE;
+      } else if (atom == nsGkAtoms::fill_opacity) {
+        svg->mContextPropsBits |= NS_STYLE_CONTEXT_PROPERTY_FILL_OPACITY;
+      } else if (atom == nsGkAtoms::stroke_opacity) {
+        svg->mContextPropsBits |= NS_STYLE_CONTEXT_PROPERTY_STROKE_OPACITY;
       }
     }
     break;
   }
 
   case eCSSUnit_Inherit:
   case eCSSUnit_Unset:
     svg->mContextProps = parentSVG->mContextProps;
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -1055,16 +1055,18 @@ enum class StyleGridTrackBreadth : uint8
 #define NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER  3
 #define NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE    4
 
 // See nsStyleSVG
 
 // -moz-context-properties
 #define NS_STYLE_CONTEXT_PROPERTY_FILL          (1 << 0)
 #define NS_STYLE_CONTEXT_PROPERTY_STROKE        (1 << 1)
+#define NS_STYLE_CONTEXT_PROPERTY_FILL_OPACITY   (1 << 2)
+#define NS_STYLE_CONTEXT_PROPERTY_STROKE_OPACITY (1 << 3)
 
 /*
  * -moz-window-shadow
  * Also used in widget code
  */
 
 #define NS_STYLE_WINDOW_SHADOW_NONE             0
 #define NS_STYLE_WINDOW_SHADOW_DEFAULT          1
--- a/layout/svg/SVGContextPaint.cpp
+++ b/layout/svg/SVGContextPaint.cpp
@@ -390,12 +390,20 @@ SVGEmbeddingContextPaint::Hash() const
     // another context has stroke set to.
     hash = 1;
   }
 
   if (mStroke) {
     hash = HashGeneric(hash, mStroke->ToABGR());
   }
 
+  if (mFillOpacity != 1.0f) {
+    hash = HashGeneric(hash, mFillOpacity);
+  }
+
+  if (mStrokeOpacity != 1.0f) {
+    hash = HashGeneric(hash, mStrokeOpacity);
+  }
+
   return hash;
 }
 
 } // namespace mozilla
--- a/layout/svg/SVGContextPaint.h
+++ b/layout/svg/SVGContextPaint.h
@@ -246,25 +246,31 @@ public:
  * it from a CSS property such as 'background-image').  In this case we only
  * support context colors and not paint servers.
  */
 class SVGEmbeddingContextPaint : public SVGContextPaint
 {
   typedef gfx::Color Color;
 
 public:
-  SVGEmbeddingContextPaint() {}
+  SVGEmbeddingContextPaint()
+    : mFillOpacity(1.0f)
+    , mStrokeOpacity(1.0f)
+  {}
 
   bool operator==(const SVGEmbeddingContextPaint& aOther) const {
     MOZ_ASSERT(GetStrokeWidth() == aOther.GetStrokeWidth() &&
                GetStrokeDashOffset() == aOther.GetStrokeDashOffset() &&
                GetStrokeDashArray() == aOther.GetStrokeDashArray(),
                "We don't currently include these in the context information "
                "from an embedding element");
-    return mFill == aOther.mFill && mStroke == aOther.mStroke;
+    return mFill == aOther.mFill &&
+           mStroke == aOther.mStroke &&
+           mFillOpacity == aOther.mFillOpacity &&
+           mStrokeOpacity == aOther.mStrokeOpacity;
   }
 
   void SetFill(nscolor aFill) {
     mFill.emplace(gfx::ToDeviceColor(aFill));
   }
   void SetStroke(nscolor aStroke) {
     mStroke.emplace(gfx::ToDeviceColor(aStroke));
   }
@@ -278,29 +284,35 @@ public:
 
   /**
    * Returns a pattern of type PatternType::COLOR, or else nullptr.
    */
   already_AddRefed<gfxPattern>
   GetStrokePattern(const DrawTarget* aDrawTarget, float aStrokeOpacity,
                    const gfxMatrix& aCTM, imgDrawingParams& aImgParams) override;
 
+  void SetFillOpacity(float aOpacity) {
+    mFillOpacity = aOpacity;
+  }
   float GetFillOpacity() const override {
-    // Always 1.0f since we don't currently allow 'context-fill-opacity'
-    return 1.0f;
+    return mFillOpacity;
   };
 
+  void SetStrokeOpacity(float aOpacity) {
+    mStrokeOpacity = aOpacity;
+  }
   float GetStrokeOpacity() const override {
-    // Always 1.0f since we don't currently allow 'context-stroke-opacity'
-    return 1.0f;
+    return mStrokeOpacity;
   };
 
   uint32_t Hash() const override;
 
 private:
   Maybe<Color> mFill;
   Maybe<Color> mStroke;
+  float mFillOpacity;
+  float mStrokeOpacity;
 };
 
 } // namespace mozilla
 
 #endif // MOZILLA_SVGCONTEXTPAINT_H_
 
--- a/layout/svg/SVGImageContext.cpp
+++ b/layout/svg/SVGImageContext.cpp
@@ -44,16 +44,24 @@ SVGImageContext::MaybeStoreContextPaint(
     haveContextPaint = true;
     contextPaint->SetFill(style->mFill.GetColor());
   }
   if ((style->mContextPropsBits & NS_STYLE_CONTEXT_PROPERTY_STROKE) &&
       style->mStroke.Type() == eStyleSVGPaintType_Color) {
     haveContextPaint = true;
     contextPaint->SetStroke(style->mStroke.GetColor());
   }
+  if (style->mContextPropsBits & NS_STYLE_CONTEXT_PROPERTY_FILL_OPACITY) {
+    haveContextPaint = true;
+    contextPaint->SetFillOpacity(style->mFillOpacity);
+  }
+  if (style->mContextPropsBits & NS_STYLE_CONTEXT_PROPERTY_STROKE_OPACITY) {
+    haveContextPaint = true;
+    contextPaint->SetStrokeOpacity(style->mStrokeOpacity);
+  }
 
   if (haveContextPaint) {
     if (!aContext) {
       aContext.emplace();
     }
     aContext->mContextPaint = contextPaint.forget();
   }
 }