Implement rendering support for the color-filter CSS property
https://bugs.webkit.org/show_bug.cgi?id=185047
rdar://problem/39664967

Reviewed by Tim Horton.

Source/WebCore:

The color-filter property transforms CSS colors just before painting. To support this,
add to RenderStyle colorByApplyingColorFilter() and visitedDependentColorWithColorFilter().
At most calls sites that transform colors for rendering, replace calls to
visitedDependentColor() with visitedDependentColorWithColorFilter(). The few locations
that don't use visitedDependentColor() (e.g. for shadows) call colorByApplyingColorFilter().

Color transformation is implemented via a new virtual function on FilterOperation;
BasicColorMatrixFilterOperation overrides this to use a new ColorMatrix class to
do color math, and BasicComponentTransferFilterOperation to do the equivalent of component
transfer operations. The math in both cases matches that for SVG filters, with the exception
that color components are stored as floats through multiple filters and then mapped to
normal 0-255 color components at the end.

Tests: css3/color-filters/color-filter-backgrounds-borders.html
       css3/color-filters/color-filter-box-shadow.html
       css3/color-filters/color-filter-brightness.html
       css3/color-filters/color-filter-color-property-list-item.html
       css3/color-filters/color-filter-color-property.html
       css3/color-filters/color-filter-color-text-decorations.html
       css3/color-filters/color-filter-column-rule.html
       css3/color-filters/color-filter-contrast.html
       css3/color-filters/color-filter-current-color.html
       css3/color-filters/color-filter-filter-list.html
       css3/color-filters/color-filter-grayscale.html
       css3/color-filters/color-filter-hue-rotate.html
       css3/color-filters/color-filter-inherits.html
       css3/color-filters/color-filter-invert.html
       css3/color-filters/color-filter-opacity.html
       css3/color-filters/color-filter-outline.html
       css3/color-filters/color-filter-saturate.html
       css3/color-filters/color-filter-sepia.html
       css3/color-filters/color-filter-text-emphasis.html

* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::adjustInnerTextStyle const):
* page/FrameView.cpp:
(WebCore::FrameView::documentBackgroundColor const):
* platform/graphics/ColorUtilities.cpp:
(WebCore::ColorMatrix::ColorMatrix):
(WebCore::ColorMatrix::makeIdentity):
(WebCore::ColorMatrix::grayscaleMatrix):
(WebCore::ColorMatrix::saturationMatrix):
(WebCore::ColorMatrix::hueRotateMatrix):
(WebCore::ColorMatrix::sepiaMatrix):
(WebCore::ColorMatrix::transformColorComponents const):
* platform/graphics/ColorUtilities.h:
* platform/graphics/filters/FilterOperation.cpp:
(WebCore::BasicColorMatrixFilterOperation::transformColor const):
(WebCore::BasicComponentTransferFilterOperation::transformColor const):
* platform/graphics/filters/FilterOperation.h:
(WebCore::FilterOperation::transformColor const):
* platform/graphics/filters/FilterOperations.cpp:
(WebCore::FilterOperations::transformColor const):
* platform/graphics/filters/FilterOperations.h:
* rendering/BorderEdge.cpp:
(WebCore::BorderEdge::getBorderEdgeInfo):
* rendering/EllipsisBox.cpp:
(WebCore::EllipsisBox::paint):
(WebCore::EllipsisBox::paintSelection):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::paintBoxDecorations):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paintMarkedTextForeground):
(WebCore::InlineTextBox::paintMarkedTextDecoration):
(WebCore::InlineTextBox::paintCompositionUnderline const):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::paintRootBoxFillLayers):
(WebCore::RenderBox::paintBackground):
(WebCore::RenderBox::getBackgroundPaintedExtent const):
(WebCore::RenderBox::backgroundIsKnownToBeOpaqueInRect const):
(WebCore::RenderBox::backgroundHasOpaqueTopLayer const):
* rendering/RenderBoxModelObject.cpp:
(WebCore::applyBoxShadowForBackground):
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
(WebCore::RenderBoxModelObject::boxShadowShouldBeAppliedToBackground const):
(WebCore::RenderBoxModelObject::paintBoxShadow):
* rendering/RenderDetailsMarker.cpp:
(WebCore::RenderDetailsMarker::paint):
* rendering/RenderElement.cpp:
(WebCore::RenderElement::selectionColor const):
(WebCore::RenderElement::selectionBackgroundColor const):
(WebCore::RenderElement::paintFocusRing):
(WebCore::RenderElement::paintOutline):
* rendering/RenderFileUploadControl.cpp:
(WebCore::RenderFileUploadControl::paintObject):
* rendering/RenderFrameSet.cpp:
(WebCore::RenderFrameSet::paintColumnBorder):
(WebCore::RenderFrameSet::paintRowBorder):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::paintReplaced):
(WebCore::RenderImage::paintAreaElementFocusRing):
* rendering/RenderInline.cpp:
(WebCore::RenderInline::paintOutline):
* rendering/RenderLayerBacking.cpp:
(WebCore::canDirectlyCompositeBackgroundBackgroundImage):
(WebCore::RenderLayerBacking::rendererBackgroundColor const):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::paintItemForeground):
(WebCore::RenderListBox::paintItemBackground):
* rendering/RenderListMarker.cpp:
(WebCore::RenderListMarker::paint):
* rendering/RenderMenuList.cpp:
(RenderMenuList::itemStyle const):
(RenderMenuList::getItemBackgroundColor const):
(RenderMenuList::menuStyle const):
* rendering/RenderMultiColumnSet.cpp:
(WebCore::RenderMultiColumnSet::paintColumnRules):
* rendering/RenderSearchField.cpp:
(WebCore::RenderSearchField::menuStyle const):
* rendering/RenderTable.h:
(WebCore::RenderTable::bgColor const):
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::computeCollapsedStartBorder const):
(WebCore::RenderTableCell::computeCollapsedEndBorder const):
(WebCore::RenderTableCell::computeCollapsedBeforeBorder const):
(WebCore::RenderTableCell::computeCollapsedAfterBorder const):
(WebCore::RenderTableCell::paintBackgroundsBehindCell):
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::paintRowGroupBorder):
* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::paintSliderTicks):
* rendering/TextDecorationPainter.cpp:
(WebCore::decorationColor):
* rendering/TextPaintStyle.cpp:
(WebCore::computeTextPaintStyle):
* rendering/mathml/MathOperator.cpp:
(WebCore::MathOperator::paint):
* rendering/mathml/RenderMathMLFraction.cpp:
(WebCore::RenderMathMLFraction::paint):
* rendering/mathml/RenderMathMLMenclose.cpp:
(WebCore::RenderMathMLMenclose::paint):
* rendering/mathml/RenderMathMLRoot.cpp:
(WebCore::RenderMathMLRoot::paint):
* rendering/mathml/RenderMathMLToken.cpp:
(WebCore::RenderMathMLToken::paint):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::visitedDependentColorWithColorFilter const):
(WebCore::RenderStyle::colorByApplyingColorFilter const):
* rendering/style/RenderStyle.h:

Source/WebKitLegacy/mac:

The body background should reflect the filtered color.

* WebView/WebFrame.mm:
(-[WebFrame _bodyBackgroundColor]):
* WebView/WebView.mm:
(-[WebView updateTextTouchBar]): No logic change, just cleanup.

LayoutTests:

Tests for color-filter rendering.

* css3/color-filters/color-filter-backgrounds-borders-expected.html: Added.
* css3/color-filters/color-filter-backgrounds-borders.html: Added.
* css3/color-filters/color-filter-box-shadow-expected.html: Added.
* css3/color-filters/color-filter-box-shadow.html: Added.
* css3/color-filters/color-filter-brightness-expected.html: Added.
* css3/color-filters/color-filter-brightness.html: Added.
* css3/color-filters/color-filter-color-property-expected.html: Added.
* css3/color-filters/color-filter-color-property-list-item-expected.html: Added.
* css3/color-filters/color-filter-color-property-list-item.html: Added.
* css3/color-filters/color-filter-color-property.html: Added.
* css3/color-filters/color-filter-color-text-decorations-expected.html: Added.
* css3/color-filters/color-filter-color-text-decorations.html: Added.
* css3/color-filters/color-filter-column-rule-expected.html: Added.
* css3/color-filters/color-filter-column-rule.html: Added.
* css3/color-filters/color-filter-contrast-expected.html: Added.
* css3/color-filters/color-filter-contrast.html: Added.
* css3/color-filters/color-filter-current-color-expected.html: Added.
* css3/color-filters/color-filter-current-color.html: Added.
* css3/color-filters/color-filter-filter-list-expected.html: Added.
* css3/color-filters/color-filter-filter-list.html: Added.
* css3/color-filters/color-filter-grayscale-expected.html: Added.
* css3/color-filters/color-filter-grayscale.html: Added.
* css3/color-filters/color-filter-hue-rotate-expected.html: Added.
* css3/color-filters/color-filter-hue-rotate.html: Added.
* css3/color-filters/color-filter-inherits-expected.html: Added.
* css3/color-filters/color-filter-inherits.html: Added.
* css3/color-filters/color-filter-invert-expected.html: Added.
* css3/color-filters/color-filter-invert.html: Added.
* css3/color-filters/color-filter-opacity-expected.html: Added.
* css3/color-filters/color-filter-opacity.html: Added.
* css3/color-filters/color-filter-outline-expected.html: Added.
* css3/color-filters/color-filter-outline.html: Added.
* css3/color-filters/color-filter-saturate-expected.html: Added.
* css3/color-filters/color-filter-saturate.html: Added.
* css3/color-filters/color-filter-sepia-expected.html: Added.
* css3/color-filters/color-filter-sepia.html: Added.
* css3/color-filters/color-filter-text-emphasis-expected.html: Added.
* css3/color-filters/color-filter-text-emphasis.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@231082 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d2d768b..fb73003 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,52 @@
+2018-04-26  Simon Fraser  <simon.fraser@apple.com>
+
+        Implement rendering support for the color-filter CSS property
+        https://bugs.webkit.org/show_bug.cgi?id=185047
+        rdar://problem/39664967
+
+        Reviewed by Tim Horton.
+        
+        Tests for color-filter rendering.
+
+        * css3/color-filters/color-filter-backgrounds-borders-expected.html: Added.
+        * css3/color-filters/color-filter-backgrounds-borders.html: Added.
+        * css3/color-filters/color-filter-box-shadow-expected.html: Added.
+        * css3/color-filters/color-filter-box-shadow.html: Added.
+        * css3/color-filters/color-filter-brightness-expected.html: Added.
+        * css3/color-filters/color-filter-brightness.html: Added.
+        * css3/color-filters/color-filter-color-property-expected.html: Added.
+        * css3/color-filters/color-filter-color-property-list-item-expected.html: Added.
+        * css3/color-filters/color-filter-color-property-list-item.html: Added.
+        * css3/color-filters/color-filter-color-property.html: Added.
+        * css3/color-filters/color-filter-color-text-decorations-expected.html: Added.
+        * css3/color-filters/color-filter-color-text-decorations.html: Added.
+        * css3/color-filters/color-filter-column-rule-expected.html: Added.
+        * css3/color-filters/color-filter-column-rule.html: Added.
+        * css3/color-filters/color-filter-contrast-expected.html: Added.
+        * css3/color-filters/color-filter-contrast.html: Added.
+        * css3/color-filters/color-filter-current-color-expected.html: Added.
+        * css3/color-filters/color-filter-current-color.html: Added.
+        * css3/color-filters/color-filter-filter-list-expected.html: Added.
+        * css3/color-filters/color-filter-filter-list.html: Added.
+        * css3/color-filters/color-filter-grayscale-expected.html: Added.
+        * css3/color-filters/color-filter-grayscale.html: Added.
+        * css3/color-filters/color-filter-hue-rotate-expected.html: Added.
+        * css3/color-filters/color-filter-hue-rotate.html: Added.
+        * css3/color-filters/color-filter-inherits-expected.html: Added.
+        * css3/color-filters/color-filter-inherits.html: Added.
+        * css3/color-filters/color-filter-invert-expected.html: Added.
+        * css3/color-filters/color-filter-invert.html: Added.
+        * css3/color-filters/color-filter-opacity-expected.html: Added.
+        * css3/color-filters/color-filter-opacity.html: Added.
+        * css3/color-filters/color-filter-outline-expected.html: Added.
+        * css3/color-filters/color-filter-outline.html: Added.
+        * css3/color-filters/color-filter-saturate-expected.html: Added.
+        * css3/color-filters/color-filter-saturate.html: Added.
+        * css3/color-filters/color-filter-sepia-expected.html: Added.
+        * css3/color-filters/color-filter-sepia.html: Added.
+        * css3/color-filters/color-filter-text-emphasis-expected.html: Added.
+        * css3/color-filters/color-filter-text-emphasis.html: Added.
+
 2018-04-26  Brent Fulgham  <bfulgham@apple.com>
 
         Show punycode if URL contains Latin small letter o with dot below character
diff --git a/LayoutTests/css3/color-filters/color-filter-backgrounds-borders-expected.html b/LayoutTests/css3/color-filters/color-filter-backgrounds-borders-expected.html
new file mode 100644
index 0000000..cc6f660
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-backgrounds-borders-expected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <meta name="assert" content="color-filter affects backgrounds and borders">
+        <style type="text/css">
+            .test
+            {
+				width: 200px;
+				height: 200px;
+				background-color: green;
+				border: 20px solid blue;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a green square with a blue border.</p>
+        <div class="test"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-backgrounds-borders.html b/LayoutTests/css3/color-filters/color-filter-backgrounds-borders.html
new file mode 100644
index 0000000..496f384
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-backgrounds-borders.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects backgrounds and borders</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-backgrounds-borders-expected.html">
+
+        <meta name="assert" content="color-filter affects backgrounds and borders">
+        <style type="text/css">
+            .test
+            {
+				width: 200px;
+				height: 200px;
+				background-color: rgb(255, 128, 255);
+				border: 20px solid yellow;
+				color-filter: invert();
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a green square with a blue border.</p>
+        <div class="test"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-box-shadow-expected.html b/LayoutTests/css3/color-filters/color-filter-box-shadow-expected.html
new file mode 100644
index 0000000..5ef432e
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-box-shadow-expected.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects box-shadow color</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <meta name="assert" content="color-filter affects backgrounds and borders">
+        <style type="text/css">
+            .test
+            {
+				width: 200px;
+				height: 200px;
+				background-color: green;
+				box-shadow: 50px 50px 0 blue;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a green square with an offset blue square behind it.</p>
+        <div class="test"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-box-shadow.html b/LayoutTests/css3/color-filters/color-filter-box-shadow.html
new file mode 100644
index 0000000..9d50b03
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-box-shadow.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects box-shadow color</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-box-shadow-expected.html">
+
+        <meta name="assert" content="color-filter affects box-shadow color">
+        <style type="text/css">
+            .test
+            {
+				width: 200px;
+				height: 200px;
+				background-color: rgb(255, 128, 255);
+				box-shadow: 50px 50px 0 yellow;
+				color-filter: invert();
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a green square with an offset blue square behind it.</p>
+        <div class="test"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-brightness-expected.html b/LayoutTests/css3/color-filters/color-filter-brightness-expected.html
new file mode 100644
index 0000000..5deab07
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-brightness-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="test" style=""></div>
+        <div class="test" style="border-color: rgb(0, 255, 0);"></div>
+        <div class="test" style=""></div>
+        <div class="test" style="background-color: rgb(0, 0, 128); border-color: rgb(0, 64, 0);"></div>
+        <div class="test" style="background-color: rgb(0, 0, 0); border-color: rgb(0, 0, 0);"></div>
+        <div class="test" style=""></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-brightness.html b/LayoutTests/css3/color-filters/color-filter-brightness.html
new file mode 100644
index 0000000..00b5408
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-brightness.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: brightness color-filter</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-brightness-expected.html">
+
+        <meta name="assert" content="brightness color-filter">
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test" style="color-filter: brightness()"></div>
+        <div class="test" style="color-filter: brightness(2)"></div>
+        <div class="test" style="color-filter: brightness(1)"></div>
+        <div class="test" style="color-filter: brightness(0.5)"></div>
+        <div class="test" style="color-filter: brightness(0)"></div>
+        <div class="test" style="color-filter: brightness(-0.5)"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-color-property-expected.html b/LayoutTests/css3/color-filters/color-filter-color-property-expected.html
new file mode 100644
index 0000000..1c7952a
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-color-property-expected.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            div.test
+            {
+				font: 40px Ahem;
+				color: green;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a green square.</p>
+        <div class="test">A</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-color-property-list-item-expected.html b/LayoutTests/css3/color-filters/color-filter-color-property-list-item-expected.html
new file mode 100644
index 0000000..aa7be50
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-color-property-list-item-expected.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <meta name="assert" content="color-filter affects the color of text">
+        <style type="text/css">
+            div.test
+            {
+				font: 200px Ahem;
+				color: green
+            }
+			ul {
+				margin: 0;
+			}
+			li {
+				margin-left: 100px;
+			}
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a green circle.</p>
+        <div class="test">
+			<ul>
+				<li></li>
+			</ul>
+		</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-color-property-list-item.html b/LayoutTests/css3/color-filters/color-filter-color-property-list-item.html
new file mode 100644
index 0000000..cb96e67
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-color-property-list-item.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects the color of a list item bullet</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-color-property-list-item-expected.html">
+
+        <meta name="assert" content="color-filter affects the color of a list item bullet">
+        <style type="text/css">
+            div.test
+            {
+				font: 200px Ahem;
+				color: rgb(255, 128, 255);
+				color-filter: invert();
+            }
+			ul {
+				margin: 0;
+			}
+			li {
+				margin-left: 100px;
+			}
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a green circle.</p>
+        <div class="test">
+			<ul>
+				<li></li>
+			</ul>
+		</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-color-property.html b/LayoutTests/css3/color-filters/color-filter-color-property.html
new file mode 100644
index 0000000..a61692f
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-color-property.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects the color of text</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-color-property-expected.html">
+
+        <meta name="assert" content="color-filter affects the color of text">
+        <style type="text/css">
+            div.test
+            {
+				font: 40px Ahem;
+				color: rgb(255, 128, 255);
+				color-filter: invert();
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a green square.</p>
+        <div class="test">A</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-color-text-decorations-expected.html b/LayoutTests/css3/color-filters/color-filter-color-text-decorations-expected.html
new file mode 100644
index 0000000..ed58eab
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-color-text-decorations-expected.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            div.test
+            {
+				font: 140px sans-serif;
+				color: green;
+				-webkit-text-decoration: underline overline blue;
+            }
+
+			p
+			{
+				margin: 8px;
+			}
+
+            .wavy
+            {
+				-webkit-text-decoration: underline overline wavy blue;
+            }
+
+            .dotted
+            {
+				-webkit-text-decoration: underline overline dotted blue;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>You hsould see three green letter A. The top should have a solid bar overline and underline. The second should have a wavy overline and underline. The bottom should have a dotted overline and underline.</p>
+        <div class="test">
+			<p>A<p>
+			<p class="wavy">A<p>
+			<p class="dotted">A<p>
+		</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-color-text-decorations.html b/LayoutTests/css3/color-filters/color-filter-color-text-decorations.html
new file mode 100644
index 0000000..917ad26
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-color-text-decorations.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects the color of text</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-color-text-decorations-expected.html">
+
+        <meta name="assert" content="color-filter affects the color of text decorations">
+        <style type="text/css">
+            div.test
+            {
+				font: 140px sans-serif;
+				color: rgb(255, 128, 255);
+				-webkit-text-decoration: underline overline yellow;
+				color-filter: invert();
+            }
+
+			p
+			{
+				margin: 8px;
+			}
+
+            .wavy
+            {
+				-webkit-text-decoration: underline overline wavy yellow;
+            }
+
+            .dotted
+            {
+				-webkit-text-decoration: underline overline dotted yellow;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>You hsould see three green letter A. The top should have a solid bar overline and underline. The second should have a wavy overline and underline. The bottom should have a dotted overline and underline.</p>
+        <div class="test">
+			<p>A<p>
+			<p class="wavy">A<p>
+			<p class="dotted">A<p>
+		</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-column-rule-expected.html b/LayoutTests/css3/color-filters/color-filter-column-rule-expected.html
new file mode 100644
index 0000000..a7b08e8
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-column-rule-expected.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <style type="text/css">
+            .test
+            {
+				font: 100px Ahem;
+				color: white;
+				width: 200px;
+				height: 200px;
+				columns: 2;
+				column-rule-width: 100px;
+				column-rule-color: green;
+				column-rule-style: solid;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a vertical green bar below.</p>
+        <div class="test">A A</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-column-rule.html b/LayoutTests/css3/color-filters/color-filter-column-rule.html
new file mode 100644
index 0000000..0b517bb
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-column-rule.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects column-rule color</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-column-rule-expected.html">
+
+        <meta name="assert" content="color-filter affects column-rule color">
+        <style type="text/css">
+            .test
+            {
+				font: 100px Ahem;
+				color: black;
+				width: 200px;
+				height: 200px;
+				columns: 2;
+				column-rule-width: 100px;
+				column-rule-color: rgb(255, 128, 255);
+				column-rule-style: solid;
+				color-filter: invert();
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a vertical green bar below.</p>
+        <div class="test">A A</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-contrast-expected.html b/LayoutTests/css3/color-filters/color-filter-contrast-expected.html
new file mode 100644
index 0000000..ad74844
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-contrast-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="test" style=""></div>
+        <div class="test" style=""></div>
+        <div class="test" style=""></div>
+        <div class="test" style="background-color: rgb(64, 64, 191); border-color: rgb(64, 128, 64);"></div>
+        <div class="test" style="background-color: rgb(128, 128, 128); border-color: rgb(128, 128, 128);"></div>
+        <div class="test" style=""></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-contrast.html b/LayoutTests/css3/color-filters/color-filter-contrast.html
new file mode 100644
index 0000000..bf127aa
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-contrast.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: contrast color-filter</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-contrast-expected.html">
+
+        <meta name="assert" content="contrast color-filter">
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test" style="color-filter: contrast()"></div>
+        <div class="test" style="color-filter: contrast(2)"></div>
+        <div class="test" style="color-filter: contrast(1)"></div>
+        <div class="test" style="color-filter: contrast(0.5)"></div>
+        <div class="test" style="color-filter: contrast(0)"></div>
+        <div class="test" style="color-filter: contrast(-0.5)"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-current-color-expected.html b/LayoutTests/css3/color-filters/color-filter-current-color-expected.html
new file mode 100644
index 0000000..2c7d97b
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-current-color-expected.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				height: 200px;
+				width: 200px;
+				margin: 10px;
+				color: green;
+				border: 4px solid blue;
+            }
+			
+			.first
+			{
+				background-color: currentColor;
+			}
+			
+			.second > div {
+				width: 100%;
+				height: 100%;
+				background-color: currentColor;
+			}
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there are two green squares with a blue border.</p>
+        <div class="test first"></div>
+        <div class="test second"><div></div></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-current-color.html b/LayoutTests/css3/color-filters/color-filter-current-color.html
new file mode 100644
index 0000000..7b81514
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-current-color.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects currentColor</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-current-color-expected.html">
+
+        <meta name="assert" content="color-filter affects currentColor">
+        <style type="text/css">
+            .test
+            {
+				height: 200px;
+				width: 200px;
+				margin: 10px;
+				color: rgb(255, 128, 255);
+				border: 4px solid yellow;
+				color-filter: invert();
+            }
+			
+			.first
+			{
+				background-color: currentColor;
+			}
+			
+			.second > div {
+				width: 100%;
+				height: 100%;
+				background-color: currentColor;
+			}
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there are two green squares with a blue border.</p>
+        <div class="test first"></div>
+        <div class="test second"><div></div></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-filter-list-expected.html b/LayoutTests/css3/color-filters/color-filter-filter-list-expected.html
new file mode 100644
index 0000000..14d0c72
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-filter-list-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: purple;
+				outline: 50px solid green;
+				margin: 60px;
+				float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="test" style=""></div>
+        <div class="test" style=""></div>
+        <div class="test" style="background-color: rgb(255, 182, 255); outline-color: rgb(72, 200, 72);"></div>
+        <div class="test" style="background-color: rgba(220, 0, 220, 0.50196); outline-color: rgba(0, 164, 0, 0.50196);"></div>
+        <div class="test" style="background-color: rgb(219, 15, 219); outline-color: rgb(37, 241, 37);"></div>
+        <div class="test" style="background-color: rgb(149, 132, 103); outline-color: rgb(197, 176, 137);"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-filter-list.html b/LayoutTests/css3/color-filters/color-filter-filter-list.html
new file mode 100644
index 0000000..318844b
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-filter-list.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter lists</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-filter-list-expected.html">
+
+        <meta name="assert" content="color-filter lists">
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: purple;
+				outline: 50px solid green;
+				margin: 60px;
+				float: left;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test"></div>
+        <div class="test" style="color-filter: brightness(2) brightness(0.5)"></div>
+        <div class="test" style="color-filter: invert() hue-rotate(180deg)"></div>
+        <div class="test" style="color-filter: opacity(0.5) saturate(200%)"></div>
+        <div class="test" style="color-filter: grayscale(0.2) brightness(2)"></div>
+        <div class="test" style="color-filter: sepia() brightness(2)"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-grayscale-expected.html b/LayoutTests/css3/color-filters/color-filter-grayscale-expected.html
new file mode 100644
index 0000000..9b70599
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-grayscale-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="test" style="background-color: rgb(18, 18, 18); border-color: rgb(92, 92, 92);"></div>
+        <div class="test" style="background-color: rgb(18, 18, 18); border-color: rgb(92, 92, 92);"></div>
+        <div class="test" style="background-color: rgb(18, 18, 18); border-color: rgb(92, 92, 92);"></div>
+        <div class="test" style="background-color: rgb(9, 9, 137); border-color: rgb(46, 110, 46);"></div>
+        <div class="test" style=""></div>
+        <div class="test" style=""></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-grayscale.html b/LayoutTests/css3/color-filters/color-filter-grayscale.html
new file mode 100644
index 0000000..fa5440b
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-grayscale.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: grayscale color-filter</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-grayscale-expected.html">
+
+        <meta name="assert" content="grayscale color-filter">
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test" style="color-filter: grayscale()"></div>
+        <div class="test" style="color-filter: grayscale(2)"></div>
+        <div class="test" style="color-filter: grayscale(1)"></div>
+        <div class="test" style="color-filter: grayscale(0.5)"></div>
+        <div class="test" style="color-filter: grayscale(0)"></div>
+        <div class="test" style="color-filter: grayscale(-0.5)"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-hue-rotate-expected.html b/LayoutTests/css3/color-filters/color-filter-hue-rotate-expected.html
new file mode 100644
index 0000000..4ca29a1
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-hue-rotate-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="test" style=""></div>
+        <div class="test" style="background-color: rgb(37, 37, 0); border-color: rgb(183, 55, 183);"></div>
+        <div class="test" style=""></div>
+        <div class="test" style="background-color: rgb(255, 0, 37); border-color: rgb(0, 109, 183);"></div>
+        <div class="test" style=""></div>
+        <div class="test" style="background-color: rgb(37, 37, 0); border-color: rgb(183, 55, 183);"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-hue-rotate.html b/LayoutTests/css3/color-filters/color-filter-hue-rotate.html
new file mode 100644
index 0000000..350bbca
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-hue-rotate.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: hue-rotate color-filter</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-hue-rotate-expected.html">
+
+        <meta name="assert" content="hue-rotate color-filter">
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test" style="color-filter: hue-rotate()"></div>
+        <div class="test" style="color-filter: hue-rotate(540deg)"></div>
+        <div class="test" style="color-filter: hue-rotate(360deg)"></div>
+        <div class="test" style="color-filter: hue-rotate(90deg)"></div>
+        <div class="test" style="color-filter: hue-rotate(0)"></div>
+        <div class="test" style="color-filter: hue-rotate(-180deg)"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-inherits-expected.html b/LayoutTests/css3/color-filters/color-filter-inherits-expected.html
new file mode 100644
index 0000000..5973ae7
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-inherits-expected.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				font: 120px Ahem;
+            }
+			
+			.test > div {
+				color: green;
+			}
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a green square.</p>
+        <div class="test">
+			<div>A</div>
+		</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-inherits.html b/LayoutTests/css3/color-filters/color-filter-inherits.html
new file mode 100644
index 0000000..a68e6d0
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-inherits.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter is inherited</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-inherits-expected.html">
+
+        <meta name="assert" content="color-filter is inherited">
+        <style type="text/css">
+            .test
+            {
+				font: 120px Ahem;
+				color-filter: invert();
+            }
+			
+			.test > div {
+				color: rgb(255, 128, 255);
+			}
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a green square.</p>
+        <div class="test">
+			<div>A</div>
+		</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-invert-expected.html b/LayoutTests/css3/color-filters/color-filter-invert-expected.html
new file mode 100644
index 0000000..99d9edd
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-invert-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="test" style="background-color: rgb(255, 255, 0); border-color: rgb(255, 127, 255)"></div>
+        <div class="test" style="background-color: rgb(255, 255, 0); border-color: rgb(255, 127, 255)"></div>
+        <div class="test" style="background-color: rgb(255, 255, 0); border-color: rgb(255, 127, 255)"></div>
+        <div class="test" style="background-color: rgb(128, 128, 128); border-color: rgb(128, 128, 128)"></div>
+        <div class="test"></div>
+        <div class="test"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-invert.html b/LayoutTests/css3/color-filters/color-filter-invert.html
new file mode 100644
index 0000000..6aad512
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-invert.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: invert color-filter</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-invert-expected.html">
+
+        <meta name="assert" content="invert color-filter">
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test" style="color-filter: invert()"></div>
+        <div class="test" style="color-filter: invert(2)"></div>
+        <div class="test" style="color-filter: invert(1)"></div>
+        <div class="test" style="color-filter: invert(0.5)"></div>
+        <div class="test" style="color-filter: invert(0)"></div>
+        <div class="test" style="color-filter: invert(-0.5)"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-opacity-expected.html b/LayoutTests/css3/color-filters/color-filter-opacity-expected.html
new file mode 100644
index 0000000..c05bc5c
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-opacity-expected.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 200px;
+				height: 200px;
+				background-color: green;
+				margin: 10px;
+				float: left;
+            }
+			
+			.test > div {
+				width: 100px;
+				height: 100px;
+				margin: 50px;
+				background-color: blue;
+			}
+        </style>
+    </head>
+    <body>
+        <div class="test">
+			<div></div>
+		</div>
+        <div class="test">
+			<div></div>
+		</div>
+        <div class="test">
+			<div></div>
+		</div>
+        <div class="test" style="background-color: rgba(0, 128, 0, 0.50196)">
+			<div style="background-color: rgba(0, 0, 255, 0.5)"></div>
+		</div>
+        <div class="test" style="background-color: transparent">
+			<div style="background-color: transparent"></div>
+		</div>
+        <div class="test">
+			<div></div>
+		</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-opacity.html b/LayoutTests/css3/color-filters/color-filter-opacity.html
new file mode 100644
index 0000000..fd5d9dc
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-opacity.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: opacity color-filter</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-opacity-expected.html">
+
+        <meta name="assert" content="opacity color-filter">
+        <style type="text/css">
+            .test
+            {
+				width: 200px;
+				height: 200px;
+				background-color: green;
+				margin: 10px;
+				float: left;
+            }
+			
+			.test > div {
+				width: 100px;
+				height: 100px;
+				margin: 50px;
+				background-color: blue;
+			}
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test" style="color-filter: opacity()"><div></div></div>
+        <div class="test" style="color-filter: opacity(2)"><div></div></div>
+        <div class="test" style="color-filter: opacity(1)"><div></div></div>
+        <div class="test" style="color-filter: opacity(0.5)"><div></div></div>
+        <div class="test" style="color-filter: opacity(0)"><div></div></div>
+        <div class="test" style="color-filter: opacity(-0.5)"><div></div></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-outline-expected.html b/LayoutTests/css3/color-filters/color-filter-outline-expected.html
new file mode 100644
index 0000000..4b72668
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-outline-expected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 200px;
+				height: 200px;
+				margin: 50px;
+				background-color: green;
+				outline: 20px solid blue;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a green square with a blue outline.</p>
+        <div class="test"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-outline.html b/LayoutTests/css3/color-filters/color-filter-outline.html
new file mode 100644
index 0000000..b590cd2
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-outline.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects outline color</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-outline-expected.html">
+
+        <meta name="assert" content="color-filter affects outline color">
+        <style type="text/css">
+            .test
+            {
+				width: 200px;
+				height: 200px;
+				margin: 50px;
+				background-color: rgb(255, 128, 255);
+				outline: 20px solid yellow;
+				color-filter: invert();
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there is a green square with a blue outline.</p>
+        <div class="test"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-saturate-expected.html b/LayoutTests/css3/color-filters/color-filter-saturate-expected.html
new file mode 100644
index 0000000..4e7eadd
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-saturate-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="test" style=""></div>
+        <div class="test" style=""></div>
+        <div class="test" style="background-color: rgb(0, 0, 255); border-color: rgb(0, 164, 0);"></div>
+        <div class="test" style="background-color: rgb(9, 9, 137); border-color: rgb(46, 110, 46);"></div>
+        <div class="test" style="background-color: rgb(18, 18, 18); border-color: rgb(92, 92, 92);"></div>
+        <div class="test" style=""></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-saturate.html b/LayoutTests/css3/color-filters/color-filter-saturate.html
new file mode 100644
index 0000000..22cd111
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-saturate.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: saturate color-filter</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-saturate-expected.html">
+
+        <meta name="assert" content="saturate color-filter">
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test" style="color-filter: saturate()"></div>
+        <div class="test" style="color-filter: saturate(1)"></div>
+        <div class="test" style="color-filter: saturate(2)"></div>
+        <div class="test" style="color-filter: saturate(0.5)"></div>
+        <div class="test" style="color-filter: saturate(0)"></div>
+        <div class="test" style="color-filter: saturate(-0.5)"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-sepia-expected.html b/LayoutTests/css3/color-filters/color-filter-sepia-expected.html
new file mode 100644
index 0000000..6ccb7d2
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-sepia-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <div class="test" style="background-color: rgb(48, 43, 33); border-color: rgb(98, 88, 68);"></div>
+        <div class="test" style="background-color: rgb(48, 43, 33); border-color: rgb(98, 88, 68);"></div>
+        <div class="test" style="background-color: rgb(48, 43, 33); border-color: rgb(98, 88, 68);"></div>
+        <div class="test" style="background-color: rgb(24, 21, 144); border-color: rgb(49, 108, 34);"></div>
+        <div class="test" style=""></div>
+        <div class="test" style=""></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-sepia.html b/LayoutTests/css3/color-filters/color-filter-sepia.html
new file mode 100644
index 0000000..2dbb6cf
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-sepia.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: sepia color-filter</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-sepia-expected.html">
+
+        <meta name="assert" content="sepia color-filter">
+        <style type="text/css">
+            .test
+            {
+				width: 100px;
+				height: 100px;
+				background-color: blue;
+				border: 50px solid green;
+				margin: 10px;
+				float: left;
+            }
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <div class="test" style="color-filter: sepia()"></div>
+        <div class="test" style="color-filter: sepia(2)"></div>
+        <div class="test" style="color-filter: sepia(1)"></div>
+        <div class="test" style="color-filter: sepia(0.5)"></div>
+        <div class="test" style="color-filter: sepia(0)"></div>
+        <div class="test" style="color-filter: sepia(-0.5)"></div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-text-emphasis-expected.html b/LayoutTests/css3/color-filters/color-filter-text-emphasis-expected.html
new file mode 100644
index 0000000..413526a
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-text-emphasis-expected.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter reference</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+
+        <style type="text/css">
+            .test
+            {
+				font: 120px Ahem;
+				color: green;
+				margin: 10px;
+            }
+
+			.over
+			{
+				-webkit-text-emphasis: "m";
+				-webkit-text-emphasis-position: over;
+			}
+			
+			.under
+			{
+				-webkit-text-emphasis: "m";
+				-webkit-text-emphasis-position: under;
+			}
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there are two shapes which are entirely green.</p>
+        <div class="test over">A</div>
+        <div class="test under">A</div>
+    </body>
+</html>
diff --git a/LayoutTests/css3/color-filters/color-filter-text-emphasis.html b/LayoutTests/css3/color-filters/color-filter-text-emphasis.html
new file mode 100644
index 0000000..09ac26c
--- /dev/null
+++ b/LayoutTests/css3/color-filters/color-filter-text-emphasis.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Test: color-filter affects text-emphasis color</title>
+        <link rel="author" title="Apple" href="http://www.apple.com/">
+        <link rel="match" href="color-filter-text-emphasis-expected.html">
+
+        <meta name="assert" content="color-filter affects the color of text-emphasis">
+        <style type="text/css">
+            .test
+            {
+				font: 120px Ahem;
+				color: rgb(255, 128, 255);
+				color-filter: invert();
+				margin: 10px;
+            }
+
+			.over
+			{
+				-webkit-text-emphasis: "m";
+				-webkit-text-emphasis-position: over;
+			}
+			
+			.under
+			{
+				-webkit-text-emphasis: "m";
+				-webkit-text-emphasis-position: under;
+			}
+        </style>
+		<script>
+			if (window.internals)
+			    internals.settings.setColorFilterEnabled(true);
+		</script>
+    </head>
+    <body>
+        <p>Test passes if there are two shapes which are entirely green.</p>
+        <div class="test over">A</div>
+        <div class="test under">A</div>
+    </body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index f80c07f..542a4f3 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,153 @@
+2018-04-26  Simon Fraser  <simon.fraser@apple.com>
+
+        Implement rendering support for the color-filter CSS property
+        https://bugs.webkit.org/show_bug.cgi?id=185047
+        rdar://problem/39664967
+
+        Reviewed by Tim Horton.
+        
+        The color-filter property transforms CSS colors just before painting. To support this,
+        add to RenderStyle colorByApplyingColorFilter() and visitedDependentColorWithColorFilter().
+        At most calls sites that transform colors for rendering, replace calls to
+        visitedDependentColor() with visitedDependentColorWithColorFilter(). The few locations
+        that don't use visitedDependentColor() (e.g. for shadows) call colorByApplyingColorFilter().
+        
+        Color transformation is implemented via a new virtual function on FilterOperation;
+        BasicColorMatrixFilterOperation overrides this to use a new ColorMatrix class to
+        do color math, and BasicComponentTransferFilterOperation to do the equivalent of component
+        transfer operations. The math in both cases matches that for SVG filters, with the exception
+        that color components are stored as floats through multiple filters and then mapped to
+        normal 0-255 color components at the end.
+
+        Tests: css3/color-filters/color-filter-backgrounds-borders.html
+               css3/color-filters/color-filter-box-shadow.html
+               css3/color-filters/color-filter-brightness.html
+               css3/color-filters/color-filter-color-property-list-item.html
+               css3/color-filters/color-filter-color-property.html
+               css3/color-filters/color-filter-color-text-decorations.html
+               css3/color-filters/color-filter-column-rule.html
+               css3/color-filters/color-filter-contrast.html
+               css3/color-filters/color-filter-current-color.html
+               css3/color-filters/color-filter-filter-list.html
+               css3/color-filters/color-filter-grayscale.html
+               css3/color-filters/color-filter-hue-rotate.html
+               css3/color-filters/color-filter-inherits.html
+               css3/color-filters/color-filter-invert.html
+               css3/color-filters/color-filter-opacity.html
+               css3/color-filters/color-filter-outline.html
+               css3/color-filters/color-filter-saturate.html
+               css3/color-filters/color-filter-sepia.html
+               css3/color-filters/color-filter-text-emphasis.html
+
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::adjustInnerTextStyle const):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::documentBackgroundColor const):
+        * platform/graphics/ColorUtilities.cpp:
+        (WebCore::ColorMatrix::ColorMatrix):
+        (WebCore::ColorMatrix::makeIdentity):
+        (WebCore::ColorMatrix::grayscaleMatrix):
+        (WebCore::ColorMatrix::saturationMatrix):
+        (WebCore::ColorMatrix::hueRotateMatrix):
+        (WebCore::ColorMatrix::sepiaMatrix):
+        (WebCore::ColorMatrix::transformColorComponents const):
+        * platform/graphics/ColorUtilities.h:
+        * platform/graphics/filters/FilterOperation.cpp:
+        (WebCore::BasicColorMatrixFilterOperation::transformColor const):
+        (WebCore::BasicComponentTransferFilterOperation::transformColor const):
+        * platform/graphics/filters/FilterOperation.h:
+        (WebCore::FilterOperation::transformColor const):
+        * platform/graphics/filters/FilterOperations.cpp:
+        (WebCore::FilterOperations::transformColor const):
+        * platform/graphics/filters/FilterOperations.h:
+        * rendering/BorderEdge.cpp:
+        (WebCore::BorderEdge::getBorderEdgeInfo):
+        * rendering/EllipsisBox.cpp:
+        (WebCore::EllipsisBox::paint):
+        (WebCore::EllipsisBox::paintSelection):
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::paintBoxDecorations):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paintMarkedTextForeground):
+        (WebCore::InlineTextBox::paintMarkedTextDecoration):
+        (WebCore::InlineTextBox::paintCompositionUnderline const):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::paintRootBoxFillLayers):
+        (WebCore::RenderBox::paintBackground):
+        (WebCore::RenderBox::getBackgroundPaintedExtent const):
+        (WebCore::RenderBox::backgroundIsKnownToBeOpaqueInRect const):
+        (WebCore::RenderBox::backgroundHasOpaqueTopLayer const):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::applyBoxShadowForBackground):
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+        (WebCore::RenderBoxModelObject::boxShadowShouldBeAppliedToBackground const):
+        (WebCore::RenderBoxModelObject::paintBoxShadow):
+        * rendering/RenderDetailsMarker.cpp:
+        (WebCore::RenderDetailsMarker::paint):
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::selectionColor const):
+        (WebCore::RenderElement::selectionBackgroundColor const):
+        (WebCore::RenderElement::paintFocusRing):
+        (WebCore::RenderElement::paintOutline):
+        * rendering/RenderFileUploadControl.cpp:
+        (WebCore::RenderFileUploadControl::paintObject):
+        * rendering/RenderFrameSet.cpp:
+        (WebCore::RenderFrameSet::paintColumnBorder):
+        (WebCore::RenderFrameSet::paintRowBorder):
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::paintReplaced):
+        (WebCore::RenderImage::paintAreaElementFocusRing):
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::paintOutline):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::canDirectlyCompositeBackgroundBackgroundImage):
+        (WebCore::RenderLayerBacking::rendererBackgroundColor const):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::paintItemForeground):
+        (WebCore::RenderListBox::paintItemBackground):
+        * rendering/RenderListMarker.cpp:
+        (WebCore::RenderListMarker::paint):
+        * rendering/RenderMenuList.cpp:
+        (RenderMenuList::itemStyle const):
+        (RenderMenuList::getItemBackgroundColor const):
+        (RenderMenuList::menuStyle const):
+        * rendering/RenderMultiColumnSet.cpp:
+        (WebCore::RenderMultiColumnSet::paintColumnRules):
+        * rendering/RenderSearchField.cpp:
+        (WebCore::RenderSearchField::menuStyle const):
+        * rendering/RenderTable.h:
+        (WebCore::RenderTable::bgColor const):
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::computeCollapsedStartBorder const):
+        (WebCore::RenderTableCell::computeCollapsedEndBorder const):
+        (WebCore::RenderTableCell::computeCollapsedBeforeBorder const):
+        (WebCore::RenderTableCell::computeCollapsedAfterBorder const):
+        (WebCore::RenderTableCell::paintBackgroundsBehindCell):
+        * rendering/RenderTableSection.cpp:
+        (WebCore::RenderTableSection::paintRowGroupBorder):
+        * rendering/RenderTheme.cpp:
+        (WebCore::RenderTheme::paintSliderTicks):
+        * rendering/TextDecorationPainter.cpp:
+        (WebCore::decorationColor):
+        * rendering/TextPaintStyle.cpp:
+        (WebCore::computeTextPaintStyle):
+        * rendering/mathml/MathOperator.cpp:
+        (WebCore::MathOperator::paint):
+        * rendering/mathml/RenderMathMLFraction.cpp:
+        (WebCore::RenderMathMLFraction::paint):
+        * rendering/mathml/RenderMathMLMenclose.cpp:
+        (WebCore::RenderMathMLMenclose::paint):
+        * rendering/mathml/RenderMathMLRoot.cpp:
+        (WebCore::RenderMathMLRoot::paint):
+        * rendering/mathml/RenderMathMLToken.cpp:
+        (WebCore::RenderMathMLToken::paint):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::visitedDependentColorWithColorFilter const):
+        (WebCore::RenderStyle::colorByApplyingColorFilter const):
+        * rendering/style/RenderStyle.h:
+
 2018-04-26  Mark Lam  <mark.lam@apple.com>
 
         Gardening: Speculative build fix for Windows.
diff --git a/Source/WebCore/html/HTMLTextFormControlElement.cpp b/Source/WebCore/html/HTMLTextFormControlElement.cpp
index ed14857..58f91aa 100644
--- a/Source/WebCore/html/HTMLTextFormControlElement.cpp
+++ b/Source/WebCore/html/HTMLTextFormControlElement.cpp
@@ -814,7 +814,7 @@
     }
 
     if (isDisabledFormControl())
-        textBlockStyle.setColor(RenderTheme::singleton().disabledTextColor(textBlockStyle.visitedDependentColor(CSSPropertyColor), parentStyle.visitedDependentColor(CSSPropertyBackgroundColor)));
+        textBlockStyle.setColor(RenderTheme::singleton().disabledTextColor(textBlockStyle.visitedDependentColorWithColorFilter(CSSPropertyColor), parentStyle.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor)));
 #if PLATFORM(IOS)
     if (textBlockStyle.textSecurity() != TSNONE && !textBlockStyle.isLeftToRightDirection()) {
         // Preserve the alignment but force the direction to LTR so that the last-typed, unmasked character
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index ff3b8aa..3bd022f 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -3885,9 +3885,9 @@
     Color htmlBackgroundColor;
     Color bodyBackgroundColor;
     if (htmlElement && htmlElement->renderer())
-        htmlBackgroundColor = htmlElement->renderer()->style().visitedDependentColor(CSSPropertyBackgroundColor);
+        htmlBackgroundColor = htmlElement->renderer()->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     if (bodyElement && bodyElement->renderer())
-        bodyBackgroundColor = bodyElement->renderer()->style().visitedDependentColor(CSSPropertyBackgroundColor);
+        bodyBackgroundColor = bodyElement->renderer()->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
 
     if (!bodyBackgroundColor.isValid()) {
         if (!htmlBackgroundColor.isValid())
diff --git a/Source/WebCore/platform/graphics/ColorUtilities.cpp b/Source/WebCore/platform/graphics/ColorUtilities.cpp
index 3f91777..0ba6c4c 100644
--- a/Source/WebCore/platform/graphics/ColorUtilities.cpp
+++ b/Source/WebCore/platform/graphics/ColorUtilities.cpp
@@ -78,4 +78,119 @@
     return Color(r, g, b, a);
 }
 
+
+ColorMatrix::ColorMatrix()
+{
+    makeIdentity();
+}
+
+void ColorMatrix::makeIdentity()
+{
+    memset(m_matrix, 0, sizeof(m_matrix));
+    m_matrix[0][0] = 1;
+    m_matrix[1][1] = 1;
+    m_matrix[2][2] = 1;
+    m_matrix[3][3] = 1;
+}
+
+ColorMatrix ColorMatrix::grayscaleMatrix(float amount)
+{
+    ColorMatrix matrix;
+
+    float oneMinusAmount = clampTo(1 - amount, 0.0, 1.0);
+
+    // Values from https://www.w3.org/TR/filter-effects-1/#grayscaleEquivalent
+    matrix.m_matrix[0][0] = 0.2126f + 0.7874f * oneMinusAmount;
+    matrix.m_matrix[0][1] = 0.7152f - 0.7152f * oneMinusAmount;
+    matrix.m_matrix[0][2] = 0.0722f - 0.0722f * oneMinusAmount;
+
+    matrix.m_matrix[1][0] = 0.2126f - 0.2126f * oneMinusAmount;
+    matrix.m_matrix[1][1] = 0.7152f + 0.2848f * oneMinusAmount;
+    matrix.m_matrix[1][2] = 0.0722f - 0.0722f * oneMinusAmount;
+
+    matrix.m_matrix[2][0] = 0.2126f - 0.2126f * oneMinusAmount;
+    matrix.m_matrix[2][1] = 0.7152f - 0.7152f * oneMinusAmount;
+    matrix.m_matrix[2][2] = 0.0722f + 0.9278f * oneMinusAmount;
+    
+    return matrix;
+}
+
+ColorMatrix ColorMatrix::saturationMatrix(float amount)
+{
+    ColorMatrix matrix;
+
+    // Values from https://www.w3.org/TR/filter-effects-1/#feColorMatrixElement
+    matrix.m_matrix[0][0] = 0.213f + 0.787f * amount;
+    matrix.m_matrix[0][1] = 0.715f - 0.715f * amount;
+    matrix.m_matrix[0][2] = 0.072f - 0.072f * amount;
+
+    matrix.m_matrix[1][0] = 0.213f - 0.213f * amount;
+    matrix.m_matrix[1][1] = 0.715f + 0.285f * amount;
+    matrix.m_matrix[1][2] = 0.072f - 0.072f * amount;
+
+    matrix.m_matrix[2][0] = 0.213f - 0.213f * amount;
+    matrix.m_matrix[2][1] = 0.715f - 0.715f * amount;
+    matrix.m_matrix[2][2] = 0.072f + 0.928f * amount;
+
+    return matrix;
+}
+
+ColorMatrix ColorMatrix::hueRotateMatrix(float angleInDegrees)
+{
+    float cosHue = cos(deg2rad(angleInDegrees));
+    float sinHue = sin(deg2rad(angleInDegrees));
+
+    ColorMatrix matrix;
+
+    // Values from https://www.w3.org/TR/filter-effects-1/#feColorMatrixElement
+    matrix.m_matrix[0][0] = 0.213f + cosHue * 0.787f - sinHue * 0.213f;
+    matrix.m_matrix[0][1] = 0.715f - cosHue * 0.715f - sinHue * 0.715f;
+    matrix.m_matrix[0][2] = 0.072f - cosHue * 0.072f + sinHue * 0.928f;
+
+    matrix.m_matrix[1][0] = 0.213f - cosHue * 0.213f + sinHue * 0.143f;
+    matrix.m_matrix[1][1] = 0.715f + cosHue * 0.285f + sinHue * 0.140f;
+    matrix.m_matrix[1][2] = 0.072f - cosHue * 0.072f - sinHue * 0.283f;
+
+    matrix.m_matrix[2][0] = 0.213f - cosHue * 0.213f - sinHue * 0.787f;
+    matrix.m_matrix[2][1] = 0.715f - cosHue * 0.715f + sinHue * 0.715f;
+    matrix.m_matrix[2][2] = 0.072f + cosHue * 0.928f + sinHue * 0.072f;
+
+    return matrix;
+}
+
+ColorMatrix ColorMatrix::sepiaMatrix(float amount)
+{
+    ColorMatrix matrix;
+
+    float oneMinusAmount = clampTo(1 - amount, 0.0, 1.0);
+
+    // Values from https://www.w3.org/TR/filter-effects-1/#sepiaEquivalent
+    matrix.m_matrix[0][0] = 0.393f + 0.607f * oneMinusAmount;
+    matrix.m_matrix[0][1] = 0.769f - 0.769f * oneMinusAmount;
+    matrix.m_matrix[0][2] = 0.189f - 0.189f * oneMinusAmount;
+
+    matrix.m_matrix[1][0] = 0.349f - 0.349f * oneMinusAmount;
+    matrix.m_matrix[1][1] = 0.686f + 0.314f * oneMinusAmount;
+    matrix.m_matrix[1][2] = 0.168f - 0.168f * oneMinusAmount;
+
+    matrix.m_matrix[2][0] = 0.272f - 0.272f * oneMinusAmount;
+    matrix.m_matrix[2][1] = 0.534f - 0.534f * oneMinusAmount;
+    matrix.m_matrix[2][2] = 0.131f + 0.869f * oneMinusAmount;
+
+    return matrix;
+}
+
+void ColorMatrix::transformColorComponents(FloatComponents& colorComonents) const
+{
+    float red = colorComonents.components[0];
+    float green = colorComonents.components[1];
+    float blue = colorComonents.components[2];
+    float alpha = colorComonents.components[3];
+
+    colorComonents.components[0] = m_matrix[0][0] * red + m_matrix[0][1] * green + m_matrix[0][2] * blue + m_matrix[0][3] * alpha + m_matrix[0][4];
+    colorComonents.components[1] = m_matrix[1][0] * red + m_matrix[1][1] * green + m_matrix[1][2] * blue + m_matrix[1][3] * alpha + m_matrix[1][4];
+    colorComonents.components[2] = m_matrix[2][0] * red + m_matrix[2][1] * green + m_matrix[2][2] * blue + m_matrix[2][3] * alpha + m_matrix[2][4];
+    colorComonents.components[3] = m_matrix[3][0] * red + m_matrix[3][1] * green + m_matrix[3][2] * blue + m_matrix[3][3] * alpha + m_matrix[3][4];
+}
+
 } // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/ColorUtilities.h b/Source/WebCore/platform/graphics/ColorUtilities.h
index 54573d7..502ec19 100644
--- a/Source/WebCore/platform/graphics/ColorUtilities.h
+++ b/Source/WebCore/platform/graphics/ColorUtilities.h
@@ -155,5 +155,22 @@
 Color linearToSRGBColor(const Color&);
 Color sRGBToLinearColor(const Color&);
 
+class ColorMatrix {
+public:
+    static ColorMatrix grayscaleMatrix(float);
+    static ColorMatrix saturationMatrix(float);
+    static ColorMatrix hueRotateMatrix(float angleInDegrees);
+    static ColorMatrix sepiaMatrix(float);
+
+    ColorMatrix();
+    
+    void transformColorComponents(FloatComponents&) const;
+
+private:
+    void makeIdentity();
+
+    float m_matrix[4][5];
+};
+
 } // namespace WebCore
 
diff --git a/Source/WebCore/platform/graphics/filters/FilterOperation.cpp b/Source/WebCore/platform/graphics/filters/FilterOperation.cpp
index 22d7737..79f60e1 100644
--- a/Source/WebCore/platform/graphics/filters/FilterOperation.cpp
+++ b/Source/WebCore/platform/graphics/filters/FilterOperation.cpp
@@ -29,6 +29,7 @@
 #include "AnimationUtilities.h"
 #include "CachedResourceLoader.h"
 #include "CachedSVGDocumentReference.h"
+#include "ColorUtilities.h"
 #include "FilterEffect.h"
 #include "SVGURIReference.h"
 #include <wtf/text/TextStream.h>
@@ -88,6 +89,37 @@
     return BasicColorMatrixFilterOperation::create(WebCore::blend(fromAmount, m_amount, progress), m_type);
 }
 
+bool BasicColorMatrixFilterOperation::transformColor(FloatComponents& colorComponents) const
+{
+    switch (m_type) {
+    case GRAYSCALE: {
+        ColorMatrix matrix = ColorMatrix::grayscaleMatrix(m_amount);
+        matrix.transformColorComponents(colorComponents);
+        return true;
+    }
+    case SEPIA: {
+        ColorMatrix matrix = ColorMatrix::sepiaMatrix(m_amount);
+        matrix.transformColorComponents(colorComponents);
+        return true;
+    }
+    case HUE_ROTATE: {
+        ColorMatrix matrix = ColorMatrix::hueRotateMatrix(m_amount);
+        matrix.transformColorComponents(colorComponents);
+        return true;
+    }
+    case SATURATE: {
+        ColorMatrix matrix = ColorMatrix::saturationMatrix(m_amount);
+        matrix.transformColorComponents(colorComponents);
+        return true;
+    }
+    default:
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    return false;
+}
+
 inline bool BasicColorMatrixFilterOperation::operator==(const FilterOperation& operation) const
 {
     if (!isSameType(operation))
@@ -124,6 +156,38 @@
     return BasicComponentTransferFilterOperation::create(WebCore::blend(fromAmount, m_amount, progress), m_type);
 }
 
+bool BasicComponentTransferFilterOperation::transformColor(FloatComponents& colorComponents) const
+{
+    switch (m_type) {
+    case OPACITY:
+        colorComponents.components[3] *= m_amount;
+        return true;
+    case INVERT: {
+        float oneMinusAmount = 1.f - m_amount;
+        colorComponents.components[0] = 1 - (oneMinusAmount + colorComponents.components[0] * (m_amount - oneMinusAmount));
+        colorComponents.components[1] = 1 - (oneMinusAmount + colorComponents.components[1] * (m_amount - oneMinusAmount));
+        colorComponents.components[2] = 1 - (oneMinusAmount + colorComponents.components[2] * (m_amount - oneMinusAmount));
+        return true;
+    }
+    case CONTRAST: {
+        float intercept = -(0.5f * m_amount) + 0.5f;
+        colorComponents.components[0] = clampTo<float>(intercept + m_amount * colorComponents.components[0], 0, 1);
+        colorComponents.components[1] = clampTo<float>(intercept + m_amount * colorComponents.components[1], 0, 1);
+        colorComponents.components[2] = clampTo<float>(intercept + m_amount * colorComponents.components[2], 0, 1);
+        return true;
+    }
+    case BRIGHTNESS:
+        colorComponents.components[0] = std::max<float>(m_amount * colorComponents.components[0], 0);
+        colorComponents.components[1] = std::max<float>(m_amount * colorComponents.components[1], 0);
+        colorComponents.components[2] = std::max<float>(m_amount * colorComponents.components[2], 0);
+        return true;
+    default:
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+    return false;
+}
+
 inline bool BasicComponentTransferFilterOperation::operator==(const FilterOperation& operation) const
 {
     if (!isSameType(operation))
diff --git a/Source/WebCore/platform/graphics/filters/FilterOperation.h b/Source/WebCore/platform/graphics/filters/FilterOperation.h
index 3a06104..4bd8e27 100644
--- a/Source/WebCore/platform/graphics/filters/FilterOperation.h
+++ b/Source/WebCore/platform/graphics/filters/FilterOperation.h
@@ -23,8 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef FilterOperation_h
-#define FilterOperation_h
+#pragma once
 
 #include "Color.h"
 #include "LayoutSize.h"
@@ -45,6 +44,7 @@
 class CachedResourceLoader;
 class CachedSVGDocumentReference;
 class FilterEffect;
+struct FloatComponents;
 struct ResourceLoaderOptions;
 
 class FilterOperation : public RefCounted<FilterOperation> {
@@ -77,6 +77,8 @@
     {
         return nullptr;
     }
+    
+    virtual bool transformColor(FloatComponents&) const { return false; }
 
     OperationType type() const { return m_type; }
 
@@ -228,6 +230,8 @@
     {
     }
 
+    bool transformColor(FloatComponents&) const override;
+
     double m_amount;
 };
 
@@ -261,6 +265,8 @@
     {
     }
 
+    bool transformColor(FloatComponents&) const override;
+
     double m_amount;
 };
 
@@ -351,4 +357,3 @@
 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(BlurFilterOperation, type() == WebCore::FilterOperation::BLUR)
 SPECIALIZE_TYPE_TRAITS_FILTEROPERATION(DropShadowFilterOperation, type() == WebCore::FilterOperation::DROP_SHADOW)
 
-#endif // FilterOperation_h
diff --git a/Source/WebCore/platform/graphics/filters/FilterOperations.cpp b/Source/WebCore/platform/graphics/filters/FilterOperations.cpp
index d261c7d..6dbeac8 100644
--- a/Source/WebCore/platform/graphics/filters/FilterOperations.cpp
+++ b/Source/WebCore/platform/graphics/filters/FilterOperations.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "FilterOperations.h"
 
+#include "ColorUtilities.h"
 #include "FEGaussianBlur.h"
 #include "IntSize.h"
 #include "LengthFunctions.h"
@@ -119,6 +120,23 @@
     return totalOutsets;
 }
 
+bool FilterOperations::transformColor(Color& color) const
+{
+    if (isEmpty())
+        return false;
+
+    FloatComponents components;
+    color.getRGBA(components.components[0], components.components[1], components.components[2], components.components[3]);
+
+    for (auto& operation : m_operations) {
+        if (!operation->transformColor(components))
+            return false;
+    }
+
+    color = Color(components.components[0], components.components[1], components.components[2], components.components[3]);
+    return true;
+}
+
 bool FilterOperations::hasFilterThatAffectsOpacity() const
 {
     for (auto& operation : m_operations) {
diff --git a/Source/WebCore/platform/graphics/filters/FilterOperations.h b/Source/WebCore/platform/graphics/filters/FilterOperations.h
index 78a41c2..9ab304e 100644
--- a/Source/WebCore/platform/graphics/filters/FilterOperations.h
+++ b/Source/WebCore/platform/graphics/filters/FilterOperations.h
@@ -60,6 +60,8 @@
 
     bool hasReferenceFilter() const;
 
+    bool transformColor(Color&) const;
+
 private:
     Vector<RefPtr<FilterOperation>> m_operations;
 };
diff --git a/Source/WebCore/rendering/BorderEdge.cpp b/Source/WebCore/rendering/BorderEdge.cpp
index f3488a0..1f60c5c 100644
--- a/Source/WebCore/rendering/BorderEdge.cpp
+++ b/Source/WebCore/rendering/BorderEdge.cpp
@@ -50,13 +50,13 @@
 {
     bool horizontal = style.isHorizontalWritingMode();
 
-    edges[BSTop] = BorderEdge(style.borderTopWidth(), style.visitedDependentColor(CSSPropertyBorderTopColor), style.borderTopStyle(), style.borderTopIsTransparent(),
+    edges[BSTop] = BorderEdge(style.borderTopWidth(), style.visitedDependentColorWithColorFilter(CSSPropertyBorderTopColor), style.borderTopStyle(), style.borderTopIsTransparent(),
         horizontal || includeLogicalLeftEdge, deviceScaleFactor);
-    edges[BSRight] = BorderEdge(style.borderRightWidth(), style.visitedDependentColor(CSSPropertyBorderRightColor), style.borderRightStyle(), style.borderRightIsTransparent(),
+    edges[BSRight] = BorderEdge(style.borderRightWidth(), style.visitedDependentColorWithColorFilter(CSSPropertyBorderRightColor), style.borderRightStyle(), style.borderRightIsTransparent(),
         !horizontal || includeLogicalRightEdge, deviceScaleFactor);
-    edges[BSBottom] = BorderEdge(style.borderBottomWidth(), style.visitedDependentColor(CSSPropertyBorderBottomColor), style.borderBottomStyle(), style.borderBottomIsTransparent(),
+    edges[BSBottom] = BorderEdge(style.borderBottomWidth(), style.visitedDependentColorWithColorFilter(CSSPropertyBorderBottomColor), style.borderBottomStyle(), style.borderBottomIsTransparent(),
         horizontal || includeLogicalRightEdge, deviceScaleFactor);
-    edges[BSLeft] = BorderEdge(style.borderLeftWidth(), style.visitedDependentColor(CSSPropertyBorderLeftColor), style.borderLeftStyle(), style.borderLeftIsTransparent(),
+    edges[BSLeft] = BorderEdge(style.borderLeftWidth(), style.visitedDependentColorWithColorFilter(CSSPropertyBorderLeftColor), style.borderLeftStyle(), style.borderLeftIsTransparent(),
         !horizontal || includeLogicalLeftEdge, deviceScaleFactor);
     }
 
diff --git a/Source/WebCore/rendering/EllipsisBox.cpp b/Source/WebCore/rendering/EllipsisBox.cpp
index 3c11db1..9524479 100644
--- a/Source/WebCore/rendering/EllipsisBox.cpp
+++ b/Source/WebCore/rendering/EllipsisBox.cpp
@@ -50,13 +50,13 @@
 {
     GraphicsContext& context = paintInfo.context();
     const RenderStyle& lineStyle = this->lineStyle();
-    Color textColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextFillColor);
+    Color textColor = lineStyle.visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor);
     if (textColor != context.fillColor())
         context.setFillColor(textColor);
     bool setShadow = false;
     if (lineStyle.textShadow()) {
-        context.setShadow(LayoutSize(lineStyle.textShadow()->x(), lineStyle.textShadow()->y()),
-            lineStyle.textShadow()->radius(), lineStyle.textShadow()->color());
+        Color shadowColor = lineStyle.colorByApplyingColorFilter(lineStyle.textShadow()->color());
+        context.setShadow(LayoutSize(lineStyle.textShadow()->x(), lineStyle.textShadow()->y()), lineStyle.textShadow()->radius(), shadowColor);
         setShadow = true;
     }
 
@@ -127,7 +127,7 @@
 
 void EllipsisBox::paintSelection(GraphicsContext& context, const LayoutPoint& paintOffset, const RenderStyle& style, const FontCascade& font)
 {
-    Color textColor = style.visitedDependentColor(CSSPropertyColor);
+    Color textColor = style.visitedDependentColorWithColorFilter(CSSPropertyColor);
     Color c = blockFlow().selectionBackgroundColor();
     if (!c.isVisible())
         return;
diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp
index 063f3b6..5f6d66d 100644
--- a/Source/WebCore/rendering/InlineFlowBox.cpp
+++ b/Source/WebCore/rendering/InlineFlowBox.cpp
@@ -1360,7 +1360,7 @@
     if (!renderer().boxShadowShouldBeAppliedToBackground(adjustedPaintoffset, BackgroundBleedNone, this))
         paintBoxShadow(paintInfo, lineStyle, Normal, paintRect);
 
-    const Color& color = lineStyle.visitedDependentColor(CSSPropertyBackgroundColor);
+    const Color& color = lineStyle.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     paintFillLayers(paintInfo, color, lineStyle.backgroundLayers(), paintRect);
     paintBoxShadow(paintInfo, lineStyle, Inset, paintRect);
 
diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp
index 9ee2515..0a73973 100644
--- a/Source/WebCore/rendering/InlineTextBox.cpp
+++ b/Source/WebCore/rendering/InlineTextBox.cpp
@@ -1011,8 +1011,10 @@
     textPainter.setFont(font);
     textPainter.setStyle(markedText.style.textStyles);
     textPainter.setIsHorizontal(isHorizontal());
-    if (markedText.style.textShadow)
+    if (markedText.style.textShadow) {
+        // FIXME: need to transform shadow color here.
         textPainter.setShadow(&markedText.style.textShadow.value());
+    }
     textPainter.setEmphasisMark(emphasisMark, emphasisMarkOffset, combinedText());
 
     TextRun textRun = createTextRun();
@@ -1064,8 +1066,10 @@
     decorationPainter.setWidth(snappedSelectionRect.width());
     decorationPainter.setBaseline(lineStyle().fontMetrics().ascent());
     decorationPainter.setIsHorizontal(isHorizontal());
-    if (markedText.style.textShadow)
+    if (markedText.style.textShadow) {
+        // FIXME: transform shadow color.
         decorationPainter.addTextShadow(&markedText.style.textShadow.value());
+    }
 
     {
         GraphicsContextStateSaver stateSaver { context, false };
@@ -1158,7 +1162,7 @@
     width -= 2;
 
     GraphicsContext& context = paintInfo.context();
-    context.setStrokeColor(underline.compositionUnderlineColor == CompositionUnderlineColor::TextColor ? renderer().style().visitedDependentColor(CSSPropertyWebkitTextFillColor) : underline.color);
+    context.setStrokeColor(underline.compositionUnderlineColor == CompositionUnderlineColor::TextColor ? renderer().style().visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor) : underline.color);
     context.setStrokeThickness(lineThickness);
     context.drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, renderer().document().printing());
 }
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index ba5b258..dcb65f7 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -1195,7 +1195,7 @@
         return;
 
     auto& style = rootBackgroundRenderer->style();
-    auto color = style.visitedDependentColor(CSSPropertyBackgroundColor);
+    auto color = style.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     paintFillLayers(paintInfo, color, style.backgroundLayers(), view().backgroundRect(), BackgroundBleedNone, CompositeSourceOver, rootBackgroundRenderer);
 }
 
@@ -1324,7 +1324,7 @@
     if (backgroundIsKnownToBeObscured(paintRect.location()) && !boxShadowShouldBeAppliedToBackground(paintRect.location(), bleedAvoidance))
         return;
 
-    paintFillLayers(paintInfo, style().visitedDependentColor(CSSPropertyBackgroundColor), style().backgroundLayers(), paintRect, bleedAvoidance);
+    paintFillLayers(paintInfo, style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor), style().backgroundLayers(), paintRect, bleedAvoidance);
 }
 
 bool RenderBox::getBackgroundPaintedExtent(const LayoutPoint& paintOffset, LayoutRect& paintedExtent) const
@@ -1332,7 +1332,7 @@
     ASSERT(hasBackground());
     LayoutRect backgroundRect = snappedIntRect(borderBoxRect());
 
-    Color backgroundColor = style().visitedDependentColor(CSSPropertyBackgroundColor);
+    Color backgroundColor = style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     if (backgroundColor.isVisible()) {
         paintedExtent = backgroundRect;
         return true;
@@ -1354,7 +1354,7 @@
     if (!paintsOwnBackground())
         return false;
 
-    Color backgroundColor = style().visitedDependentColor(CSSPropertyBackgroundColor);
+    Color backgroundColor = style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     if (!backgroundColor.isOpaque())
         return false;
 
@@ -1482,7 +1482,7 @@
 
     // If there is only one layer and no image, check whether the background color is opaque.
     if (!fillLayer.next() && !fillLayer.hasImage()) {
-        Color bgColor = style().visitedDependentColor(CSSPropertyBackgroundColor);
+        Color bgColor = style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
         if (bgColor.isOpaque())
             return true;
     }
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index 014cd10..e00e624 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -703,17 +703,17 @@
     return getBackgroundRoundedRect(borderRect, box, boxSize.width(), boxSize.height(), includeLogicalLeftEdge, includeLogicalRightEdge);
 }
 
-static void applyBoxShadowForBackground(GraphicsContext& context, const RenderStyle* style)
+static void applyBoxShadowForBackground(GraphicsContext& context, const RenderStyle& style)
 {
-    const ShadowData* boxShadow = style->boxShadow();
+    const ShadowData* boxShadow = style.boxShadow();
     while (boxShadow->style() != Normal)
         boxShadow = boxShadow->next();
 
     FloatSize shadowOffset(boxShadow->x(), boxShadow->y());
     if (!boxShadow->isWebkitBoxShadow())
-        context.setShadow(shadowOffset, boxShadow->radius(), boxShadow->color());
+        context.setShadow(shadowOffset, boxShadow->radius(), style.colorByApplyingColorFilter(boxShadow->color()));
     else
-        context.setLegacyShadow(shadowOffset, boxShadow->radius(), boxShadow->color());
+        context.setLegacyShadow(shadowOffset, boxShadow->radius(), style.colorByApplyingColorFilter(boxShadow->color()));
 }
 
 InterpolationQuality RenderBoxModelObject::chooseInterpolationQuality(GraphicsContext& context, Image& image, const void* layer, const LayoutSize& size)
@@ -797,7 +797,7 @@
         bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(rect.location(), bleedAvoidance, box);
         GraphicsContextStateSaver shadowStateSaver(context, boxShadowShouldBeAppliedToBackground);
         if (boxShadowShouldBeAppliedToBackground)
-            applyBoxShadowForBackground(context, &style());
+            applyBoxShadowForBackground(context, style());
 
         if (hasRoundedBorder && bleedAvoidance != BackgroundBleedUseTransparencyLayer) {
             FloatRoundedRect pixelSnappedBorder = backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box, boxSize,
@@ -932,7 +932,7 @@
 
             GraphicsContextStateSaver shadowStateSaver(context, boxShadowShouldBeAppliedToBackground);
             if (boxShadowShouldBeAppliedToBackground)
-                applyBoxShadowForBackground(context, &style());
+                applyBoxShadowForBackground(context, style());
 
             FloatRect backgroundRectForPainting = snapRectToDevicePixels(backgroundRect, deviceScaleFactor);
             if (baseColor.isVisible()) {
@@ -2297,7 +2297,7 @@
     if (!hasOneNormalBoxShadow)
         return false;
 
-    Color backgroundColor = style().visitedDependentColor(CSSPropertyBackgroundColor);
+    Color backgroundColor = style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     if (!backgroundColor.isOpaque())
         return false;
 
@@ -2348,7 +2348,7 @@
     bool isHorizontal = style.isHorizontalWritingMode();
     float deviceScaleFactor = document().deviceScaleFactor();
 
-    bool hasOpaqueBackground = style.visitedDependentColor(CSSPropertyBackgroundColor).isOpaque();
+    bool hasOpaqueBackground = style.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor).isOpaque();
     for (const ShadowData* shadow = style.boxShadow(); shadow; shadow = shadow->next()) {
         if (shadow->style() != shadowStyle)
             continue;
@@ -2363,7 +2363,7 @@
         if (shadowOffset.isZero() && !shadowRadius && !shadowSpread)
             continue;
         
-        const Color& shadowColor = shadow->color();
+        Color shadowColor = style.colorByApplyingColorFilter(shadow->color());
 
         if (shadow->style() == Normal) {
             RoundedRect fillRect = border;
diff --git a/Source/WebCore/rendering/RenderDetailsMarker.cpp b/Source/WebCore/rendering/RenderDetailsMarker.cpp
index 260bbb6..5ac4fc9 100644
--- a/Source/WebCore/rendering/RenderDetailsMarker.cpp
+++ b/Source/WebCore/rendering/RenderDetailsMarker.cpp
@@ -130,7 +130,7 @@
     if (!paintInfo.rect.intersects(snappedIntRect(overflowRect)))
         return;
 
-    const Color color(style().visitedDependentColor(CSSPropertyColor));
+    const Color color(style().visitedDependentColorWithColorFilter(CSSPropertyColor));
     paintInfo.context().setStrokeColor(color);
     paintInfo.context().setStrokeStyle(SolidStroke);
     paintInfo.context().setStrokeThickness(1.0f);
diff --git a/Source/WebCore/rendering/RenderElement.cpp b/Source/WebCore/rendering/RenderElement.cpp
index cf5ebbb..38d3325 100644
--- a/Source/WebCore/rendering/RenderElement.cpp
+++ b/Source/WebCore/rendering/RenderElement.cpp
@@ -1365,9 +1365,9 @@
         return Color();
 
     if (std::unique_ptr<RenderStyle> pseudoStyle = selectionPseudoStyle()) {
-        Color color = pseudoStyle->visitedDependentColor(colorProperty);
+        Color color = pseudoStyle->visitedDependentColorWithColorFilter(colorProperty);
         if (!color.isValid())
-            color = pseudoStyle->visitedDependentColor(CSSPropertyColor);
+            color = pseudoStyle->visitedDependentColorWithColorFilter(CSSPropertyColor);
         return color;
     }
 
@@ -1407,11 +1407,11 @@
         return Color();
 
     if (frame().selection().shouldShowBlockCursor() && frame().selection().isCaret())
-        return style().visitedDependentColor(CSSPropertyColor).blendWithWhite();
+        return style().visitedDependentColorWithColorFilter(CSSPropertyColor).blendWithWhite();
 
     std::unique_ptr<RenderStyle> pseudoStyle = selectionPseudoStyle();
-    if (pseudoStyle && pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
-        return pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).blendWithWhite();
+    if (pseudoStyle && pseudoStyle->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor).isValid())
+        return pseudoStyle->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor).blendWithWhite();
 
     if (frame().selection().isFocusedAndActive())
         return theme().activeSelectionBackgroundColor();
@@ -1842,7 +1842,7 @@
     if (needsRepaint)
         page().focusController().setFocusedElementNeedsRepaint();
 #else
-    paintInfo.context().drawFocusRing(pixelSnappedFocusRingRects, style.outlineWidth(), style.outlineOffset(), style.visitedDependentColor(CSSPropertyOutlineColor));
+    paintInfo.context().drawFocusRing(pixelSnappedFocusRingRects, style.outlineWidth(), style.outlineOffset(), style.visitedDependentColorWithColorFilter(CSSPropertyOutlineColor));
 #endif
 }
 
@@ -1882,7 +1882,7 @@
         return;
 
     EBorderStyle outlineStyle = styleToUse.outlineStyle();
-    Color outlineColor = styleToUse.visitedDependentColor(CSSPropertyOutlineColor);
+    Color outlineColor = styleToUse.visitedDependentColorWithColorFilter(CSSPropertyOutlineColor);
 
     bool useTransparencyLayer = !outlineColor.isOpaque();
     if (useTransparencyLayer) {
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.cpp b/Source/WebCore/rendering/RenderFileUploadControl.cpp
index d0532bd..c4c764c 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/Source/WebCore/rendering/RenderFileUploadControl.cpp
@@ -160,7 +160,7 @@
         else
             textY = baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
 
-        paintInfo.context().setFillColor(style().visitedDependentColor(CSSPropertyColor));
+        paintInfo.context().setFillColor(style().visitedDependentColorWithColorFilter(CSSPropertyColor));
         
         // Draw the filename
         paintInfo.context().drawBidiText(font, textRun, IntPoint(roundToInt(textX), roundToInt(textY)));
diff --git a/Source/WebCore/rendering/RenderFrameSet.cpp b/Source/WebCore/rendering/RenderFrameSet.cpp
index 26078f6..0da8c83 100644
--- a/Source/WebCore/rendering/RenderFrameSet.cpp
+++ b/Source/WebCore/rendering/RenderFrameSet.cpp
@@ -95,7 +95,7 @@
     
     // Fill first.
     GraphicsContext& context = paintInfo.context();
-    context.fillRect(borderRect, frameSetElement().hasBorderColor() ? style().visitedDependentColor(CSSPropertyBorderLeftColor) : borderFillColor());
+    context.fillRect(borderRect, frameSetElement().hasBorderColor() ? style().visitedDependentColorWithColorFilter(CSSPropertyBorderLeftColor) : borderFillColor());
     
     // Now stroke the edges but only if we have enough room to paint both edges with a little
     // bit of the fill color showing through.
@@ -114,7 +114,7 @@
     
     // Fill first.
     GraphicsContext& context = paintInfo.context();
-    context.fillRect(borderRect, frameSetElement().hasBorderColor() ? style().visitedDependentColor(CSSPropertyBorderLeftColor) : borderFillColor());
+    context.fillRect(borderRect, frameSetElement().hasBorderColor() ? style().visitedDependentColorWithColorFilter(CSSPropertyBorderLeftColor) : borderFillColor());
 
     // Now stroke the edges but only if we have enough room to paint both edges with a little
     // bit of the fill color showing through.
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index 984681f..be5cab9 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -439,7 +439,7 @@
 
             if (!m_altText.isEmpty()) {
                 String text = document().displayStringModifiedByEncoding(m_altText);
-                context.setFillColor(style().visitedDependentColor(CSSPropertyColor));
+                context.setFillColor(style().visitedDependentColorWithColorFilter(CSSPropertyColor));
                 const FontCascade& font = style().fontCascade();
                 const FontMetrics& fontMetrics = font.fontMetrics();
                 LayoutUnit ascent = fontMetrics.ascent();
@@ -548,7 +548,7 @@
     if (needsRepaint)
         page().focusController().setFocusedElementNeedsRepaint();
 #else
-    paintInfo.context().drawFocusRing(path, outlineWidth, areaElementStyle->outlineOffset(), areaElementStyle->visitedDependentColor(CSSPropertyOutlineColor));
+    paintInfo.context().drawFocusRing(path, outlineWidth, areaElementStyle->outlineOffset(), areaElementStyle->visitedDependentColorWithColorFilter(CSSPropertyOutlineColor));
 #endif
 #endif
 }
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index 9aea5c0..fcbeb88 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -1230,7 +1230,7 @@
     }
     rects.append(LayoutRect());
 
-    Color outlineColor = styleToUse.visitedDependentColor(CSSPropertyOutlineColor);
+    Color outlineColor = styleToUse.visitedDependentColorWithColorFilter(CSSPropertyOutlineColor);
     bool useTransparencyLayer = !outlineColor.isOpaque();
     if (useTransparencyLayer) {
         graphicsContext.beginTransparencyLayer(outlineColor.alphaAsFloat());
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index 2d8d09f..160a531 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -1845,7 +1845,7 @@
 
     // FIXME: Allow color+image compositing when it makes sense.
     // For now bailing out.
-    if (style.visitedDependentColor(CSSPropertyBackgroundColor).isVisible())
+    if (style.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor).isVisible())
         return false;
 
     // FIXME: support gradients with isGeneratedImage.
@@ -1885,7 +1885,7 @@
     if (!backgroundRenderer)
         backgroundRenderer = &renderer();
 
-    return backgroundRenderer->style().visitedDependentColor(CSSPropertyBackgroundColor);
+    return backgroundRenderer->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
 }
 
 void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 1c4047d..0e90888 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -3101,9 +3101,9 @@
 
     Color oldBackgroundColor;
     if (oldStyle)
-        oldBackgroundColor = oldStyle->visitedDependentColor(CSSPropertyBackgroundColor);
+        oldBackgroundColor = oldStyle->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
 
-    if (oldBackgroundColor != renderer.style().visitedDependentColor(CSSPropertyBackgroundColor))
+    if (oldBackgroundColor != renderer.style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor))
         rootBackgroundTransparencyChanged();
 
     bool hadFixedBackground = oldStyle && oldStyle->hasEntirelyFixedBackground();
diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp
index a63fbe7..fd1daf8 100644
--- a/Source/WebCore/rendering/RenderListBox.cpp
+++ b/Source/WebCore/rendering/RenderListBox.cpp
@@ -422,7 +422,7 @@
         itemText = downcast<HTMLOptGroupElement>(*listItemElement).groupLabelText();
     itemText = applyTextTransform(style(), itemText, ' ');
 
-    Color textColor = itemStyle.visitedDependentColor(CSSPropertyColor);
+    Color textColor = itemStyle.visitedDependentColorWithColorFilter(CSSPropertyColor);
     if (isOptionElement && downcast<HTMLOptionElement>(*listItemElement).selected()) {
         if (frame().selection().isFocusedAndActive() && document().focusedElement() == &selectElement())
             textColor = theme().activeListBoxSelectionForegroundColor();
@@ -462,7 +462,7 @@
         else
             backColor = theme().inactiveListBoxSelectionBackgroundColor(document().useSystemAppearance());
     } else
-        backColor = itemStyle.visitedDependentColor(CSSPropertyBackgroundColor);
+        backColor = itemStyle.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
 
     // Draw the background for this list box item
     if (itemStyle.visibility() == HIDDEN)
diff --git a/Source/WebCore/rendering/RenderListMarker.cpp b/Source/WebCore/rendering/RenderListMarker.cpp
index 904f994..6496978 100644
--- a/Source/WebCore/rendering/RenderListMarker.cpp
+++ b/Source/WebCore/rendering/RenderListMarker.cpp
@@ -1221,7 +1221,7 @@
         context.fillRect(snappedIntRect(selRect), m_listItem.selectionBackgroundColor());
     }
 
-    const Color color(style().visitedDependentColor(CSSPropertyColor));
+    const Color color(style().visitedDependentColorWithColorFilter(CSSPropertyColor));
     context.setStrokeColor(color);
     context.setStrokeStyle(SolidStroke);
     context.setStrokeThickness(1.0f);
diff --git a/Source/WebCore/rendering/RenderMenuList.cpp b/Source/WebCore/rendering/RenderMenuList.cpp
index d8895b9..5e3c30a 100644
--- a/Source/WebCore/rendering/RenderMenuList.cpp
+++ b/Source/WebCore/rendering/RenderMenuList.cpp
@@ -507,7 +507,7 @@
     getItemBackgroundColor(listIndex, itemBackgroundColor, itemHasCustomBackgroundColor);
 
     auto& style = *element->computedStyle();
-    return PopupMenuStyle(style.visitedDependentColor(CSSPropertyColor), itemBackgroundColor, style.fontCascade(), style.visibility() == VISIBLE,
+    return PopupMenuStyle(style.visitedDependentColorWithColorFilter(CSSPropertyColor), itemBackgroundColor, style.fontCascade(), style.visibility() == VISIBLE,
         style.display() == NONE, true, style.textIndent(), style.direction(), isOverride(style.unicodeBidi()),
         itemHasCustomBackgroundColor ? PopupMenuStyle::CustomBackgroundColor : PopupMenuStyle::DefaultBackgroundColor);
 }
@@ -516,13 +516,13 @@
 {
     const Vector<HTMLElement*>& listItems = selectElement().listItems();
     if (listIndex >= listItems.size()) {
-        itemBackgroundColor = style().visitedDependentColor(CSSPropertyBackgroundColor);
+        itemBackgroundColor = style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
         itemHasCustomBackgroundColor = false;
         return;
     }
     HTMLElement* element = listItems[listIndex];
 
-    Color backgroundColor = element->computedStyle()->visitedDependentColor(CSSPropertyBackgroundColor);
+    Color backgroundColor = element->computedStyle()->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     itemHasCustomBackgroundColor = backgroundColor.isValid() && backgroundColor.isVisible();
     // If the item has an opaque background color, return that.
     if (backgroundColor.isOpaque()) {
@@ -531,7 +531,7 @@
     }
 
     // Otherwise, the item's background is overlayed on top of the menu background.
-    backgroundColor = style().visitedDependentColor(CSSPropertyBackgroundColor).blend(backgroundColor);
+    backgroundColor = style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor).blend(backgroundColor);
     if (backgroundColor.isOpaque()) {
         itemBackgroundColor = backgroundColor;
         return;
@@ -545,7 +545,7 @@
 {
     const RenderStyle& styleToUse = m_innerBlock ? m_innerBlock->style() : style();
     IntRect absBounds = absoluteBoundingBoxRectIgnoringTransforms();
-    return PopupMenuStyle(styleToUse.visitedDependentColor(CSSPropertyColor), styleToUse.visitedDependentColor(CSSPropertyBackgroundColor),
+    return PopupMenuStyle(styleToUse.visitedDependentColorWithColorFilter(CSSPropertyColor), styleToUse.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor),
         styleToUse.fontCascade(), styleToUse.visibility() == VISIBLE, styleToUse.display() == NONE,
         style().hasAppearance() && style().appearance() == MenulistPart, styleToUse.textIndent(),
         style().direction(), isOverride(style().unicodeBidi()), PopupMenuStyle::DefaultBackgroundColor,
diff --git a/Source/WebCore/rendering/RenderMultiColumnSet.cpp b/Source/WebCore/rendering/RenderMultiColumnSet.cpp
index 41c1c08..5f7a566 100644
--- a/Source/WebCore/rendering/RenderMultiColumnSet.cpp
+++ b/Source/WebCore/rendering/RenderMultiColumnSet.cpp
@@ -581,7 +581,7 @@
 
     RenderMultiColumnFlow* fragmentedFlow = multiColumnFlow();
     const RenderStyle& blockStyle = parent()->style();
-    const Color& ruleColor = blockStyle.visitedDependentColor(CSSPropertyColumnRuleColor);
+    const Color& ruleColor = blockStyle.visitedDependentColorWithColorFilter(CSSPropertyColumnRuleColor);
     bool ruleTransparent = blockStyle.columnRuleIsTransparent();
     EBorderStyle ruleStyle = collapsedBorderStyle(blockStyle.columnRuleStyle());
     LayoutUnit ruleThickness = blockStyle.columnRuleWidth();
diff --git a/Source/WebCore/rendering/RenderSearchField.cpp b/Source/WebCore/rendering/RenderSearchField.cpp
index 88fd64a..f2a817a 100644
--- a/Source/WebCore/rendering/RenderSearchField.cpp
+++ b/Source/WebCore/rendering/RenderSearchField.cpp
@@ -270,7 +270,7 @@
 
 PopupMenuStyle RenderSearchField::menuStyle() const
 {
-    return PopupMenuStyle(style().visitedDependentColor(CSSPropertyColor), style().visitedDependentColor(CSSPropertyBackgroundColor), style().fontCascade(), style().visibility() == VISIBLE,
+    return PopupMenuStyle(style().visitedDependentColorWithColorFilter(CSSPropertyColor), style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor), style().fontCascade(), style().visibility() == VISIBLE,
         style().display() == NONE, true, style().textIndent(), style().direction(), isOverride(style().unicodeBidi()), PopupMenuStyle::CustomBackgroundColor);
 }
 
diff --git a/Source/WebCore/rendering/RenderTable.h b/Source/WebCore/rendering/RenderTable.h
index 1d1d3d2..f720557 100644
--- a/Source/WebCore/rendering/RenderTable.h
+++ b/Source/WebCore/rendering/RenderTable.h
@@ -88,7 +88,7 @@
         return style().isLeftToRightDirection() ? borderEnd() : borderStart();
     }
 
-    Color bgColor() const { return style().visitedDependentColor(CSSPropertyBackgroundColor); }
+    Color bgColor() const { return style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor); }
 
     LayoutUnit outerBorderBefore() const;
     LayoutUnit outerBorderAfter() const;
diff --git a/Source/WebCore/rendering/RenderTableCell.cpp b/Source/WebCore/rendering/RenderTableCell.cpp
index 218b4d1..e095ec5 100644
--- a/Source/WebCore/rendering/RenderTableCell.cpp
+++ b/Source/WebCore/rendering/RenderTableCell.cpp
@@ -560,7 +560,7 @@
     // (1) Our start border.
     CSSPropertyID startColorProperty = includeColor ? CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderStartColor, styleForCellFlow().direction(), styleForCellFlow().writingMode()) : CSSPropertyInvalid;
     CSSPropertyID endColorProperty = includeColor ? CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderEndColor, styleForCellFlow().direction(), styleForCellFlow().writingMode()) : CSSPropertyInvalid;
-    CollapsedBorderValue result(style().borderStart(), includeColor ? style().visitedDependentColor(startColorProperty) : Color(), BCELL);
+    CollapsedBorderValue result(style().borderStart(), includeColor ? style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BCELL);
 
     RenderTable* table = this->table();
     if (!table)
@@ -568,7 +568,7 @@
     // (2) The end border of the preceding cell.
     RenderTableCell* cellBefore = table->cellBefore(this);
     if (cellBefore) {
-        CollapsedBorderValue cellBeforeAdjoiningBorder = CollapsedBorderValue(cellBefore->borderAdjoiningCellAfter(*this), includeColor ? cellBefore->style().visitedDependentColor(endColorProperty) : Color(), BCELL);
+        CollapsedBorderValue cellBeforeAdjoiningBorder = CollapsedBorderValue(cellBefore->borderAdjoiningCellAfter(*this), includeColor ? cellBefore->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BCELL);
         // |result| should be the 2nd argument as |cellBefore| should win in case of equality per CSS 2.1 (Border conflict resolution, point 4).
         result = chooseBorder(cellBeforeAdjoiningBorder, result);
         if (!result.exists())
@@ -578,12 +578,12 @@
     bool startBorderAdjoinsTable = hasStartBorderAdjoiningTable();
     if (startBorderAdjoinsTable) {
         // (3) Our row's start border.
-        result = chooseBorder(result, CollapsedBorderValue(row()->borderAdjoiningStartCell(*this), includeColor ? parent()->style().visitedDependentColor(startColorProperty) : Color(), BROW));
+        result = chooseBorder(result, CollapsedBorderValue(row()->borderAdjoiningStartCell(*this), includeColor ? parent()->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BROW));
         if (!result.exists())
             return result;
 
         // (4) Our row group's start border.
-        result = chooseBorder(result, CollapsedBorderValue(section()->borderAdjoiningStartCell(*this), includeColor ? section()->style().visitedDependentColor(startColorProperty) : Color(), BROWGROUP));
+        result = chooseBorder(result, CollapsedBorderValue(section()->borderAdjoiningStartCell(*this), includeColor ? section()->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BROWGROUP));
         if (!result.exists())
             return result;
     }
@@ -594,19 +594,19 @@
     if (RenderTableCol* colElt = table->colElement(col(), &startColEdge, &endColEdge)) {
         if (colElt->isTableColumnGroup() && startColEdge) {
             // The |colElt| is a column group and is also the first colgroup (in case of spanned colgroups).
-            result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellStartBorder(), includeColor ? colElt->style().visitedDependentColor(startColorProperty) : Color(), BCOLGROUP));
+            result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellStartBorder(), includeColor ? colElt->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BCOLGROUP));
             if (!result.exists())
                 return result;
         } else if (!colElt->isTableColumnGroup()) {
             // We first consider the |colElt| and irrespective of whether it is a spanned col or not, we apply
             // its start border. This is as per HTML5 which states that: "For the purposes of the CSS table model,
             // the col element is expected to be treated as if it was present as many times as its span attribute specifies".
-            result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellStartBorder(), includeColor ? colElt->style().visitedDependentColor(startColorProperty) : Color(), BCOL));
+            result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellStartBorder(), includeColor ? colElt->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BCOL));
             if (!result.exists())
                 return result;
             // Next, apply the start border of the enclosing colgroup but only if it is adjacent to the cell's edge.
             if (RenderTableCol* enclosingColumnGroup = colElt->enclosingColumnGroupIfAdjacentBefore()) {
-                result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->borderAdjoiningCellStartBorder(), includeColor ? enclosingColumnGroup->style().visitedDependentColor(startColorProperty) : Color(), BCOLGROUP));
+                result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->borderAdjoiningCellStartBorder(), includeColor ? enclosingColumnGroup->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BCOLGROUP));
                 if (!result.exists())
                     return result;
             }
@@ -618,18 +618,18 @@
         if (RenderTableCol* colElt = table->colElement(col() - 1, &startColEdge, &endColEdge)) {
             if (colElt->isTableColumnGroup() && endColEdge) {
                 // The element is a colgroup and is also the last colgroup (in case of spanned colgroups).
-                result = chooseBorder(CollapsedBorderValue(colElt->borderAdjoiningCellAfter(*this), includeColor ? colElt->style().visitedDependentColor(endColorProperty) : Color(), BCOLGROUP), result);
+                result = chooseBorder(CollapsedBorderValue(colElt->borderAdjoiningCellAfter(*this), includeColor ? colElt->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BCOLGROUP), result);
                 if (!result.exists())
                     return result;
             } else if (colElt->isTableColumn()) {
                 // Resolve the collapsing border against the col's border ignoring any 'span' as per HTML5.
-                result = chooseBorder(CollapsedBorderValue(colElt->borderAdjoiningCellAfter(*this), includeColor ? colElt->style().visitedDependentColor(endColorProperty) : Color(), BCOL), result);
+                result = chooseBorder(CollapsedBorderValue(colElt->borderAdjoiningCellAfter(*this), includeColor ? colElt->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BCOL), result);
                 if (!result.exists())
                     return result;
                 // Next, if the previous col has a parent colgroup then its end border should be applied
                 // but only if it is adjacent to the cell's edge.
                 if (RenderTableCol* enclosingColumnGroup = colElt->enclosingColumnGroupIfAdjacentAfter()) {
-                    result = chooseBorder(CollapsedBorderValue(enclosingColumnGroup->borderAdjoiningCellEndBorder(), includeColor ? enclosingColumnGroup->style().visitedDependentColor(endColorProperty) : Color(), BCOLGROUP), result);
+                    result = chooseBorder(CollapsedBorderValue(enclosingColumnGroup->borderAdjoiningCellEndBorder(), includeColor ? enclosingColumnGroup->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BCOLGROUP), result);
                     if (!result.exists())
                         return result;
                 }
@@ -639,7 +639,7 @@
 
     if (startBorderAdjoinsTable) {
         // (7) The table's start border.
-        result = chooseBorder(result, CollapsedBorderValue(table->tableStartBorderAdjoiningCell(*this), includeColor ? table->style().visitedDependentColor(startColorProperty) : Color(), BTABLE));
+        result = chooseBorder(result, CollapsedBorderValue(table->tableStartBorderAdjoiningCell(*this), includeColor ? table->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BTABLE));
         if (!result.exists())
             return result;
     }
@@ -671,7 +671,7 @@
     // (1) Our end border.
     CSSPropertyID startColorProperty = includeColor ? CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderStartColor, styleForCellFlow().direction(), styleForCellFlow().writingMode()) : CSSPropertyInvalid;
     CSSPropertyID endColorProperty = includeColor ? CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderEndColor, styleForCellFlow().direction(), styleForCellFlow().writingMode()) : CSSPropertyInvalid;
-    CollapsedBorderValue result = CollapsedBorderValue(style().borderEnd(), includeColor ? style().visitedDependentColor(endColorProperty) : Color(), BCELL);
+    CollapsedBorderValue result = CollapsedBorderValue(style().borderEnd(), includeColor ? style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BCELL);
 
     RenderTable* table = this->table();
     if (!table)
@@ -682,7 +682,7 @@
     // (2) The start border of the following cell.
     if (!isEndColumn) {
         if (RenderTableCell* cellAfter = table->cellAfter(this)) {
-            CollapsedBorderValue cellAfterAdjoiningBorder = CollapsedBorderValue(cellAfter->borderAdjoiningCellBefore(*this), includeColor ? cellAfter->style().visitedDependentColor(startColorProperty) : Color(), BCELL);
+            CollapsedBorderValue cellAfterAdjoiningBorder = CollapsedBorderValue(cellAfter->borderAdjoiningCellBefore(*this), includeColor ? cellAfter->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BCELL);
             result = chooseBorder(result, cellAfterAdjoiningBorder);
             if (!result.exists())
                 return result;
@@ -692,12 +692,12 @@
     bool endBorderAdjoinsTable = hasEndBorderAdjoiningTable();
     if (endBorderAdjoinsTable) {
         // (3) Our row's end border.
-        result = chooseBorder(result, CollapsedBorderValue(row()->borderAdjoiningEndCell(*this), includeColor ? parent()->style().visitedDependentColor(endColorProperty) : Color(), BROW));
+        result = chooseBorder(result, CollapsedBorderValue(row()->borderAdjoiningEndCell(*this), includeColor ? parent()->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BROW));
         if (!result.exists())
             return result;
         
         // (4) Our row group's end border.
-        result = chooseBorder(result, CollapsedBorderValue(section()->borderAdjoiningEndCell(*this), includeColor ? section()->style().visitedDependentColor(endColorProperty) : Color(), BROWGROUP));
+        result = chooseBorder(result, CollapsedBorderValue(section()->borderAdjoiningEndCell(*this), includeColor ? section()->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BROWGROUP));
         if (!result.exists())
             return result;
     }
@@ -708,19 +708,19 @@
     if (RenderTableCol* colElt = table->colElement(col() + colSpan() - 1, &startColEdge, &endColEdge)) {
         if (colElt->isTableColumnGroup() && endColEdge) {
             // The element is a colgroup and is also the last colgroup (in case of spanned colgroups).
-            result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellEndBorder(), includeColor ? colElt->style().visitedDependentColor(endColorProperty) : Color(), BCOLGROUP));
+            result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellEndBorder(), includeColor ? colElt->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BCOLGROUP));
             if (!result.exists())
                 return result;
         } else if (!colElt->isTableColumnGroup()) {
             // First apply the end border of the column irrespective of whether it is spanned or not. This is as per
             // HTML5 which states that: "For the purposes of the CSS table model, the col element is expected to be
             // treated as if it was present as many times as its span attribute specifies".
-            result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellEndBorder(), includeColor ? colElt->style().visitedDependentColor(endColorProperty) : Color(), BCOL));
+            result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellEndBorder(), includeColor ? colElt->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BCOL));
             if (!result.exists())
                 return result;
             // Next, if it has a parent colgroup then we apply its end border but only if it is adjacent to the cell.
             if (RenderTableCol* enclosingColumnGroup = colElt->enclosingColumnGroupIfAdjacentAfter()) {
-                result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->borderAdjoiningCellEndBorder(), includeColor ? enclosingColumnGroup->style().visitedDependentColor(endColorProperty) : Color(), BCOLGROUP));
+                result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->borderAdjoiningCellEndBorder(), includeColor ? enclosingColumnGroup->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BCOLGROUP));
                 if (!result.exists())
                     return result;
             }
@@ -732,17 +732,17 @@
         if (RenderTableCol* colElt = table->colElement(col() + colSpan(), &startColEdge, &endColEdge)) {
             if (colElt->isTableColumnGroup() && startColEdge) {
                 // This case is a colgroup without any col, we only compute it if it is adjacent to the cell's edge.
-                result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellBefore(*this), includeColor ? colElt->style().visitedDependentColor(startColorProperty) : Color(), BCOLGROUP));
+                result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellBefore(*this), includeColor ? colElt->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BCOLGROUP));
                 if (!result.exists())
                     return result;
             } else if (colElt->isTableColumn()) {
                 // Resolve the collapsing border against the col's border ignoring any 'span' as per HTML5.
-                result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellBefore(*this), includeColor ? colElt->style().visitedDependentColor(startColorProperty) : Color(), BCOL));
+                result = chooseBorder(result, CollapsedBorderValue(colElt->borderAdjoiningCellBefore(*this), includeColor ? colElt->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BCOL));
                 if (!result.exists())
                     return result;
                 // If we have a parent colgroup, resolve the border only if it is adjacent to the cell.
                 if (RenderTableCol* enclosingColumnGroup = colElt->enclosingColumnGroupIfAdjacentBefore()) {
-                    result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->borderAdjoiningCellStartBorder(), includeColor ? enclosingColumnGroup->style().visitedDependentColor(startColorProperty) : Color(), BCOLGROUP));
+                    result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->borderAdjoiningCellStartBorder(), includeColor ? enclosingColumnGroup->style().visitedDependentColorWithColorFilter(startColorProperty) : Color(), BCOLGROUP));
                     if (!result.exists())
                         return result;
                 }
@@ -752,7 +752,7 @@
 
     if (endBorderAdjoinsTable) {
         // (7) The table's end border.
-        result = chooseBorder(result, CollapsedBorderValue(table->tableEndBorderAdjoiningCell(*this), includeColor ? table->style().visitedDependentColor(endColorProperty) : Color(), BTABLE));
+        result = chooseBorder(result, CollapsedBorderValue(table->tableEndBorderAdjoiningCell(*this), includeColor ? table->style().visitedDependentColorWithColorFilter(endColorProperty) : Color(), BTABLE));
         if (!result.exists())
             return result;
     }
@@ -784,7 +784,7 @@
     // (1) Our before border.
     CSSPropertyID beforeColorProperty = includeColor ? CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderBeforeColor, styleForCellFlow().direction(), styleForCellFlow().writingMode()) : CSSPropertyInvalid;
     CSSPropertyID afterColorProperty = includeColor ? CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderAfterColor, styleForCellFlow().direction(), styleForCellFlow().writingMode()) : CSSPropertyInvalid;
-    CollapsedBorderValue result = CollapsedBorderValue(style().borderBefore(), includeColor ? style().visitedDependentColor(beforeColorProperty) : Color(), BCELL);
+    CollapsedBorderValue result = CollapsedBorderValue(style().borderBefore(), includeColor ? style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BCELL);
     
     RenderTable* table = this->table();
     if (!table)
@@ -792,13 +792,13 @@
     RenderTableCell* prevCell = table->cellAbove(this);
     if (prevCell) {
         // (2) A before cell's after border.
-        result = chooseBorder(CollapsedBorderValue(prevCell->style().borderAfter(), includeColor ? prevCell->style().visitedDependentColor(afterColorProperty) : Color(), BCELL), result);
+        result = chooseBorder(CollapsedBorderValue(prevCell->style().borderAfter(), includeColor ? prevCell->style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BCELL), result);
         if (!result.exists())
             return result;
     }
     
     // (3) Our row's before border.
-    result = chooseBorder(result, CollapsedBorderValue(parent()->style().borderBefore(), includeColor ? parent()->style().visitedDependentColor(beforeColorProperty) : Color(), BROW));
+    result = chooseBorder(result, CollapsedBorderValue(parent()->style().borderBefore(), includeColor ? parent()->style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BROW));
     if (!result.exists())
         return result;
     
@@ -811,7 +811,7 @@
             prevRow = prevCell->section()->lastRow();
     
         if (prevRow) {
-            result = chooseBorder(CollapsedBorderValue(prevRow->style().borderAfter(), includeColor ? prevRow->style().visitedDependentColor(afterColorProperty) : Color(), BROW), result);
+            result = chooseBorder(CollapsedBorderValue(prevRow->style().borderAfter(), includeColor ? prevRow->style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BROW), result);
             if (!result.exists())
                 return result;
         }
@@ -821,14 +821,14 @@
     RenderTableSection* currSection = section();
     if (!rowIndex()) {
         // (5) Our row group's before border.
-        result = chooseBorder(result, CollapsedBorderValue(currSection->style().borderBefore(), includeColor ? currSection->style().visitedDependentColor(beforeColorProperty) : Color(), BROWGROUP));
+        result = chooseBorder(result, CollapsedBorderValue(currSection->style().borderBefore(), includeColor ? currSection->style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BROWGROUP));
         if (!result.exists())
             return result;
         
         // (6) Previous row group's after border.
         currSection = table->sectionAbove(currSection, SkipEmptySections);
         if (currSection) {
-            result = chooseBorder(CollapsedBorderValue(currSection->style().borderAfter(), includeColor ? currSection->style().visitedDependentColor(afterColorProperty) : Color(), BROWGROUP), result);
+            result = chooseBorder(CollapsedBorderValue(currSection->style().borderAfter(), includeColor ? currSection->style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BROWGROUP), result);
             if (!result.exists())
                 return result;
         }
@@ -838,18 +838,18 @@
         // (8) Our column and column group's before borders.
         RenderTableCol* colElt = table->colElement(col());
         if (colElt) {
-            result = chooseBorder(result, CollapsedBorderValue(colElt->style().borderBefore(), includeColor ? colElt->style().visitedDependentColor(beforeColorProperty) : Color(), BCOL));
+            result = chooseBorder(result, CollapsedBorderValue(colElt->style().borderBefore(), includeColor ? colElt->style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BCOL));
             if (!result.exists())
                 return result;
             if (RenderTableCol* enclosingColumnGroup = colElt->enclosingColumnGroup()) {
-                result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->style().borderBefore(), includeColor ? enclosingColumnGroup->style().visitedDependentColor(beforeColorProperty) : Color(), BCOLGROUP));
+                result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->style().borderBefore(), includeColor ? enclosingColumnGroup->style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BCOLGROUP));
                 if (!result.exists())
                     return result;
             }
         }
         
         // (9) The table's before border.
-        result = chooseBorder(result, CollapsedBorderValue(table->style().borderBefore(), includeColor ? table->style().visitedDependentColor(beforeColorProperty) : Color(), BTABLE));
+        result = chooseBorder(result, CollapsedBorderValue(table->style().borderBefore(), includeColor ? table->style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BTABLE));
         if (!result.exists())
             return result;
     }
@@ -881,7 +881,7 @@
     // (1) Our after border.
     CSSPropertyID beforeColorProperty = includeColor ? CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderBeforeColor, styleForCellFlow().direction(), styleForCellFlow().writingMode()) : CSSPropertyInvalid;
     CSSPropertyID afterColorProperty = includeColor ? CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderAfterColor, styleForCellFlow().direction(), styleForCellFlow().writingMode()) : CSSPropertyInvalid;
-    CollapsedBorderValue result = CollapsedBorderValue(style().borderAfter(), includeColor ? style().visitedDependentColor(afterColorProperty) : Color(), BCELL);
+    CollapsedBorderValue result = CollapsedBorderValue(style().borderAfter(), includeColor ? style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BCELL);
     
     RenderTable* table = this->table();
     if (!table)
@@ -889,19 +889,19 @@
     RenderTableCell* nextCell = table->cellBelow(this);
     if (nextCell) {
         // (2) An after cell's before border.
-        result = chooseBorder(result, CollapsedBorderValue(nextCell->style().borderBefore(), includeColor ? nextCell->style().visitedDependentColor(beforeColorProperty) : Color(), BCELL));
+        result = chooseBorder(result, CollapsedBorderValue(nextCell->style().borderBefore(), includeColor ? nextCell->style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BCELL));
         if (!result.exists())
             return result;
     }
     
     // (3) Our row's after border. (FIXME: Deal with rowspan!)
-    result = chooseBorder(result, CollapsedBorderValue(parent()->style().borderAfter(), includeColor ? parent()->style().visitedDependentColor(afterColorProperty) : Color(), BROW));
+    result = chooseBorder(result, CollapsedBorderValue(parent()->style().borderAfter(), includeColor ? parent()->style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BROW));
     if (!result.exists())
         return result;
     
     // (4) The next row's before border.
     if (nextCell) {
-        result = chooseBorder(result, CollapsedBorderValue(nextCell->parent()->style().borderBefore(), includeColor ? nextCell->parent()->style().visitedDependentColor(beforeColorProperty) : Color(), BROW));
+        result = chooseBorder(result, CollapsedBorderValue(nextCell->parent()->style().borderBefore(), includeColor ? nextCell->parent()->style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BROW));
         if (!result.exists())
             return result;
     }
@@ -910,14 +910,14 @@
     RenderTableSection* currSection = section();
     if (rowIndex() + rowSpan() >= currSection->numRows()) {
         // (5) Our row group's after border.
-        result = chooseBorder(result, CollapsedBorderValue(currSection->style().borderAfter(), includeColor ? currSection->style().visitedDependentColor(afterColorProperty) : Color(), BROWGROUP));
+        result = chooseBorder(result, CollapsedBorderValue(currSection->style().borderAfter(), includeColor ? currSection->style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BROWGROUP));
         if (!result.exists())
             return result;
         
         // (6) Following row group's before border.
         currSection = table->sectionBelow(currSection, SkipEmptySections);
         if (currSection) {
-            result = chooseBorder(result, CollapsedBorderValue(currSection->style().borderBefore(), includeColor ? currSection->style().visitedDependentColor(beforeColorProperty) : Color(), BROWGROUP));
+            result = chooseBorder(result, CollapsedBorderValue(currSection->style().borderBefore(), includeColor ? currSection->style().visitedDependentColorWithColorFilter(beforeColorProperty) : Color(), BROWGROUP));
             if (!result.exists())
                 return result;
         }
@@ -927,17 +927,17 @@
         // (8) Our column and column group's after borders.
         RenderTableCol* colElt = table->colElement(col());
         if (colElt) {
-            result = chooseBorder(result, CollapsedBorderValue(colElt->style().borderAfter(), includeColor ? colElt->style().visitedDependentColor(afterColorProperty) : Color(), BCOL));
+            result = chooseBorder(result, CollapsedBorderValue(colElt->style().borderAfter(), includeColor ? colElt->style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BCOL));
             if (!result.exists()) return result;
             if (RenderTableCol* enclosingColumnGroup = colElt->enclosingColumnGroup()) {
-                result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->style().borderAfter(), includeColor ? enclosingColumnGroup->style().visitedDependentColor(afterColorProperty) : Color(), BCOLGROUP));
+                result = chooseBorder(result, CollapsedBorderValue(enclosingColumnGroup->style().borderAfter(), includeColor ? enclosingColumnGroup->style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BCOLGROUP));
                 if (!result.exists())
                     return result;
             }
         }
         
         // (9) The table's after border.
-        result = chooseBorder(result, CollapsedBorderValue(table->style().borderAfter(), includeColor ? table->style().visitedDependentColor(afterColorProperty) : Color(), BTABLE));
+        result = chooseBorder(result, CollapsedBorderValue(table->style().borderAfter(), includeColor ? table->style().visitedDependentColorWithColorFilter(afterColorProperty) : Color(), BTABLE));
         if (!result.exists())
             return result;
     }
@@ -1282,10 +1282,10 @@
     if (backgroundObject != this)
         adjustedPaintOffset.moveBy(location());
 
-    Color c = backgroundObject->style().visitedDependentColor(CSSPropertyBackgroundColor);
+    Color color = backgroundObject->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     auto& bgLayer = backgroundObject->style().backgroundLayers();
 
-    if (bgLayer.hasImage() || c.isValid()) {
+    if (bgLayer.hasImage() || color.isValid()) {
         // We have to clip here because the background would paint
         // on top of the borders otherwise.  This only matters for cells and rows.
         bool shouldClip = backgroundObject->hasLayer() && (backgroundObject == this || backgroundObject == parent()) && tableElt->collapseBorders();
@@ -1295,7 +1295,7 @@
                 width() - borderLeft() - borderRight(), height() - borderTop() - borderBottom());
             paintInfo.context().clip(clipRect);
         }
-        paintFillLayers(paintInfo, c, bgLayer, LayoutRect(adjustedPaintOffset, frameRect().size()), BackgroundBleedNone, CompositeSourceOver, backgroundObject);
+        paintFillLayers(paintInfo, color, bgLayer, LayoutRect(adjustedPaintOffset, frameRect().size()), BackgroundBleedNone, CompositeSourceOver, backgroundObject);
     }
 }
 
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index e38deab..c7e7bd6 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -1082,7 +1082,7 @@
     rect.intersect(paintInfo.rect);
     if (rect.isEmpty())
         return;
-    drawLineForBoxSide(paintInfo.context(), rect, side, style().visitedDependentColor(borderColor), borderStyle, 0, 0, antialias);
+    drawLineForBoxSide(paintInfo.context(), rect, side, style().visitedDependentColorWithColorFilter(borderColor), borderStyle, 0, 0, antialias);
 }
 
 LayoutUnit RenderTableSection::offsetLeftForRowGroupBorder(RenderTableCell* cell, const LayoutRect& rowGroupRect, unsigned row)
diff --git a/Source/WebCore/rendering/RenderTheme.cpp b/Source/WebCore/rendering/RenderTheme.cpp
index 7920b77..a707f18 100644
--- a/Source/WebCore/rendering/RenderTheme.cpp
+++ b/Source/WebCore/rendering/RenderTheme.cpp
@@ -1053,7 +1053,7 @@
     }
     Ref<HTMLCollection> options = dataList->options();
     GraphicsContextStateSaver stateSaver(paintInfo.context());
-    paintInfo.context().setFillColor(o.style().visitedDependentColor(CSSPropertyColor));
+    paintInfo.context().setFillColor(o.style().visitedDependentColorWithColorFilter(CSSPropertyColor));
     for (unsigned i = 0; Node* node = options->item(i); i++) {
         ASSERT(is<HTMLOptionElement>(*node));
         HTMLOptionElement& optionElement = downcast<HTMLOptionElement>(*node);
diff --git a/Source/WebCore/rendering/TextDecorationPainter.cpp b/Source/WebCore/rendering/TextDecorationPainter.cpp
index 4159b15..f87ce1b 100644
--- a/Source/WebCore/rendering/TextDecorationPainter.cpp
+++ b/Source/WebCore/rendering/TextDecorationPainter.cpp
@@ -359,7 +359,7 @@
 static Color decorationColor(const RenderStyle& style)
 {
     // Check for text decoration color first.
-    Color result = style.visitedDependentColor(CSSPropertyWebkitTextDecorationColor);
+    Color result = style.visitedDependentColorWithColorFilter(CSSPropertyWebkitTextDecorationColor);
     if (result.isValid())
         return result;
     if (style.hasPositiveStrokeWidth()) {
@@ -369,7 +369,7 @@
             return result;
     }
     
-    return style.visitedDependentColor(CSSPropertyWebkitTextFillColor);
+    return style.visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor);
 }
 
 static void collectStylesForRenderer(TextDecorationPainter::Styles& result, const RenderObject& renderer, OptionSet<TextDecoration> remainingDecorations, bool firstLineStyle, PseudoId pseudoId)
diff --git a/Source/WebCore/rendering/TextPaintStyle.cpp b/Source/WebCore/rendering/TextPaintStyle.cpp
index ebfdec2..28f83f8 100644
--- a/Source/WebCore/rendering/TextPaintStyle.cpp
+++ b/Source/WebCore/rendering/TextPaintStyle.cpp
@@ -106,7 +106,7 @@
         }
     }
 
-    paintStyle.fillColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextFillColor);
+    paintStyle.fillColor = lineStyle.visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor);
 
     bool forceBackgroundToWhite = false;
     if (frame.document() && frame.document()->printing()) {
@@ -126,7 +126,7 @@
     if (forceBackgroundToWhite)
         paintStyle.strokeColor = adjustColorForVisibilityOnBackground(paintStyle.strokeColor, Color::white);
 
-    paintStyle.emphasisMarkColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextEmphasisColor);
+    paintStyle.emphasisMarkColor = lineStyle.visitedDependentColorWithColorFilter(CSSPropertyWebkitTextEmphasisColor);
 
     // Make the text stroke color legible against a white background
     if (forceBackgroundToWhite)
diff --git a/Source/WebCore/rendering/mathml/MathOperator.cpp b/Source/WebCore/rendering/mathml/MathOperator.cpp
index 8e02c35..2ee272e 100644
--- a/Source/WebCore/rendering/mathml/MathOperator.cpp
+++ b/Source/WebCore/rendering/mathml/MathOperator.cpp
@@ -714,7 +714,7 @@
     // Make a copy of the PaintInfo because applyTransform will modify its rect.
     PaintInfo paintInfo(info);
     GraphicsContextStateSaver stateSaver(paintInfo.context());
-    paintInfo.context().setFillColor(style.visitedDependentColor(CSSPropertyColor));
+    paintInfo.context().setFillColor(style.visitedDependentColorWithColorFilter(CSSPropertyColor));
 
     // For a radical character, we may need some scale transform to stretch it vertically or mirror it.
     if (m_baseCharacter == kRadicalOperator) {
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
index 447c160..2607e9b 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
@@ -264,7 +264,7 @@
 
     info.context().setStrokeThickness(thickness);
     info.context().setStrokeStyle(SolidStroke);
-    info.context().setStrokeColor(style().visitedDependentColor(CSSPropertyColor));
+    info.context().setStrokeColor(style().visitedDependentColorWithColorFilter(CSSPropertyColor));
     info.context().drawLine(adjustedPaintOffset, roundedIntPoint(LayoutPoint(adjustedPaintOffset.x() + logicalWidth(), adjustedPaintOffset.y())));
 }
 
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLMenclose.cpp b/Source/WebCore/rendering/mathml/RenderMathMLMenclose.cpp
index 908cfe3..42f6a3c 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLMenclose.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLMenclose.cpp
@@ -218,7 +218,7 @@
 
     paintInfo.context().setStrokeThickness(thickness);
     paintInfo.context().setStrokeStyle(SolidStroke);
-    paintInfo.context().setStrokeColor(style().visitedDependentColor(CSSPropertyColor));
+    paintInfo.context().setStrokeColor(style().visitedDependentColorWithColorFilter(CSSPropertyColor));
     paintInfo.context().setFillColor(Color::transparent);
     paintInfo.applyTransform(AffineTransform().translate(paintOffset + location()));
 
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp b/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp
index e94fa2b..1a041c7 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp
@@ -289,7 +289,7 @@
 
     info.context().setStrokeThickness(ruleThickness);
     info.context().setStrokeStyle(SolidStroke);
-    info.context().setStrokeColor(style().visitedDependentColor(CSSPropertyColor));
+    info.context().setStrokeColor(style().visitedDependentColorWithColorFilter(CSSPropertyColor));
     LayoutPoint ruleOffsetFrom = paintOffset + location() + LayoutPoint(0, m_radicalOperatorTop + ruleThickness / 2);
     LayoutPoint ruleOffsetTo = ruleOffsetFrom;
     horizontalOffset += m_radicalOperator.width();
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLToken.cpp b/Source/WebCore/rendering/mathml/RenderMathMLToken.cpp
index e25f2a7..2d157db 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLToken.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLToken.cpp
@@ -602,7 +602,7 @@
         return;
 
     GraphicsContextStateSaver stateSaver(info.context());
-    info.context().setFillColor(style().visitedDependentColor(CSSPropertyColor));
+    info.context().setFillColor(style().visitedDependentColorWithColorFilter(CSSPropertyColor));
 
     GlyphBuffer buffer;
     buffer.add(mathVariantGlyph.glyph, mathVariantGlyph.font, mathVariantGlyph.font->widthForGlyph(mathVariantGlyph.glyph));
diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp
index 77bc455..4609bea 100644
--- a/Source/WebCore/rendering/style/RenderStyle.cpp
+++ b/Source/WebCore/rendering/style/RenderStyle.cpp
@@ -1846,6 +1846,21 @@
     return visitedColor.colorWithAlpha(unvisitedColor.alphaAsFloat());
 }
 
+Color RenderStyle::visitedDependentColorWithColorFilter(CSSPropertyID colorProperty) const
+{
+    if (!hasColorFilter())
+        return visitedDependentColor(colorProperty);
+
+    return colorByApplyingColorFilter(visitedDependentColor(colorProperty));
+}
+
+Color RenderStyle::colorByApplyingColorFilter(const Color& color) const
+{
+    Color transformedColor = color;
+    colorFilter().transformColor(transformedColor);
+    return transformedColor;
+}
+
 const BorderValue& RenderStyle::borderBefore() const
 {
     switch (writingMode()) {
diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h
index 5d68577..a32cdfc 100644
--- a/Source/WebCore/rendering/style/RenderStyle.h
+++ b/Source/WebCore/rendering/style/RenderStyle.h
@@ -1414,6 +1414,10 @@
     void setLastChildState() { setUnique(); m_nonInheritedFlags.lastChildState = true; }
 
     WEBCORE_EXPORT Color visitedDependentColor(CSSPropertyID) const;
+    WEBCORE_EXPORT Color visitedDependentColorWithColorFilter(CSSPropertyID) const;
+
+    WEBCORE_EXPORT Color colorByApplyingColorFilter(const Color&) const;
+
     bool backgroundColorEqualsToColorIgnoringVisited(const Color& color) const { return color == backgroundColor(); }
 
     void setHasExplicitlyInheritedProperties() { m_nonInheritedFlags.hasExplicitlyInheritedProperties = true; }
diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog
index b560801..44c99da 100644
--- a/Source/WebKitLegacy/mac/ChangeLog
+++ b/Source/WebKitLegacy/mac/ChangeLog
@@ -1,3 +1,18 @@
+2018-04-26  Simon Fraser  <simon.fraser@apple.com>
+
+        Implement rendering support for the color-filter CSS property
+        https://bugs.webkit.org/show_bug.cgi?id=185047
+        rdar://problem/39664967
+
+        Reviewed by Tim Horton.
+        
+        The body background should reflect the filtered color.
+
+        * WebView/WebFrame.mm:
+        (-[WebFrame _bodyBackgroundColor]):
+        * WebView/WebView.mm:
+        (-[WebView updateTextTouchBar]): No logic change, just cleanup.
+
 2018-04-26  Jer Noble  <jer.noble@apple.com>
 
         WK_COCOA_TOUCH all the things.
diff --git a/Source/WebKitLegacy/mac/WebView/WebFrame.mm b/Source/WebKitLegacy/mac/WebView/WebFrame.mm
index fd92453..4828480 100644
--- a/Source/WebKitLegacy/mac/WebView/WebFrame.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebFrame.mm
@@ -1034,7 +1034,7 @@
     RenderObject* bodyRenderer = body->renderer();
     if (!bodyRenderer)
         return nil;
-    Color color = bodyRenderer->style().visitedDependentColor(CSSPropertyBackgroundColor);
+    Color color = bodyRenderer->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     if (!color.isValid())
         return nil;
 #if !PLATFORM(IOS)
diff --git a/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h b/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
index 110692c..5cc4a2b 100644
--- a/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
+++ b/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
@@ -193,6 +193,7 @@
 #define WebKitIsSecureContextAttributeEnabledPreferenceKey @"WebKitIsSecureContextAttributeEnabled"
 #define WebKitViewportFitEnabledPreferenceKey @"WebKitViewportFitEnabled"
 #define WebKitConstantPropertiesEnabledPreferenceKey @"WebKitConstantPropertiesEnabled"
+#define WebKitColorFilterEnabledPreferenceKey @"WebKitColorFilterEnabled"
 #define WebKitFetchAPIKeepAliveEnabledPreferenceKey @"WebKitFetchAPIKeepAliveEnabled"
 #define WebKitCSSAnimationsAndCSSTransitionsBackedByWebAnimationsEnabledPreferenceKey @"WebKitCSSAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled"
 
diff --git a/Source/WebKitLegacy/mac/WebView/WebPreferences.mm b/Source/WebKitLegacy/mac/WebView/WebPreferences.mm
index 1bb4796..6858597 100644
--- a/Source/WebKitLegacy/mac/WebView/WebPreferences.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebPreferences.mm
@@ -676,6 +676,7 @@
         @NO, WebKitEncryptedMediaAPIEnabledKey,
         @YES, WebKitViewportFitEnabledPreferenceKey,
         @YES, WebKitConstantPropertiesEnabledPreferenceKey,
+        @NO, WebKitColorFilterEnabledPreferenceKey,
         @YES, WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey,
         @NO, WebKitInspectorAdditionsEnabledPreferenceKey,
         (NSString *)Settings::defaultMediaContentTypesRequiringHardwareSupport(), WebKitMediaContentTypesRequiringHardwareSupportPreferenceKey,
@@ -3077,6 +3078,7 @@
 {
     [self _setBoolValue:flag forKey:WebKitVisualViewportAPIEnabledPreferenceKey];
 }
+
 - (BOOL)webAnimationsEnabled
 {
     return [self _boolValueForKey:WebKitWebAnimationsEnabledPreferenceKey];
@@ -3259,6 +3261,16 @@
     [self _setBoolValue:flag forKey:WebKitConstantPropertiesEnabledPreferenceKey];
 }
 
+- (BOOL)colorFilterEnabled
+{
+    return [self _boolValueForKey:WebKitColorFilterEnabledPreferenceKey];
+}
+
+- (void)setColorFilterEnabled:(BOOL)flag
+{
+    [self _setBoolValue:flag forKey:WebKitColorFilterEnabledPreferenceKey];
+}
+
 - (BOOL)allowMediaContentTypesRequiringHardwareSupportAsFallback
 {
     return [self _boolValueForKey:WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey];
diff --git a/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h b/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
index 78d84f9..0c22714 100644
--- a/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
+++ b/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
@@ -597,6 +597,7 @@
 @property (nonatomic) BOOL encryptedMediaAPIEnabled;
 @property (nonatomic) BOOL viewportFitEnabled;
 @property (nonatomic) BOOL constantPropertiesEnabled;
+@property (nonatomic) BOOL colorFilterEnabled;
 @property (nonatomic) BOOL inspectorAdditionsEnabled;
 @property (nonatomic) BOOL allowMediaContentTypesRequiringHardwareSupportAsFallback;
 @property (nonatomic) BOOL accessibilityObjectModelEnabled;
diff --git a/Source/WebKitLegacy/mac/WebView/WebView.mm b/Source/WebKitLegacy/mac/WebView/WebView.mm
index 43487d8..b1d83c5 100644
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
@@ -3065,6 +3065,7 @@
 
     settings.setViewportFitEnabled([preferences viewportFitEnabled]);
     settings.setConstantPropertiesEnabled([preferences constantPropertiesEnabled]);
+    settings.setColorFilterEnabled([preferences colorFilterEnabled]);
 
 #if ENABLE(GAMEPAD)
     RuntimeEnabledFeatures::sharedFeatures().setGamepadsEnabled([preferences gamepadsEnabled]);
@@ -9921,8 +9922,9 @@
                 } else
                     [_private->_textTouchBarItemController setTextIsUnderlined:(style->textDecorationsInEffect() & TextDecorationUnderline)];
 
-                if (style->visitedDependentColor(CSSPropertyColor).isValid())
-                    [_private->_textTouchBarItemController setTextColor:nsColor(style->visitedDependentColor(CSSPropertyColor))];
+                Color textColor = style->visitedDependentColor(CSSPropertyColor);
+                if (textColor.isValid())
+                    [_private->_textTouchBarItemController setTextColor:nsColor(textColor)];
 
                 [_private->_textTouchBarItemController setCurrentTextAlignment:nsTextAlignmentFromRenderStyle(style)];
 
diff --git a/Tools/DumpRenderTree/mac/DumpRenderTree.mm b/Tools/DumpRenderTree/mac/DumpRenderTree.mm
index 83781ac..5ac28d2 100644
--- a/Tools/DumpRenderTree/mac/DumpRenderTree.mm
+++ b/Tools/DumpRenderTree/mac/DumpRenderTree.mm
@@ -861,6 +861,7 @@
     preferences.encryptedMediaAPIEnabled = YES;
     [preferences setAccessibilityObjectModelEnabled:YES];
     [preferences setVisualViewportAPIEnabled:YES];
+    [preferences setColorFilterEnabled:YES];
 }
 
 // Called before each test.