Diff
Modified: trunk/LayoutTests/ChangeLog (231104 => 231105)
--- trunk/LayoutTests/ChangeLog 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/LayoutTests/ChangeLog 2018-04-27 17:59:25 UTC (rev 231105)
@@ -1,5 +1,15 @@
2018-04-27 Simon Fraser <[email protected]>
+ Make color-filter transform gradient colors
+ https://bugs.webkit.org/show_bug.cgi?id=185080
+
+ Reviewed by Zalan Bujtas.
+
+ * css3/color-filters/color-filter-gradients-expected.html: Added.
+ * css3/color-filters/color-filter-gradients.html: Added.
+
+2018-04-27 Simon Fraser <[email protected]>
+
Disable color-filter tests on Windows for now
https://bugs.webkit.org/show_bug.cgi?id=185076
Added: trunk/LayoutTests/css3/color-filters/color-filter-gradients-expected.html (0 => 231105)
--- trunk/LayoutTests/css3/color-filters/color-filter-gradients-expected.html (rev 0)
+++ trunk/LayoutTests/css3/color-filters/color-filter-gradients-expected.html 2018-04-27 17:59:25 UTC (rev 231105)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>CSS Test: color-filter reference</title>
+ <link rel="author" title="Apple" href=""
+
+ <style type="text/css">
+ .test
+ {
+ width: 200px;
+ height: 200px;
+ margin: 10px;
+ float: left;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="test" style="background-image: linear-gradient(blue, red);"></div>
+ <div class="test" style="background-image: radial-gradient(blue, red);"></div>
+ <div class="test" style="background-image: repeating-linear-gradient(blue, red 50px);"></div>
+ <div class="test" style="background-image: repeating-radial-gradient(blue, red 50px);"></div>
+ </body>
+</html>
Added: trunk/LayoutTests/css3/color-filters/color-filter-gradients.html (0 => 231105)
--- trunk/LayoutTests/css3/color-filters/color-filter-gradients.html (rev 0)
+++ trunk/LayoutTests/css3/color-filters/color-filter-gradients.html 2018-04-27 17:59:25 UTC (rev 231105)
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>CSS Test: color-filter affects gradients</title>
+ <link rel="author" title="Apple" href=""
+ <link rel="match" href=""
+
+ <meta name="assert" content="color-filter affects gradients">
+ <style type="text/css">
+ .test
+ {
+ width: 200px;
+ height: 200px;
+ margin: 10px;
+ float: left;
+ color-filter: invert();
+ }
+ </style>
+ <script>
+ if (window.internals)
+ internals.settings.setColorFilterEnabled(true);
+ </script>
+ </head>
+ <body>
+ <div class="test" style="background-image: linear-gradient(yellow, cyan);"></div>
+ <div class="test" style="background-image: radial-gradient(yellow, cyan);"></div>
+ <div class="test" style="background-image: repeating-linear-gradient(yellow, cyan 50px);"></div>
+ <div class="test" style="background-image: repeating-radial-gradient(yellow, cyan 50px);"></div>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (231104 => 231105)
--- trunk/Source/WebCore/ChangeLog 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/ChangeLog 2018-04-27 17:59:25 UTC (rev 231105)
@@ -1,3 +1,37 @@
+2018-04-27 Simon Fraser <[email protected]>
+
+ Make color-filter transform gradient colors
+ https://bugs.webkit.org/show_bug.cgi?id=185080
+
+ Reviewed by Zalan Bujtas.
+
+ In CSSGradientValue::computeStops(), transform the color of each gradient color
+ stop through the color filter. Having a color filter makes the gradient uncacheable.
+
+ Color filters can add alpha, so we also have to fix up CSSGradientValue::knownToBeOpaque()
+ to take a RenderStyle and convert the colors before testing opaqueness. Clean up some related
+ functions to take const RenderStyle&.
+
+ Test: css3/color-filters/color-filter-gradients.html
+
+ * css/CSSCrossfadeValue.cpp:
+ (WebCore::subimageKnownToBeOpaque):
+ * css/CSSFilterImageValue.cpp:
+ (WebCore::CSSFilterImageValue::knownToBeOpaque const):
+ * css/CSSFilterImageValue.h:
+ * css/CSSGradientValue.cpp:
+ (WebCore::CSSGradientValue::image):
+ (WebCore::CSSGradientValue::computeStops):
+ (WebCore::CSSGradientValue::knownToBeOpaque const):
+ (WebCore::CSSLinearGradientValue::createGradient):
+ (WebCore::CSSRadialGradientValue::createGradient):
+ * css/CSSGradientValue.h:
+ * css/CSSImageGeneratorValue.cpp:
+ (WebCore::CSSImageGeneratorValue::knownToBeOpaque const):
+ * css/CSSImageValue.cpp:
+ (WebCore::CSSImageValue::knownToBeOpaque const):
+ * css/CSSImageValue.h:
+
2018-04-26 Simon Fraser <[email protected]>
Fix color-filter to apply to text decorations
Modified: trunk/Source/WebCore/css/CSSCrossfadeValue.cpp (231104 => 231105)
--- trunk/Source/WebCore/css/CSSCrossfadeValue.cpp 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/css/CSSCrossfadeValue.cpp 2018-04-27 17:59:25 UTC (rev 231105)
@@ -46,7 +46,7 @@
static bool subimageKnownToBeOpaque(const CSSValue& value, const RenderElement& renderer)
{
if (is<CSSImageValue>(value))
- return downcast<CSSImageValue>(value).knownToBeOpaque(&renderer);
+ return downcast<CSSImageValue>(value).knownToBeOpaque(renderer);
if (is<CSSImageGeneratorValue>(value))
return downcast<CSSImageGeneratorValue>(value).knownToBeOpaque(renderer);
Modified: trunk/Source/WebCore/css/CSSFilterImageValue.cpp (231104 => 231105)
--- trunk/Source/WebCore/css/CSSFilterImageValue.cpp 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/css/CSSFilterImageValue.cpp 2018-04-27 17:59:25 UTC (rev 231105)
@@ -76,7 +76,7 @@
return CSSImageGeneratorValue::subimageIsPending(m_imageValue);
}
-bool CSSFilterImageValue::knownToBeOpaque(const RenderElement*) const
+bool CSSFilterImageValue::knownToBeOpaque(const RenderElement&) const
{
return false;
}
Modified: trunk/Source/WebCore/css/CSSFilterImageValue.h (231104 => 231105)
--- trunk/Source/WebCore/css/CSSFilterImageValue.h 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/css/CSSFilterImageValue.h 2018-04-27 17:59:25 UTC (rev 231105)
@@ -58,7 +58,7 @@
FloatSize fixedSize(const RenderElement*);
bool isPending() const;
- bool knownToBeOpaque(const RenderElement*) const;
+ bool knownToBeOpaque(const RenderElement&) const;
void loadSubimages(CachedResourceLoader&, const ResourceLoaderOptions&);
Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (231104 => 231105)
--- trunk/Source/WebCore/css/CSSGradientValue.cpp 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp 2018-04-27 17:59:25 UTC (rev 231105)
@@ -52,7 +52,7 @@
{
if (size.isEmpty())
return nullptr;
- bool cacheable = isCacheable();
+ bool cacheable = isCacheable() && !renderer.style().hasColorFilter();
if (cacheable) {
if (!clients().contains(&renderer))
return nullptr;
@@ -225,7 +225,7 @@
};
template<typename GradientAdapter>
-Gradient::ColorStopVector CSSGradientValue::computeStops(GradientAdapter& gradient, const CSSToLengthConversionData& conversionData, float maxLengthForRepeat)
+Gradient::ColorStopVector CSSGradientValue::computeStops(GradientAdapter& gradient, const CSSToLengthConversionData& conversionData, const RenderStyle& style, float maxLengthForRepeat)
{
if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDeprecatedRadialGradient) {
sortStopsIfNeeded();
@@ -240,7 +240,10 @@
else
offset = stop.m_position->floatValue(CSSPrimitiveValue::CSS_NUMBER);
- result.uncheckedAppend({ offset, stop.m_resolvedColor });
+ Color color = stop.m_resolvedColor;
+ if (style.hasColorFilter())
+ style.colorFilter().transformColor(color);
+ result.uncheckedAppend({ offset, color });
}
return result;
@@ -259,8 +262,13 @@
auto& stop = m_stops[i];
stops[i].isMidpoint = stop.isMidpoint;
- stops[i].color = stop.m_resolvedColor;
+ Color color = stop.m_resolvedColor;
+ if (style.hasColorFilter())
+ style.colorFilter().transformColor(color);
+
+ stops[i].color = color;
+
if (stop.m_position) {
auto& positionValue = *stop.m_position;
if (positionValue.isPercentage())
@@ -569,9 +577,18 @@
return true;
}
-bool CSSGradientValue::knownToBeOpaque() const
+bool CSSGradientValue::knownToBeOpaque(const RenderElement& renderer) const
{
+ bool hasColorFilter = renderer.style().hasColorFilter();
+
for (auto& stop : m_stops) {
+ if (hasColorFilter) {
+ Color stopColor = stop.m_resolvedColor;
+ renderer.style().colorFilter().transformColor(stopColor);
+ if (!stopColor.isOpaque())
+ return false;
+ }
+
if (!stop.m_resolvedColor.isOpaque())
return false;
}
@@ -814,7 +831,7 @@
Gradient::LinearData data { firstPoint, secondPoint };
LinearGradientAdapter adapter { data };
- auto stops = computeStops(adapter, conversionData, 1);
+ auto stops = computeStops(adapter, conversionData, renderer.style(), 1);
auto gradient = Gradient::create(WTFMove(data));
gradient->setSortedColorStops(WTFMove(stops));
@@ -1231,7 +1248,7 @@
Gradient::RadialData data { firstPoint, secondPoint, firstRadius, secondRadius, aspectRatio };
RadialGradientAdapter adapter { data };
- auto stops = computeStops(adapter, conversionData, maxExtent);
+ auto stops = computeStops(adapter, conversionData, renderer.style(), maxExtent);
auto gradient = Gradient::create(WTFMove(data));
gradient->setSortedColorStops(WTFMove(stops));
Modified: trunk/Source/WebCore/css/CSSGradientValue.h (231104 => 231105)
--- trunk/Source/WebCore/css/CSSGradientValue.h 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/css/CSSGradientValue.h 2018-04-27 17:59:25 UTC (rev 231105)
@@ -82,7 +82,7 @@
FloatSize fixedSize(const RenderElement&) const { return FloatSize(); }
bool isPending() const { return false; }
- bool knownToBeOpaque() const;
+ bool knownToBeOpaque(const RenderElement&) const;
void loadSubimages(CachedResourceLoader&, const ResourceLoaderOptions&) { }
Ref<CSSGradientValue> gradientWithStylesResolved(const StyleResolver&);
@@ -110,7 +110,7 @@
}
template<typename GradientAdapter>
- Gradient::ColorStopVector computeStops(GradientAdapter&, const CSSToLengthConversionData&, float maxLengthForRepeat);
+ Gradient::ColorStopVector computeStops(GradientAdapter&, const CSSToLengthConversionData&, const RenderStyle&, float maxLengthForRepeat);
// Resolve points/radii to front end values.
FloatPoint computeEndPoint(CSSPrimitiveValue*, CSSPrimitiveValue*, const CSSToLengthConversionData&, const FloatSize&);
Modified: trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp (231104 => 231105)
--- trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp 2018-04-27 17:59:25 UTC (rev 231105)
@@ -233,13 +233,13 @@
case NamedImageClass:
return false;
case FilterImageClass:
- return downcast<CSSFilterImageValue>(*this).knownToBeOpaque(&renderer);
+ return downcast<CSSFilterImageValue>(*this).knownToBeOpaque(renderer);
case LinearGradientClass:
- return downcast<CSSLinearGradientValue>(*this).knownToBeOpaque();
+ return downcast<CSSLinearGradientValue>(*this).knownToBeOpaque(renderer);
case RadialGradientClass:
- return downcast<CSSRadialGradientValue>(*this).knownToBeOpaque();
+ return downcast<CSSRadialGradientValue>(*this).knownToBeOpaque(renderer);
case ConicGradientClass:
- return downcast<CSSConicGradientValue>(*this).knownToBeOpaque();
+ return downcast<CSSConicGradientValue>(*this).knownToBeOpaque(renderer);
default:
ASSERT_NOT_REACHED();
}
Modified: trunk/Source/WebCore/css/CSSImageValue.cpp (231104 => 231105)
--- trunk/Source/WebCore/css/CSSImageValue.cpp 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/css/CSSImageValue.cpp 2018-04-27 17:59:25 UTC (rev 231105)
@@ -100,11 +100,11 @@
return DeprecatedCSSOMPrimitiveValue::create(CSSPrimitiveValue::create(m_url, CSSPrimitiveValue::CSS_URI), styleDeclaration);
}
-bool CSSImageValue::knownToBeOpaque(const RenderElement* renderer) const
+bool CSSImageValue::knownToBeOpaque(const RenderElement& renderer) const
{
if (!m_cachedImage)
return false;
- return m_cachedImage->currentFrameKnownToBeOpaque(renderer);
+ return m_cachedImage->currentFrameKnownToBeOpaque(&renderer);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/css/CSSImageValue.h (231104 => 231105)
--- trunk/Source/WebCore/css/CSSImageValue.h 2018-04-27 17:22:35 UTC (rev 231104)
+++ trunk/Source/WebCore/css/CSSImageValue.h 2018-04-27 17:59:25 UTC (rev 231105)
@@ -54,7 +54,7 @@
bool equals(const CSSImageValue&) const;
- bool knownToBeOpaque(const RenderElement*) const;
+ bool knownToBeOpaque(const RenderElement&) const;
void setInitiator(const AtomicString& name) { m_initiatorName = name; }