Bug 793617 - Implement mask-type property. r=dbaron,longsonr
authorCameron McCormack <cam@mcc.id.au>
Fri, 21 Dec 2012 11:15:22 +1100
changeset 116738 e043d5feb0b6
parent 116737 01f69299eba0
child 116739 f533eacd8458
push id24072
push userMs2ger@gmail.com
push date2012-12-22 13:18 +0000
treeherdermozilla-central@ea373e534245 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron, longsonr
bugs793617
milestone20.0a1
Bug 793617 - Implement mask-type property. r=dbaron,longsonr
content/base/src/nsGkAtomList.h
content/smil/nsSMILCSSProperty.cpp
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
content/svg/content/src/nsSVGMaskElement.cpp
layout/base/nsStyleConsts.h
layout/reftests/svg/mask-type-01-ref.svg
layout/reftests/svg/mask-type-01.svg
layout/reftests/svg/mask-type-02.svg
layout/reftests/svg/mask-type-03.svg
layout/reftests/svg/mask-type-04.svg
layout/reftests/svg/reftest.list
layout/style/nsCSSKeywordList.h
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
layout/svg/nsSVGMaskFrame.cpp
modules/libpref/src/init/all.js
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1291,16 +1291,17 @@ GK_ATOM(marker, "marker")
 GK_ATOM(marker_end, "marker-end")
 GK_ATOM(marker_mid, "marker-mid")
 GK_ATOM(marker_start, "marker-start")
 GK_ATOM(markerHeight, "markerHeight")
 GK_ATOM(markerUnits, "markerUnits")
 GK_ATOM(markerWidth, "markerWidth")
 GK_ATOM(mask, "mask")
 GK_ATOM(maskContentUnits, "maskContentUnits")
+GK_ATOM(mask_type, "mask-type")
 GK_ATOM(maskUnits, "maskUnits")
 GK_ATOM(matrix, "matrix")
 GK_ATOM(metadata, "metadata")
 GK_ATOM(missingGlyph, "missing-glyph")
 GK_ATOM(mm, "mm")
 GK_ATOM(mpath, "mpath")
 GK_ATOM(noStitch, "noStitch")
 GK_ATOM(numOctaves, "numOctaves")
--- a/content/smil/nsSMILCSSProperty.cpp
+++ b/content/smil/nsSMILCSSProperty.cpp
@@ -223,16 +223,17 @@ nsSMILCSSProperty::IsPropertyAnimatable(
     case eCSSProperty_image_rendering:
     case eCSSProperty_letter_spacing:
     case eCSSProperty_lighting_color:
     case eCSSProperty_marker:
     case eCSSProperty_marker_end:
     case eCSSProperty_marker_mid:
     case eCSSProperty_marker_start:
     case eCSSProperty_mask:
+    case eCSSProperty_mask_type:
     case eCSSProperty_opacity:
     case eCSSProperty_overflow:
     case eCSSProperty_pointer_events:
     case eCSSProperty_shape_rendering:
     case eCSSProperty_stop_color:
     case eCSSProperty_stop_opacity:
     case eCSSProperty_stroke:
     case eCSSProperty_stroke_dasharray:
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1006,16 +1006,23 @@ nsSVGElement::sFEFloodMap[] = {
 
 // PresentationAttributes-LightingEffects
 /* static */ const Element::MappedAttributeEntry
 nsSVGElement::sLightingEffectsMap[] = {
   { &nsGkAtoms::lighting_color },
   { nullptr }
 };
 
+// PresentationAttributes-mask
+/* static */ const Element::MappedAttributeEntry
+nsSVGElement::sMaskMap[] = {
+  { &nsGkAtoms::mask_type },
+  { nullptr }
+};
+
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 NS_IMETHODIMP
 nsSVGElement::IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aReturn)
 {
   *aReturn = Element::IsSupported(aFeature, aVersion);
   return NS_OK;
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -98,16 +98,17 @@ public:
   static const MappedAttributeEntry sFontSpecificationMap[];
   static const MappedAttributeEntry sGradientStopMap[];
   static const MappedAttributeEntry sViewportsMap[];
   static const MappedAttributeEntry sMarkersMap[];
   static const MappedAttributeEntry sColorMap[];
   static const MappedAttributeEntry sFiltersMap[];
   static const MappedAttributeEntry sFEFloodMap[];
   static const MappedAttributeEntry sLightingEffectsMap[];
+  static const MappedAttributeEntry sMaskMap[];
 
   // nsIDOMNode
   NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion,
                          bool* aReturn);
   
   // nsIDOMSVGElement
   NS_IMETHOD GetId(nsAString & aId);
   NS_IMETHOD SetId(const nsAString & aId);
--- a/content/svg/content/src/nsSVGMaskElement.cpp
+++ b/content/svg/content/src/nsSVGMaskElement.cpp
@@ -136,15 +136,16 @@ nsSVGMaskElement::IsAttributeMapped(cons
 {
   static const MappedAttributeEntry* const map[] = {
     sFEFloodMap,
     sFiltersMap,
     sFontSpecificationMap,
     sGradientStopMap,
     sGraphicsMap,
     sMarkersMap,
+    sMaskMap,
     sTextContentElementsMap,
     sViewportsMap
   };
 
   return FindAttributeDependence(name, map) ||
     nsSVGMaskElementBase::IsAttributeMapped(name);
 }
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -854,16 +854,20 @@ static inline mozilla::css::Side operato
 #define NS_STYLE_FILL_RULE_EVENODD              1
 
 // image-rendering
 #define NS_STYLE_IMAGE_RENDERING_AUTO             0
 #define NS_STYLE_IMAGE_RENDERING_OPTIMIZESPEED    1
 #define NS_STYLE_IMAGE_RENDERING_OPTIMIZEQUALITY  2
 #define NS_STYLE_IMAGE_RENDERING_CRISPEDGES       3
 
+// mask-type
+#define NS_STYLE_MASK_TYPE_LUMINANCE            0
+#define NS_STYLE_MASK_TYPE_ALPHA                1
+
 // shape-rendering
 #define NS_STYLE_SHAPE_RENDERING_AUTO               0
 #define NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED      1
 #define NS_STYLE_SHAPE_RENDERING_CRISPEDGES         2
 #define NS_STYLE_SHAPE_RENDERING_GEOMETRICPRECISION 3
 
 // stroke-linecap
 #define NS_STYLE_STROKE_LINECAP_BUTT            0
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/mask-type-01-ref.svg
@@ -0,0 +1,12 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
+
+  <title>Reference for alpha mask</title>
+
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=793617 -->
+
+  <rect x="10" y="10" width="80" height="80" fill="blue" fill-opacity="0.5"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/mask-type-01.svg
@@ -0,0 +1,15 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
+
+  <title>Testcase for alpha mask</title>
+
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=793617 -->
+
+  <mask id="m" maskContentUnits="objectBoundingBox" style="mask-type: alpha">
+    <rect x=".1" y=".1" width=".8" height=".8" fill="black" fill-opacity="0.5"/>
+  </mask>
+  <rect width="100" height="100" fill="blue" mask="url(#m)"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/mask-type-02.svg
@@ -0,0 +1,15 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
+
+  <title>Testcase for alpha mask using the presentation attribute</title>
+
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=793617 -->
+
+  <mask id="m" maskContentUnits="objectBoundingBox" mask-type="alpha">
+    <rect x=".1" y=".1" width=".8" height=".8" fill="black" fill-opacity="0.5"/>
+  </mask>
+  <rect width="100" height="100" fill="blue" mask="url(#m)"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/mask-type-03.svg
@@ -0,0 +1,23 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"
+     class="reftest-wait" onload="run()">
+
+  <title>Testcase for alpha mask, dynamically setting mask-type</title>
+
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=793617 -->
+
+  <mask id="m" maskContentUnits="objectBoundingBox">
+    <rect x=".1" y=".1" width=".8" height=".8" fill="black" fill-opacity="0.5"/>
+  </mask>
+  <rect width="100" height="100" fill="blue" mask="url(#m)"/>
+
+  <script>
+    function run() {
+      document.getElementById("m").style.maskType = "alpha";
+      document.documentElement.removeAttribute("class");
+    }
+  </script>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/mask-type-04.svg
@@ -0,0 +1,16 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
+
+  <title>Testcase for alpha mask, dynamically setting mask-type</title>
+
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=793617 -->
+
+  <mask id="m" maskContentUnits="objectBoundingBox">
+    <rect x=".1" y=".1" width=".8" height=".8" fill="black" fill-opacity="0.5"/>
+    <set attributeName="mask-type" to="alpha"/>
+  </mask>
+  <rect width="100" height="100" fill="blue" mask="url(#m)"/>
+</svg>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -172,16 +172,20 @@ fuzzy-if(Android,9,980) == gradient-live
 == marker-attribute-01.svg pass.svg
 == marker-viewBox-01.svg marker-viewBox-01-ref.svg
 == marker-orientation-01.svg marker-orientation-01-ref.svg
 == mask-basic-01.svg pass.svg
 == mask-basic-02.svg mask-basic-02-ref.svg
 == mask-extref-dataURI-01.svg pass.svg
 == mask-containing-masked-content-01.svg pass.svg
 == mask-transformed-01.svg mask-transformed-01-ref.svg
+pref(layout.css.masking.enabled,true) == mask-type-01.svg mask-type-01-ref.svg
+pref(layout.css.masking.enabled,true) == mask-type-02.svg mask-type-01-ref.svg
+pref(layout.css.masking.enabled,true) == mask-type-03.svg mask-type-01-ref.svg
+pref(layout.css.masking.enabled,true) == mask-type-04.svg mask-type-01-ref.svg
 == nested-viewBox-01.svg pass.svg
 == nesting-invalid-01.svg nesting-invalid-01-ref.svg
 == non-scaling-stroke-01.svg non-scaling-stroke-01-ref.svg 
 fuzzy-if(Android,9,61) fuzzy-if(!contentSameGfxBackendAsCanvas,1,99) == non-scaling-stroke-02.svg non-scaling-stroke-02-ref.svg 
 == objectBoundingBox-and-clipPath.svg pass.svg
 # Bug 588684
 random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-01.svg objectBoundingBox-and-fePointLight-01-ref.svg
 random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-02.svg objectBoundingBox-and-fePointLight-02-ref.svg
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -159,16 +159,17 @@ CSS_KEY(-moz-zoom-in, _moz_zoom_in)
 CSS_KEY(-moz-zoom-out, _moz_zoom_out)
 CSS_KEY(absolute, absolute)
 CSS_KEY(active, active)
 CSS_KEY(activeborder, activeborder)
 CSS_KEY(activecaption, activecaption)
 CSS_KEY(alias, alias)
 CSS_KEY(all, all)
 CSS_KEY(all-scroll, all_scroll)
+CSS_KEY(alpha, alpha)
 CSS_KEY(alternate, alternate)
 CSS_KEY(alternate-reverse, alternate_reverse)
 CSS_KEY(always, always)
 CSS_KEY(appworkspace, appworkspace)
 CSS_KEY(armenian, armenian)
 CSS_KEY(auto, auto)
 CSS_KEY(avoid, avoid)
 CSS_KEY(background, background)
@@ -311,16 +312,17 @@ CSS_KEY(linear, linear)
 CSS_KEY(list-item, list_item)
 CSS_KEY(logical, logical)
 CSS_KEY(lower-alpha, lower_alpha)
 CSS_KEY(lower-greek, lower_greek)
 CSS_KEY(lower-latin, lower_latin)
 CSS_KEY(lower-roman, lower_roman)
 CSS_KEY(lowercase, lowercase)
 CSS_KEY(ltr, ltr)
+CSS_KEY(luminance, luminance)
 CSS_KEY(manual, manual)
 CSS_KEY(margin-box, margin_box)
 CSS_KEY(matrix, matrix)
 CSS_KEY(matrix3d, matrix3d)
 CSS_KEY(medium, medium)
 CSS_KEY(menu, menu)
 CSS_KEY(menutext, menutext)
 CSS_KEY(message-box, message_box)
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -3289,16 +3289,26 @@ CSS_PROP_SVGRESET(
     mask,
     Mask,
     CSS_PROPERTY_PARSE_VALUE,
     "",
     VARIANT_HUO,
     nullptr,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
+CSS_PROP_SVGRESET(
+    mask-type,
+    mask_type,
+    MaskType,
+    CSS_PROPERTY_PARSE_VALUE,
+    "layout.css.masking.enabled",
+    VARIANT_HK,
+    kMaskTypeKTable,
+    offsetof(nsStyleSVGReset, mMaskType),
+    eStyleAnimType_EnumU8)
 CSS_PROP_SVG(
     shape-rendering,
     shape_rendering,
     ShapeRendering,
     CSS_PROPERTY_PARSE_VALUE,
     "",
     VARIANT_HK,
     kShapeRenderingKTable,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1581,16 +1581,22 @@ const int32_t nsCSSProps::kFillRuleKTabl
 const int32_t nsCSSProps::kImageRenderingKTable[] = {
   eCSSKeyword_auto, NS_STYLE_IMAGE_RENDERING_AUTO,
   eCSSKeyword_optimizespeed, NS_STYLE_IMAGE_RENDERING_OPTIMIZESPEED,
   eCSSKeyword_optimizequality, NS_STYLE_IMAGE_RENDERING_OPTIMIZEQUALITY,
   eCSSKeyword__moz_crisp_edges, NS_STYLE_IMAGE_RENDERING_CRISPEDGES,
   eCSSKeyword_UNKNOWN, -1
 };
 
+const int32_t nsCSSProps::kMaskTypeKTable[] = {
+  eCSSKeyword_luminance, NS_STYLE_MASK_TYPE_LUMINANCE,
+  eCSSKeyword_alpha, NS_STYLE_MASK_TYPE_ALPHA,
+  eCSSKeyword_UNKNOWN, -1
+};
+
 const int32_t nsCSSProps::kShapeRenderingKTable[] = {
   eCSSKeyword_auto, NS_STYLE_SHAPE_RENDERING_AUTO,
   eCSSKeyword_optimizespeed, NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED,
   eCSSKeyword_crispedges, NS_STYLE_SHAPE_RENDERING_CRISPEDGES,
   eCSSKeyword_geometricprecision, NS_STYLE_SHAPE_RENDERING_GEOMETRICPRECISION,
   eCSSKeyword_UNKNOWN, -1
 };
 
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -401,16 +401,17 @@ public:
   static const int32_t kFontStretchKTable[];
   static const int32_t kFontStyleKTable[];
   static const int32_t kFontVariantKTable[];
   static const int32_t kFontWeightKTable[];
   static const int32_t kIMEModeKTable[];
   static const int32_t kLineHeightKTable[];
   static const int32_t kListStylePositionKTable[];
   static const int32_t kListStyleKTable[];
+  static const int32_t kMaskTypeKTable[];
   static const int32_t kObjectOpacityKTable[];
   static const int32_t kObjectPatternKTable[];
   static const int32_t kOrientKTable[];
   static const int32_t kOutlineStyleKTable[];
   static const int32_t kOutlineColorKTable[];
   static const int32_t kOverflowKTable[];
   static const int32_t kOverflowSubKTable[];
   static const int32_t kPageBreakKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -4358,16 +4358,26 @@ nsComputedDOMStyle::DoGetMask()
     val->SetURI(svg->mMask);
   else
     val->SetIdent(eCSSKeyword_none);
 
   return val;
 }
 
 CSSValue*
+nsComputedDOMStyle::DoGetMaskType()
+{
+  nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
+  val->SetIdent(
+    nsCSSProps::ValueToKeywordEnum(GetStyleSVGReset()->mMaskType,
+                                   nsCSSProps::kMaskTypeKTable));
+  return val;
+}
+
+CSSValue*
 nsComputedDOMStyle::DoGetTransitionDelay()
 {
   const nsStyleDisplay* display = GetStyleDisplay();
 
   nsDOMCSSValueList *valueList = GetROCSSValueList(true);
 
   NS_ABORT_IF_FALSE(display->mTransitionDelayCount > 0,
                     "first item must be explicit");
@@ -4924,16 +4934,17 @@ nsComputedDOMStyle::GetQueryableProperty
     COMPUTED_STYLE_MAP_ENTRY(flood_color,                   FloodColor),
     COMPUTED_STYLE_MAP_ENTRY(flood_opacity,                 FloodOpacity),
     COMPUTED_STYLE_MAP_ENTRY(image_rendering,               ImageRendering),
     COMPUTED_STYLE_MAP_ENTRY(lighting_color,                LightingColor),
     COMPUTED_STYLE_MAP_ENTRY(marker_end,                    MarkerEnd),
     COMPUTED_STYLE_MAP_ENTRY(marker_mid,                    MarkerMid),
     COMPUTED_STYLE_MAP_ENTRY(marker_start,                  MarkerStart),
     COMPUTED_STYLE_MAP_ENTRY(mask,                          Mask),
+    COMPUTED_STYLE_MAP_ENTRY(mask_type,                     MaskType),
     COMPUTED_STYLE_MAP_ENTRY(shape_rendering,               ShapeRendering),
     COMPUTED_STYLE_MAP_ENTRY(stop_color,                    StopColor),
     COMPUTED_STYLE_MAP_ENTRY(stop_opacity,                  StopOpacity),
     COMPUTED_STYLE_MAP_ENTRY(stroke,                        Stroke),
     COMPUTED_STYLE_MAP_ENTRY(stroke_dasharray,              StrokeDasharray),
     COMPUTED_STYLE_MAP_ENTRY(stroke_dashoffset,             StrokeDashoffset),
     COMPUTED_STYLE_MAP_ENTRY(stroke_linecap,                StrokeLinecap),
     COMPUTED_STYLE_MAP_ENTRY(stroke_linejoin,               StrokeLinejoin),
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -416,16 +416,17 @@ private:
 
   mozilla::dom::CSSValue* DoGetFloodColor();
   mozilla::dom::CSSValue* DoGetLightingColor();
   mozilla::dom::CSSValue* DoGetStopColor();
 
   mozilla::dom::CSSValue* DoGetClipPath();
   mozilla::dom::CSSValue* DoGetFilter();
   mozilla::dom::CSSValue* DoGetMask();
+  mozilla::dom::CSSValue* DoGetMaskType();
 
   nsROCSSPrimitiveValue* GetROCSSPrimitiveValue();
   nsDOMCSSValueList* GetROCSSValueList(bool aCommaDelimited);
   void SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor);
   void SetValueToStyleImage(const nsStyleImage& aStyleImage,
                             nsROCSSPrimitiveValue* aValue);
 
   /**
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -7612,16 +7612,23 @@ nsRuleNode::ComputeSVGResetData(void* aS
   } else if (eCSSUnit_None == maskValue->GetUnit() ||
              eCSSUnit_Initial == maskValue->GetUnit()) {
     svgReset->mMask = nullptr;
   } else if (eCSSUnit_Inherit == maskValue->GetUnit()) {
     canStoreInRuleTree = false;
     svgReset->mMask = parentSVGReset->mMask;
   }
 
+  // mask-type: enum, inherit, initial
+  SetDiscrete(*aRuleData->ValueForMaskType(),
+              svgReset->mMaskType,
+              canStoreInRuleTree, SETDSC_ENUMERATED,
+              parentSVGReset->mMaskType,
+              NS_STYLE_MASK_TYPE_LUMINANCE, 0, 0, 0, 0);
+
   COMPUTE_END_RESET(SVGReset, svgReset)
 }
 
 const void*
 nsRuleNode::GetStyleData(nsStyleStructID aSID,
                          nsStyleContext* aContext,
                          bool aComputeData)
 {
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -965,16 +965,17 @@ nsStyleSVGReset::nsStyleSVGReset()
     mLightingColor           = NS_RGB(255,255,255);
     mClipPath                = nullptr;
     mFilter                  = nullptr;
     mMask                    = nullptr;
     mStopOpacity             = 1.0f;
     mFloodOpacity            = 1.0f;
     mDominantBaseline        = NS_STYLE_DOMINANT_BASELINE_AUTO;
     mVectorEffect            = NS_STYLE_VECTOR_EFFECT_NONE;
+    mMaskType                = NS_STYLE_MASK_TYPE_LUMINANCE;
 }
 
 nsStyleSVGReset::~nsStyleSVGReset() 
 {
   MOZ_COUNT_DTOR(nsStyleSVGReset);
 }
 
 nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset& aSource)
@@ -985,16 +986,17 @@ nsStyleSVGReset::nsStyleSVGReset(const n
   mLightingColor = aSource.mLightingColor;
   mClipPath = aSource.mClipPath;
   mFilter = aSource.mFilter;
   mMask = aSource.mMask;
   mStopOpacity = aSource.mStopOpacity;
   mFloodOpacity = aSource.mFloodOpacity;
   mDominantBaseline = aSource.mDominantBaseline;
   mVectorEffect = aSource.mVectorEffect;
+  mMaskType = aSource.mMaskType;
 }
 
 nsChangeHint nsStyleSVGReset::CalcDifference(const nsStyleSVGReset& aOther) const
 {
   nsChangeHint hint = nsChangeHint(0);
 
   if (!EqualURIs(mClipPath, aOther.mClipPath) ||
       !EqualURIs(mFilter, aOther.mFilter)     ||
@@ -1005,17 +1007,18 @@ nsChangeHint nsStyleSVGReset::CalcDiffer
   } else if (mDominantBaseline != aOther.mDominantBaseline) {
     NS_UpdateHint(hint, nsChangeHint_NeedReflow);
     NS_UpdateHint(hint, nsChangeHint_NeedDirtyReflow);
   } else if (mStopColor     != aOther.mStopColor     ||
              mFloodColor    != aOther.mFloodColor    ||
              mLightingColor != aOther.mLightingColor ||
              mStopOpacity   != aOther.mStopOpacity   ||
              mFloodOpacity  != aOther.mFloodOpacity  ||
-             mVectorEffect  != aOther.mVectorEffect)
+             mVectorEffect  != aOther.mVectorEffect  ||
+             mMaskType      != aOther.mMaskType)
     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
 
   return hint;
 }
 
 // nsStyleSVGPaint implementation
 nsStyleSVGPaint::~nsStyleSVGPaint()
 {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2273,11 +2273,12 @@ struct nsStyleSVGReset {
   nscolor          mFloodColor;       // [reset]
   nscolor          mLightingColor;    // [reset]
 
   float            mStopOpacity;      // [reset]
   float            mFloodOpacity;     // [reset]
 
   uint8_t          mDominantBaseline; // [reset] see nsStyleConsts.h
   uint8_t          mVectorEffect;     // [reset] see nsStyleConsts.h
+  uint8_t          mMaskType;         // [reset] see nsStyleConsts.h
 };
 
 #endif /* nsStyleStruct_h___ */
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -3573,16 +3573,24 @@ var gCSSProperties = {
 	"mask": {
 		domProp: "mask",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "none" ],
 		other_values: [ "url(#mymask)" ],
 		invalid_values: []
 	},
+	"mask-type": {
+		domProp: "maskType",
+		inherited: false,
+		type: CSS_TYPE_LONGHAND,
+		initial_values: [ "luminance" ],
+		other_values: [ "alpha" ],
+		invalid_values: []
+	},
 	"shape-rendering": {
 		domProp: "shapeRendering",
 		inherited: true,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "auto" ],
 		other_values: [ "optimizeSpeed", "crispEdges", "geometricPrecision" ],
 		invalid_values: []
 	},
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -114,30 +114,41 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
 
   nsIntRect rect(0, 0, surfaceSize.width, surfaceSize.height);
   nsSVGUtils::UnPremultiplyImageDataAlpha(data, stride, rect);
   if (GetStyleSVG()->mColorInterpolation ==
       NS_STYLE_COLOR_INTERPOLATION_LINEARRGB) {
     nsSVGUtils::ConvertImageDataToLinearRGB(data, stride, rect);
   }
 
-  for (int32_t y = 0; y < surfaceSize.height; y++)
-    for (int32_t x = 0; x < surfaceSize.width; x++) {
-      uint8_t *pixel = data + stride * y + 4 * x;
+  if (GetStyleSVGReset()->mMaskType == NS_STYLE_MASK_TYPE_LUMINANCE) {
+    for (int32_t y = 0; y < surfaceSize.height; y++) {
+      for (int32_t x = 0; x < surfaceSize.width; x++) {
+        uint8_t *pixel = data + stride * y + 4 * x;
+
+        /* linearRGB -> intensity */
+        uint8_t alpha =
+          static_cast<uint8_t>
+                     ((pixel[GFX_ARGB32_OFFSET_R] * 0.2125 +
+                          pixel[GFX_ARGB32_OFFSET_G] * 0.7154 +
+                          pixel[GFX_ARGB32_OFFSET_B] * 0.0721) *
+                         (pixel[GFX_ARGB32_OFFSET_A] / 255.0) * aOpacity);
 
-      /* linearRGB -> intensity */
-      uint8_t alpha =
-        static_cast<uint8_t>
-                   ((pixel[GFX_ARGB32_OFFSET_R] * 0.2125 +
-                        pixel[GFX_ARGB32_OFFSET_G] * 0.7154 +
-                        pixel[GFX_ARGB32_OFFSET_B] * 0.0721) *
-                       (pixel[GFX_ARGB32_OFFSET_A] / 255.0) * aOpacity);
-
-      memset(pixel, alpha, 4);
+        memset(pixel, alpha, 4);
+      }
     }
+  } else {
+    for (int32_t y = 0; y < surfaceSize.height; y++) {
+      for (int32_t x = 0; x < surfaceSize.width; x++) {
+        uint8_t *pixel = data + stride * y + 4 * x;
+        uint8_t alpha = pixel[GFX_ARGB32_OFFSET_A] * aOpacity;
+        memset(pixel, alpha, 4);
+      }
+    }
+  }
 
   gfxPattern *retval = new gfxPattern(image);
   retval->SetMatrix(matrix);
   NS_IF_ADDREF(retval);
   return retval;
 }
 
 /* virtual */ void
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1633,16 +1633,23 @@ pref("layout.css.visited_links_enabled",
 pref("layout.css.dpi", -1);
 
 // Set the number of device pixels per CSS pixel. A value <= 0 means choose
 // automatically based on user settings for the platform (e.g., "UI scale factor"
 // on Mac). A positive value is used as-is. This effectively controls the size
 // of a CSS "px". This is only used for windows on the screen, not for printing.
 pref("layout.css.devPixelsPerPx", "-1.0");
 
+// Is support for CSS Masking features enabled?
+#ifdef RELEASE_BUILD
+pref("layout.css.masking.enabled", false);
+#else
+pref("layout.css.masking.enabled", true);
+#endif
+
 // Is support for the the @supports rule enabled?
 #ifdef RELEASE_BUILD
 pref("layout.css.supports-rule.enabled", false);
 #else
 pref("layout.css.supports-rule.enabled", true);
 #endif
 
 // Is support for CSS Flexbox enabled?