Bug 948265 - Add CSS saturate filter to nsCSSFilterInstance. r=mstange,dbaron
authorMax Vujovic <mvujovic@adobe.com>
Wed, 20 Aug 2014 17:52:28 -0700
changeset 200726 b7453585c44e95fd8ac26cd7ea3bdbaf0cad5111
parent 200725 ea0bc2228058525131f6200f78c8f9a2b7528d0a
child 200727 c1e574f7a9a39d6d3e5a6e9126e1e58ba2d4c462
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmstange, dbaron
bugs948265
milestone34.0a1
Bug 948265 - Add CSS saturate filter to nsCSSFilterInstance. r=mstange,dbaron
layout/reftests/svg/filters/css-filters/reftest.list
layout/reftests/svg/filters/css-filters/saturate-desaturate-ref.html
layout/reftests/svg/filters/css-filters/saturate-desaturate.html
layout/reftests/svg/filters/css-filters/saturate-extreme-ref.html
layout/reftests/svg/filters/css-filters/saturate-extreme.html
layout/reftests/svg/filters/css-filters/saturate-one-ref.html
layout/reftests/svg/filters/css-filters/saturate-one.html
layout/reftests/svg/filters/css-filters/saturate-percent-ref.html
layout/reftests/svg/filters/css-filters/saturate-percent.html
layout/reftests/svg/filters/css-filters/saturate-ref.html
layout/reftests/svg/filters/css-filters/saturate-zero-ref.html
layout/reftests/svg/filters/css-filters/saturate-zero.html
layout/reftests/svg/filters/css-filters/saturate.html
layout/style/nsStyleCoord.h
layout/svg/nsCSSFilterInstance.cpp
layout/svg/nsCSSFilterInstance.h
--- a/layout/reftests/svg/filters/css-filters/reftest.list
+++ b/layout/reftests/svg/filters/css-filters/reftest.list
@@ -13,8 +13,14 @@ default-preferences pref(layout.css.filt
 == hue-rotate.html hue-rotate-ref.html
 == hue-rotate-360.html hue-rotate-360-ref.html
 == hue-rotate-grad.html hue-rotate-grad-ref.html
 == hue-rotate-negative.html hue-rotate-negative-ref.html
 == hue-rotate-over-360.html hue-rotate-over-360-ref.html
 == hue-rotate-rad.html hue-rotate-rad-ref.html
 == hue-rotate-turn.html hue-rotate-turn-ref.html
 == hue-rotate-zero.html hue-rotate-zero-ref.html
+== saturate.html saturate-ref.html
+fuzzy-if(d2d,1,10000) == saturate-desaturate.html saturate-desaturate-ref.html
+== saturate-extreme.html saturate-extreme-ref.html
+== saturate-one.html saturate-one-ref.html
+== saturate-percent.html saturate-percent-ref.html
+fuzzy-if(d2d,1,10000) == saturate-zero.html saturate-zero-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-desaturate-ref.html
@@ -0,0 +1,22 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Desaturate an HTML Element</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <style type="text/css">
+    #target {
+      background-color: rgb(145, 197, 145);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a dull green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-desaturate.html
@@ -0,0 +1,28 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Desaturate an HTML Element</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-saturate">
+  <link rel="match" href="saturate-desaturate-ref.html">
+  <meta name="assert"
+        content="Given a factor of less than one, the CSS saturate filter
+                 function should dull the color of an HTML element.">
+  <style type="text/css">
+    #target {
+      filter: saturate(0.2);
+      background-color: rgb(0, 255, 0);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a dull green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-extreme-ref.html
@@ -0,0 +1,22 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Saturate an HTML Element Using a Large Factor</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <style type="text/css">
+    #target {
+      background-color: #0f0;
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a bright green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-extreme.html
@@ -0,0 +1,29 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Saturate an HTML Element Using a Large Factor</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-saturate">
+  <link rel="match" href="saturate-extreme-ref.html">
+  <meta name="assert"
+        content="Given a large factor, the CSS saturate filter function should
+                 significantly increase any non-zero color channels in an HTML
+                 element.">
+  <style type="text/css">
+    #target {
+      filter: saturate(1000);
+      background-color: rgb(0, 1, 0);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a bright green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-one-ref.html
@@ -0,0 +1,22 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Saturate an HTML Element Using a Factor of One</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <style type="text/css">
+    #target {
+      background-color: rgb(0, 128, 0);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-one.html
@@ -0,0 +1,28 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Saturate an HTML Element Using a Factor of One</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-saturate">
+  <link rel="match" href="saturate-one-ref.html">
+  <meta name="assert"
+        content="Given a factor of one, the CSS saturate filter function should
+                 not change the color of an HTML element.">
+  <style type="text/css">
+    #target {
+      filter: saturate(1);
+      background-color: rgb(0, 128, 0);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-percent-ref.html
@@ -0,0 +1,22 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Saturate an HTML Element Using a Percentage</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <style type="text/css">
+    #target {
+      background-color: #0f0;
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a bright green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-percent.html
@@ -0,0 +1,28 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Saturate an HTML Element Using a Percentage</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-saturate">
+  <link rel="match" href="saturate-percent-ref.html">
+  <meta name="assert"
+        content="Given a percentage, the CSS saturate filter function should
+                 change the color of an HTML element.">
+  <style type="text/css">
+    #target {
+      filter: saturate(500%);
+      background-color: rgb(0, 128, 0);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a bright green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-ref.html
@@ -0,0 +1,22 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Saturate an HTML Element</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <style type="text/css">
+    #target {
+      background-color: #0f0;
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a bright green square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-zero-ref.html
@@ -0,0 +1,22 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Desaturate an HTML Element Using a Factor of Zero</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <style type="text/css">
+    #target {
+      background-color: rgb(53, 53, 53);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a gray square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate-zero.html
@@ -0,0 +1,28 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Desaturate an HTML Element Using a Factor of Zero</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-saturate">
+  <link rel="match" href="saturate-zero-ref.html">
+  <meta name="assert"
+        content="Given a factor of zero, the CSS saturate filter function should
+                 completely desaturate an HTML element.">
+  <style type="text/css">
+    #target {
+      filter: saturate(0);
+      background-color: rgb(255, 0, 0);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a gray square.</p>
+  <div id="target"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/saturate.html
@@ -0,0 +1,28 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Saturate an HTML Element</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-saturate">
+  <link rel="match" href="saturate-ref.html">
+  <meta name="assert"
+        content="The CSS saturate filter function should change the color of an
+                 HTML element.">
+  <style type="text/css">
+    #target {
+      filter: saturate(5);
+      background-color: rgb(0, 128, 0);
+      width: 100px;
+      height: 100px;
+    }
+  </style>
+</head>
+<body>
+  <p>You should see a bright green square.</p>
+  <div id="target"></div>
+</body>
+</html>
--- a/layout/style/nsStyleCoord.h
+++ b/layout/style/nsStyleCoord.h
@@ -147,16 +147,17 @@ public:
     return mUnit == eStyleUnit_Coord ||
            (IsCalcUnit() && !CalcHasPercent());
   }
 
   nscoord     GetCoordValue() const;
   int32_t     GetIntValue() const;
   float       GetPercentValue() const;
   float       GetFactorValue() const;
+  float       GetFactorOrPercentValue() const;
   float       GetAngleValue() const;
   double      GetAngleValueInDegrees() const;
   double      GetAngleValueInRadians() const;
   float       GetFlexFractionValue() const;
   Calc*       GetCalcValue() const;
   uint32_t    HashValue(uint32_t aHash) const;
 
   // Sets to null and releases any refcounted objects.  Only use this if the
@@ -329,16 +330,26 @@ inline float nsStyleCoord::GetFactorValu
 {
   NS_ASSERTION(mUnit == eStyleUnit_Factor, "not a factor value");
   if (mUnit == eStyleUnit_Factor) {
     return mValue.mFloat;
   }
   return 0.0f;
 }
 
+inline float nsStyleCoord::GetFactorOrPercentValue() const
+{
+  NS_ASSERTION(mUnit == eStyleUnit_Factor || mUnit == eStyleUnit_Percent,
+               "not a percent or factor value");
+  if (mUnit == eStyleUnit_Factor || mUnit == eStyleUnit_Percent) {
+    return mValue.mFloat;
+  }
+  return 0.0f;
+}
+
 inline float nsStyleCoord::GetAngleValue() const
 {
   NS_ASSERTION(mUnit >= eStyleUnit_Degree &&
                mUnit <= eStyleUnit_Turn, "not an angle value");
   if (mUnit >= eStyleUnit_Degree && mUnit <= eStyleUnit_Turn) {
     return mValue.mFloat;
   }
   return 0.0f;
--- a/layout/svg/nsCSSFilterInstance.cpp
+++ b/layout/svg/nsCSSFilterInstance.cpp
@@ -52,17 +52,19 @@ nsCSSFilterInstance::BuildPrimitives(nsT
       descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix, aPrimitiveDescrs);
       result = SetAttributesForHueRotate(descr);
       break;
     case NS_STYLE_FILTER_INVERT:
       return NS_ERROR_NOT_IMPLEMENTED;
     case NS_STYLE_FILTER_OPACITY:
       return NS_ERROR_NOT_IMPLEMENTED;
     case NS_STYLE_FILTER_SATURATE:
-      return NS_ERROR_NOT_IMPLEMENTED;
+      descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix, aPrimitiveDescrs);
+      result = SetAttributesForSaturate(descr);
+      break;
     case NS_STYLE_FILTER_SEPIA:
       return NS_ERROR_NOT_IMPLEMENTED;
     default:
       NS_NOTREACHED("not a valid CSS filter type");
       return NS_ERROR_FAILURE;
   }
 
   if (NS_FAILED(result)) {
@@ -140,16 +142,30 @@ nsCSSFilterInstance::SetAttributesForHue
   // Set color matrix values.
   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
   float value = styleValue.GetAngleValueInDegrees();
   aDescr.Attributes().Set(eColorMatrixValues, &value, 1);
 
   return NS_OK;
 }
 
+nsresult
+nsCSSFilterInstance::SetAttributesForSaturate(FilterPrimitiveDescription& aDescr)
+{
+  // Set color matrix type.
+  aDescr.Attributes().Set(eColorMatrixType, (uint32_t)SVG_FECOLORMATRIX_TYPE_SATURATE);
+
+  // Set color matrix values.
+  const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
+  float value = styleValue.GetFactorOrPercentValue();
+  aDescr.Attributes().Set(eColorMatrixValues, &value, 1);
+
+  return NS_OK;
+}
+
 Size
 nsCSSFilterInstance::BlurRadiusToFilterSpace(nscoord aRadiusInFrameSpace)
 {
   float radiusInFrameSpaceInCSSPx =
     nsPresContext::AppUnitsToFloatCSSPixels(aRadiusInFrameSpace);
 
   // Convert the radius to filter space.
   gfxSize radiusInFilterSpace(radiusInFrameSpaceInCSSPx,
--- a/layout/svg/nsCSSFilterInstance.h
+++ b/layout/svg/nsCSSFilterInstance.h
@@ -60,16 +60,17 @@ private:
                                                         const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs);
 
   /**
    * Sets aDescr's attributes using the style info in mFilter.
    */
   nsresult SetAttributesForBlur(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForDropShadow(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForHueRotate(FilterPrimitiveDescription& aDescr);
+  nsresult SetAttributesForSaturate(FilterPrimitiveDescription& aDescr);
 
   /**
    * Returns the index of the last result in the aPrimitiveDescrs, which we'll
    * use as the input to this CSS filter.
    */
   int32_t GetLastResultIndex(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs);
 
   /**