WebKit Bugzilla
Attachment 338998 Details for
Bug 185080
: Make color-filter transform gradient colors
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185080-20180427100835.patch (text/plain), 14.44 KB, created by
Simon Fraser (smfr)
on 2018-04-27 10:08:36 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Simon Fraser (smfr)
Created:
2018-04-27 10:08:36 PDT
Size:
14.44 KB
patch
obsolete
>Subversion Revision: 231101 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index c98d01b98a327c6fbc0bbd78238d424caf935f45..64220f90bb763a94e6592b7ff9188b5a5ab5bf8e 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,37 @@ >+2018-04-27 Simon Fraser <simon.fraser@apple.com> >+ >+ Make color-filter transform gradient colors >+ https://bugs.webkit.org/show_bug.cgi?id=185080 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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 <simon.fraser@apple.com> > > Fix color-filter to apply to text decorations >diff --git a/Source/WebCore/css/CSSCrossfadeValue.cpp b/Source/WebCore/css/CSSCrossfadeValue.cpp >index 9eb6f0f294aac537bff0c4117f303986b31fe668..172c9458d1342d6a85e2310970cc6017da9be09e 100644 >--- a/Source/WebCore/css/CSSCrossfadeValue.cpp >+++ b/Source/WebCore/css/CSSCrossfadeValue.cpp >@@ -46,7 +46,7 @@ static inline double blendFunc(double from, double to, double progress) > 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); >diff --git a/Source/WebCore/css/CSSFilterImageValue.cpp b/Source/WebCore/css/CSSFilterImageValue.cpp >index eaab7033754708776513c39e549d611a2e2dcefb..6acf744eab4a9eceaab6c6c72ef9ce958b02e515 100644 >--- a/Source/WebCore/css/CSSFilterImageValue.cpp >+++ b/Source/WebCore/css/CSSFilterImageValue.cpp >@@ -76,7 +76,7 @@ bool CSSFilterImageValue::isPending() const > return CSSImageGeneratorValue::subimageIsPending(m_imageValue); > } > >-bool CSSFilterImageValue::knownToBeOpaque(const RenderElement*) const >+bool CSSFilterImageValue::knownToBeOpaque(const RenderElement&) const > { > return false; > } >diff --git a/Source/WebCore/css/CSSFilterImageValue.h b/Source/WebCore/css/CSSFilterImageValue.h >index 3ffc4f286785cd35127ebc2d0e1c98695f345dd7..8f1c999181e86176ad7bb06252fcd26ec6aa2bc6 100644 >--- a/Source/WebCore/css/CSSFilterImageValue.h >+++ b/Source/WebCore/css/CSSFilterImageValue.h >@@ -58,7 +58,7 @@ public: > FloatSize fixedSize(const RenderElement*); > > bool isPending() const; >- bool knownToBeOpaque(const RenderElement*) const; >+ bool knownToBeOpaque(const RenderElement&) const; > > void loadSubimages(CachedResourceLoader&, const ResourceLoaderOptions&); > >diff --git a/Source/WebCore/css/CSSGradientValue.cpp b/Source/WebCore/css/CSSGradientValue.cpp >index eef295b86a34d2a398009da4725c4c10141c2da8..171d4726383292609f2209eb5678bee14d5a682b 100644 >--- a/Source/WebCore/css/CSSGradientValue.cpp >+++ b/Source/WebCore/css/CSSGradientValue.cpp >@@ -52,7 +52,7 @@ RefPtr<Image> CSSGradientValue::image(RenderElement& renderer, const FloatSize& > { > 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 @@ private: > }; > > 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 @@ Gradient::ColorStopVector CSSGradientValue::computeStops(GradientAdapter& gradie > 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,7 +262,12 @@ Gradient::ColorStopVector CSSGradientValue::computeStops(GradientAdapter& gradie > 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; >@@ -569,9 +577,18 @@ bool CSSGradientValue::isCacheable() const > 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 @@ Ref<Gradient> CSSLinearGradientValue::createGradient(RenderElement& renderer, co > > 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 @@ Ref<Gradient> CSSRadialGradientValue::createGradient(RenderElement& renderer, co > > 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)); >diff --git a/Source/WebCore/css/CSSGradientValue.h b/Source/WebCore/css/CSSGradientValue.h >index 9cb03f463f6c52b8d1d79b77f1b7d29e1ec6fe30..68f8240f2dced5d5dbaf93ebd07688beed04658d 100644 >--- a/Source/WebCore/css/CSSGradientValue.h >+++ b/Source/WebCore/css/CSSGradientValue.h >@@ -82,7 +82,7 @@ public: > 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 @@ protected: > } > > 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&); >diff --git a/Source/WebCore/css/CSSImageGeneratorValue.cpp b/Source/WebCore/css/CSSImageGeneratorValue.cpp >index a7e664c8866563d5eca54c7b9ddf47e5250be5c4..7a8e19f230f4a200a52b51158302e1cdce55fc6e 100644 >--- a/Source/WebCore/css/CSSImageGeneratorValue.cpp >+++ b/Source/WebCore/css/CSSImageGeneratorValue.cpp >@@ -233,13 +233,13 @@ bool CSSImageGeneratorValue::knownToBeOpaque(const RenderElement& renderer) cons > 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(); > } >diff --git a/Source/WebCore/css/CSSImageValue.cpp b/Source/WebCore/css/CSSImageValue.cpp >index c191ecc2dddc820eab687e05cf9d8aaeab42b20b..4ea4114ccd8980553975e50ad8b593f04d5b11f8 100644 >--- a/Source/WebCore/css/CSSImageValue.cpp >+++ b/Source/WebCore/css/CSSImageValue.cpp >@@ -100,11 +100,11 @@ Ref<DeprecatedCSSOMValue> CSSImageValue::createDeprecatedCSSOMWrapper(CSSStyleDe > 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 >diff --git a/Source/WebCore/css/CSSImageValue.h b/Source/WebCore/css/CSSImageValue.h >index 3ab559944fa0b85812cca6d0b2db60c7066723e1..76f94df5e42e833ea987ec93cf91d1c26c2fe86d 100644 >--- a/Source/WebCore/css/CSSImageValue.h >+++ b/Source/WebCore/css/CSSImageValue.h >@@ -54,7 +54,7 @@ public: > > bool equals(const CSSImageValue&) const; > >- bool knownToBeOpaque(const RenderElement*) const; >+ bool knownToBeOpaque(const RenderElement&) const; > > void setInitiator(const AtomicString& name) { m_initiatorName = name; } > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index e65c3c2efa7b8fc5ba85fdb3f8bc6e1630ab1e7f..1b02d76f68d0dcc0b75cebb8313a8a28e8b68ff7 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,13 @@ >+2018-04-27 Simon Fraser <simon.fraser@apple.com> >+ >+ Make color-filter transform gradient colors >+ https://bugs.webkit.org/show_bug.cgi?id=185080 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * css3/color-filters/color-filter-gradients-expected.html: Added. >+ * css3/color-filters/color-filter-gradients.html: Added. >+ > 2018-04-27 Simon Fraser <simon.fraser@apple.com> > > Disable color-filter tests on Windows for now >diff --git a/LayoutTests/css3/color-filters/color-filter-gradients-expected.html b/LayoutTests/css3/color-filters/color-filter-gradients-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..39a79635e3c6d47201de93cfa74212ab85e4dfd9 >--- /dev/null >+++ b/LayoutTests/css3/color-filters/color-filter-gradients-expected.html >@@ -0,0 +1,23 @@ >+<!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: 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> >diff --git a/LayoutTests/css3/color-filters/color-filter-gradients.html b/LayoutTests/css3/color-filters/color-filter-gradients.html >new file mode 100644 >index 0000000000000000000000000000000000000000..4e1cae9a77fb744c3be17f46de26e4c8eac34ac8 >--- /dev/null >+++ b/LayoutTests/css3/color-filters/color-filter-gradients.html >@@ -0,0 +1,30 @@ >+<!DOCTYPE html> >+<html> >+ <head> >+ <title>CSS Test: color-filter affects gradients</title> >+ <link rel="author" title="Apple" href="http://www.apple.com/"> >+ <link rel="match" href="color-filter-grayscale-expected.html"> >+ >+ <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>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185080
: 338998