Bug 948265 - Add CSS contrast filter to nsCSSFilterInstance. r=mstange
authorMax Vujovic <mvujovic@adobe.com>
Mon, 25 Aug 2014 12:23:21 -0700
changeset 223103 a1be86db0dd5fc947d80dc060e29aab4452ff0ba
parent 223102 6e8ee2996f56abdef8c83684da83728d74cfd0a2
child 223104 c1e44d669b444479f2eaff8da994c25d3504fa61
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs948265
milestone34.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 948265 - Add CSS contrast filter to nsCSSFilterInstance. r=mstange
layout/reftests/svg/filters/css-filters/contrast-extreme-ref.html
layout/reftests/svg/filters/css-filters/contrast-extreme.html
layout/reftests/svg/filters/css-filters/contrast-one-ref.html
layout/reftests/svg/filters/css-filters/contrast-one.html
layout/reftests/svg/filters/css-filters/contrast-percent-ref.html
layout/reftests/svg/filters/css-filters/contrast-percent.html
layout/reftests/svg/filters/css-filters/contrast-reduce-ref.html
layout/reftests/svg/filters/css-filters/contrast-reduce.html
layout/reftests/svg/filters/css-filters/contrast-ref.html
layout/reftests/svg/filters/css-filters/contrast-zero-ref.html
layout/reftests/svg/filters/css-filters/contrast-zero.html
layout/reftests/svg/filters/css-filters/contrast.html
layout/reftests/svg/filters/css-filters/reftest.list
layout/svg/nsCSSFilterInstance.cpp
layout/svg/nsCSSFilterInstance.h
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/css-filters/contrast-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: Increase the Contrast of 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/contrast-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: Increase the Contrast of 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-contrast">
+  <link rel="match" href="contrast-extreme-ref.html">
+  <meta name="assert"
+        content="Given a large factor, the CSS contrast filter function should
+                 should change color channel values to be much farther from
+                 their middle value.">
+  <style type="text/css">
+    #target {
+      filter: contrast(1000);
+      background-color: rgb(127, 129, 127); /* 127 should change to 0, and 129 should change to 255. */
+      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/contrast-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: Set the Contrast of 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/contrast-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: Set the Contrast of 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-contrast">
+  <link rel="match" href="contrast-one-ref.html">
+  <meta name="assert"
+        content="Given a factor of one, the CSS contrast filter function
+                 should not change the color of an HTML element.">
+  <style type="text/css">
+    #target {
+      filter: contrast(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/contrast-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: Increase the Contrast of 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/contrast-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: Increase the Contrast of 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-contrast">
+  <link rel="match" href="contrast-percent-ref.html">
+  <meta name="assert"
+        content="Given a percentage, the CSS contrast filter function should
+                 change the color of an HTML element.">
+  <style type="text/css">
+    #target {
+      filter: contrast(200%);
+      background-color: rgb(0, 196, 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/contrast-reduce-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: Reduce the Contrast of an HTML Element</title>
+  <link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
+  <style type="text/css">
+    #target {
+      background-color: rgb(64, 191, 64);
+      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/contrast-reduce.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: Reduce the Contrast of 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-contrast">
+  <link rel="match" href="contrast-reduce-ref.html">
+  <meta name="assert"
+        content="Given a factor of less than one, the CSS contrast filter
+                 function should change color channel values to be closer to
+                 their middle value.">
+  <style type="text/css">
+    #target {
+      filter: contrast(0.5);
+      background-color: #0f0;
+      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/contrast-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: Increase the Contrast of 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/contrast-zero-ref.html
@@ -0,0 +1,23 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+<head>
+  <title>CSS Filters: Reduce the Contrast of 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 {
+      filter: contrast(0);
+      background-color: rgb(128, 128, 128);
+      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/contrast-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: Reduce the Contrast of 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-contrast">
+  <link rel="match" href="contrast-zero-ref.html">
+  <meta name="assert"
+        content="Given a factor of zero, the CSS contrast filter function
+                 should change the color of an HTML element to gray.">
+  <style type="text/css">
+    #target {
+      filter: contrast(0);
+      background-color: rgb(0, 128, 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/contrast.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: Increase the Contrast of 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-contrast">
+  <link rel="match" href="contrast-ref.html">
+  <meta name="assert"
+        content="The CSS contrast filter function should change the color of
+                 an HTML element.">
+  <style type="text/css">
+    #target {
+      filter: contrast(2);
+      background-color: rgb(0, 196, 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/reftests/svg/filters/css-filters/reftest.list
+++ b/layout/reftests/svg/filters/css-filters/reftest.list
@@ -8,16 +8,22 @@ default-preferences pref(layout.css.filt
 == blur-zero-radius.html blur-zero-radius-ref.html
 == blur-zoomed-page.html blur-zoomed-page-ref.html
 == brightness.html brightness-ref.html
 == brightness-darken.html brightness-darken-ref.html
 == brightness-extreme.html brightness-extreme-ref.html
 == brightness-one.html brightness-one-ref.html
 == brightness-percent.html brightness-percent-ref.html
 == brightness-zero.html brightness-zero-ref.html
+== contrast.html contrast-ref.html
+== contrast-extreme.html contrast-extreme-ref.html
+== contrast-one.html contrast-one-ref.html
+== contrast-percent.html contrast-percent-ref.html
+== contrast-reduce.html contrast-reduce-ref.html
+== contrast-zero.html contrast-zero-ref.html
 == drop-shadow.html drop-shadow-ref.html
 == drop-shadow-default-color.html drop-shadow-default-color-ref.html
 == drop-shadow-negative-offset.html drop-shadow-negative-offset-ref.html
 fuzzy-if(d2d,1,10000) == grayscale.html grayscale-ref.html
 fuzzy-if(d2d,1,10000) == grayscale-one.html grayscale-one-ref.html
 fuzzy-if(d2d,1,10000) == grayscale-over-one.html grayscale-over-one-ref.html
 fuzzy-if(d2d,1,10000) == grayscale-percent.html grayscale-percent-ref.html
 == grayscale-zero.html grayscale-zero-ref.html
--- a/layout/svg/nsCSSFilterInstance.cpp
+++ b/layout/svg/nsCSSFilterInstance.cpp
@@ -50,17 +50,19 @@ nsCSSFilterInstance::BuildPrimitives(nsT
       descr = CreatePrimitiveDescription(PrimitiveType::GaussianBlur, aPrimitiveDescrs);
       result = SetAttributesForBlur(descr);
       break;
     case NS_STYLE_FILTER_BRIGHTNESS:
       descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer, aPrimitiveDescrs);
       result = SetAttributesForBrightness(descr);
       break;
     case NS_STYLE_FILTER_CONTRAST:
-      return NS_ERROR_NOT_IMPLEMENTED;
+      descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer, aPrimitiveDescrs);
+      result = SetAttributesForContrast(descr);
+      break;
     case NS_STYLE_FILTER_DROP_SHADOW:
       descr = CreatePrimitiveDescription(PrimitiveType::DropShadow, aPrimitiveDescrs);
       result = SetAttributesForDropShadow(descr);
       break;
     case NS_STYLE_FILTER_GRAYSCALE:
       descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix, aPrimitiveDescrs);
       result = SetAttributesForGrayscale(descr);
       break;
@@ -147,16 +149,42 @@ nsCSSFilterInstance::SetAttributesForBri
   identityAttrs.Set(eComponentTransferFunctionType,
                     (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY);
   aDescr.Attributes().Set(eComponentTransferFunctionA, identityAttrs);
 
   return NS_OK;
 }
 
 nsresult
+nsCSSFilterInstance::SetAttributesForContrast(FilterPrimitiveDescription& aDescr)
+{
+  const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
+  float value = styleValue.GetFactorOrPercentValue();
+  float intercept = -(0.5 * value) + 0.5;
+
+  // Set transfer functions for RGB.
+  AttributeMap contrastAttrs;
+  contrastAttrs.Set(eComponentTransferFunctionType,
+                    (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_LINEAR);
+  contrastAttrs.Set(eComponentTransferFunctionSlope, value);
+  contrastAttrs.Set(eComponentTransferFunctionIntercept, intercept);
+  aDescr.Attributes().Set(eComponentTransferFunctionR, contrastAttrs);
+  aDescr.Attributes().Set(eComponentTransferFunctionG, contrastAttrs);
+  aDescr.Attributes().Set(eComponentTransferFunctionB, contrastAttrs);
+
+  // Set identity transfer function for A.
+  AttributeMap identityAttrs;
+  identityAttrs.Set(eComponentTransferFunctionType,
+                    (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY);
+  aDescr.Attributes().Set(eComponentTransferFunctionA, identityAttrs);
+
+  return NS_OK;
+}
+
+nsresult
 nsCSSFilterInstance::SetAttributesForDropShadow(FilterPrimitiveDescription& aDescr)
 {
   nsCSSShadowArray* shadows = mFilter.GetDropShadow();
   if (!shadows || shadows->Length() != 1) {
     NS_NOTREACHED("Exactly one drop shadow should have been parsed.");
     return NS_ERROR_FAILURE;
   }
 
--- a/layout/svg/nsCSSFilterInstance.h
+++ b/layout/svg/nsCSSFilterInstance.h
@@ -59,16 +59,17 @@ private:
   FilterPrimitiveDescription CreatePrimitiveDescription(PrimitiveType aType,
                                                         const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs);
 
   /**
    * Sets aDescr's attributes using the style info in mFilter.
    */
   nsresult SetAttributesForBlur(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForBrightness(FilterPrimitiveDescription& aDescr);
+  nsresult SetAttributesForContrast(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForDropShadow(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForGrayscale(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForHueRotate(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForInvert(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForSaturate(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForSepia(FilterPrimitiveDescription& aDescr);
 
   /**