Diff
Modified: trunk/LayoutTests/ChangeLog (287309 => 287310)
--- trunk/LayoutTests/ChangeLog 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/LayoutTests/ChangeLog 2021-12-21 12:42:19 UTC (rev 287310)
@@ -1,3 +1,20 @@
+2021-12-21 Sam Weinig <wei...@apple.com>
+
+ Add support for premultiplied alpha interpolated gradients and defaulted off option to use them for CSS Gradients
+ https://bugs.webkit.org/show_bug.cgi?id=234492
+
+ Reviewed by Simon Fraser.
+
+ Add and update tests for gradients with alpha now that we have support for premultiplied interpolation.
+ By default, the tests now enable premultiplied interpolation (since it is an experimental feature) so
+ to continue testing the old path, the setting must be explicitly disabled.
+
+ * fast/gradients/alpha-premultiplied-expected.html: Added.
+ * fast/gradients/alpha-premultiplied.html: Added.
+ * fast/gradients/conic-gradient-alpha-expected.html:
+ * fast/gradients/conic-gradient-alpha-unpremultiplied-expected.html: Added.
+ * fast/gradients/conic-gradient-alpha-unpremultiplied.html: Added.
+
2021-12-20 Jon Lee <jon...@apple.com>
Unreviewed, garden GPU Process test expectations
Added: trunk/LayoutTests/fast/gradients/alpha-premultiplied-expected.html (0 => 287310)
--- trunk/LayoutTests/fast/gradients/alpha-premultiplied-expected.html (rev 0)
+++ trunk/LayoutTests/fast/gradients/alpha-premultiplied-expected.html 2021-12-21 12:42:19 UTC (rev 287310)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+
+ #linear {
+ background-image: linear-gradient(transparent, rgb(0, 0, 255));
+ }
+
+ #linear-repeating {
+ background-image: repeating-linear-gradient(transparent, rgb(0, 0, 255) 25px);
+ }
+
+ #radial {
+ background-image: radial-gradient(transparent, rgb(0, 0, 255));
+ }
+
+ #radial-repeating {
+ background-image: repeating-radial-gradient(transparent, rgb(0, 0, 255) 25px);
+ }
+
+ #conic {
+ background-image: conic-gradient(transparent, rgb(0, 0, 255));
+ }
+
+ #conic-repeating {
+ background-image: repeating-conic-gradient(transparent, rgb(0, 0, 255) 30deg);
+ }
+
+</style>
+</head>
+<body>
+<div id="linear"></div>
+<div id="linear-repeating"></div>
+<div id="radial"></div>
+<div id="radial-repeating"></div>
+<div id="conic"></div>
+<div id="conic-repeating"></div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/gradients/alpha-premultiplied.html (0 => 287310)
--- trunk/LayoutTests/fast/gradients/alpha-premultiplied.html (rev 0)
+++ trunk/LayoutTests/fast/gradients/alpha-premultiplied.html 2021-12-21 12:42:19 UTC (rev 287310)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+
+ #linear {
+ background-image: linear-gradient(rgba(255, 0, 255, 0), rgb(0, 0, 255));
+ }
+
+ #linear-repeating {
+ background-image: repeating-linear-gradient(rgba(255, 0, 255, 0), rgb(0, 0, 255) 25px);
+ }
+
+ #radial {
+ background-image: radial-gradient(rgba(255, 0, 255, 0), rgb(0, 0, 255));
+ }
+
+ #radial-repeating {
+ background-image: repeating-radial-gradient(rgba(255, 0, 255, 0), rgb(0, 0, 255) 25px);
+ }
+
+ #conic {
+ background-image: conic-gradient(rgba(255, 0, 255, 0), rgb(0, 0, 255));
+ }
+
+ #conic-repeating {
+ background-image: repeating-conic-gradient(rgba(255, 0, 255, 0), rgb(0, 0, 255) 30deg);
+ }
+
+</style>
+</head>
+<body>
+<div id="linear"></div>
+<div id="linear-repeating"></div>
+<div id="radial"></div>
+<div id="radial-repeating"></div>
+<div id="conic"></div>
+<div id="conic-repeating"></div>
+</body>
+</html>
Modified: trunk/LayoutTests/fast/gradients/conic-gradient-alpha-expected.html (287309 => 287310)
--- trunk/LayoutTests/fast/gradients/conic-gradient-alpha-expected.html 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/LayoutTests/fast/gradients/conic-gradient-alpha-expected.html 2021-12-21 12:42:19 UTC (rev 287310)
@@ -10,27 +10,27 @@
#topleft {
width: 0;
height: 0;
- border-left: 100px solid rgb(64,87,64);
+ border-left: 100px solid rgb(64,64,64);
border-top: 100px solid rgb(32,32,32);
}
#topright {
width: 0;
height: 0;
- border-right: 100px solid rgb(225,246,225);
- border-top: 100px solid rgb(254,254,254);
+ border-right: 100px solid rgb(224,224,224);
+ border-top: 100px solid rgb(255,255,255);
}
#bottomleft {
clear: left;
width: 0;
height: 0;
- border-left: 100px solid rgb(96,135,96);
- border-bottom: 100px solid rgb(128,175,128);
+ border-left: 100px solid rgb(96,96,96);
+ border-bottom: 100px solid rgb(128,128,128);
}
#bottomright {
width: 0;
height: 0;
- border-right: 100px solid rgb(193,231,193);
- border-bottom: 100px solid rgb(160,207,160);
+ border-right: 100px solid rgb(192,192,192);
+ border-bottom: 100px solid rgb(160,160,160);
}
.box {
position: absolute;
Copied: trunk/LayoutTests/fast/gradients/conic-gradient-alpha-unpremultiplied-expected.html (from rev 287309, trunk/LayoutTests/fast/gradients/conic-gradient-alpha-expected.html) (0 => 287310)
--- trunk/LayoutTests/fast/gradients/conic-gradient-alpha-unpremultiplied-expected.html (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-gradient-alpha-unpremultiplied-expected.html 2021-12-21 12:42:19 UTC (rev 287310)
@@ -0,0 +1,67 @@
+<html><!-- webkit-test-runner [ CSSGradientPremultipliedAlphaInterpolationEnabled=false ] -->
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 200px;
+ float: left;
+ }
+ /*tweak this until it's actually right... */
+ #topleft {
+ width: 0;
+ height: 0;
+ border-left: 100px solid rgb(64,87,64);
+ border-top: 100px solid rgb(32,32,32);
+ }
+ #topright {
+ width: 0;
+ height: 0;
+ border-right: 100px solid rgb(225,246,225);
+ border-top: 100px solid rgb(254,254,254);
+ }
+ #bottomleft {
+ clear: left;
+ width: 0;
+ height: 0;
+ border-left: 100px solid rgb(96,135,96);
+ border-bottom: 100px solid rgb(128,175,128);
+ }
+ #bottomright {
+ width: 0;
+ height: 0;
+ border-right: 100px solid rgb(193,231,193);
+ border-bottom: 100px solid rgb(160,207,160);
+ }
+ .box {
+ position: absolute;
+ }
+ .x {
+ position: absolute;
+ -webkit-clip-path: polygon(0% 0%, 0% 10%, 40% 50%, 0% 90%, 0% 100%, 10% 100%, 50% 60%, 90% 100%, 100% 100%, 100% 90%, 60% 50%, 100% 10%, 100% 0%, 90% 0%, 50% 40%, 10% 0%);
+ }
+ #x {
+ background-color:white;
+ }
+ .plus {
+ position: absolute;
+ -webkit-clip-path: polygon(45% 0%, 55% 0%, 55% 45%, 100% 45%, 100% 55%, 55% 55%, 55% 100%, 45% 100%, 45% 55%, 0% 55%, 0% 45%, 45% 45%);
+ }
+ #plus {
+ background-color:white;
+ }
+
+ </style>
+</head>
+<body>
+ <div>
+ <div class="box">
+ <div id="topleft"></div>
+ <div id="topright"></div>
+ <div id="bottomleft"></div>
+ <div id="bottomright"></div>
+ </div>
+ <div id="x" class="x"></div>
+ <div id="plus" class="plus"></div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/gradients/conic-gradient-alpha-unpremultiplied.html (0 => 287310)
--- trunk/LayoutTests/fast/gradients/conic-gradient-alpha-unpremultiplied.html (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-gradient-alpha-unpremultiplied.html 2021-12-21 12:42:19 UTC (rev 287310)
@@ -0,0 +1,56 @@
+<html><!-- webkit-test-runner [ CSSGradientPremultipliedAlphaInterpolationEnabled=false ] -->
+<head>
+<style>
+ svg {
+ width: 800px;
+ display: none;
+ }
+ div {
+ width: 200px;
+ height: 200px;
+ }
+ #gradient {
+ position: absolute;
+ width: 200px;
+ height: 200px;
+ background-image: conic-gradient(rgba(0,255,0,0), black);
+ filter: url(#posterize);
+ }
+
+ .x {
+ position: absolute;
+ -webkit-clip-path: polygon(0% 0%, 0% 10%, 40% 50%, 0% 90%, 0% 100%, 10% 100%, 50% 60%, 90% 100%, 100% 100%, 100% 90%, 60% 50%, 100% 10%, 100% 0%, 90% 0%, 50% 40%, 10% 0%);
+ }
+ #x {
+ background-color:white;
+ }
+ .plus {
+ position: absolute;
+ -webkit-clip-path: polygon(45% 0%, 55% 0%, 55% 45%, 100% 45%, 100% 55%, 55% 55%, 55% 100%, 45% 100%, 45% 55%, 0% 55%, 0% 45%, 45% 45%);
+ }
+ #plus {
+ background-color:white;
+ }
+</style>
+</head>
+
+<body>
+<svg viewBox="0 0 700 100">
+<defs>
+ <filter id="posterize" filterUnits="objectBoundingBox" primitiveUnits="objectBoundingBox">
+ <feComponentTransfer>
+ <feFuncR type="discrete" tableValues="0 0.125 0.25 0.375 0.5 0.625 0.75 0.875"/>
+ <feFuncG type="discrete" tableValues="0 0.125 0.25 0.375 0.5 0.625 0.75 0.875"/>
+ <feFuncB type="discrete" tableValues="0 0.125 0.25 0.375 0.5 0.625 0.75 0.875"/>
+ <feFuncA type="discrete" tableValues="0 0.125 0.25 0.375 0.5 0.625 0.75 0.875"/>
+ </feComponentTransfer>
+ </filter>
+</defs>
+</svg>
+
+<div>
+ <div id="gradient"></div>
+ <div id="x" class="x"></div>
+ <div id="plus" class="plus"></div>
+</div>
+</html>
Modified: trunk/LayoutTests/platform/glib/TestExpectations (287309 => 287310)
--- trunk/LayoutTests/platform/glib/TestExpectations 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/LayoutTests/platform/glib/TestExpectations 2021-12-21 12:42:19 UTC (rev 287310)
@@ -489,7 +489,9 @@
# fast/gradients are Skip in the top level Expectation. When fixing, change this to
# Pass instead of removing this line.
+webkit.org/b/214259 fast/gradients/conic-gradient-alpha-unpremultiplied.html [ ImageOnlyFailure ]
webkit.org/b/214259 fast/gradients/conic-gradient-alpha.html [ ImageOnlyFailure ]
+webkit.org/b/234492 fast/gradients/alpha-premultiplied.html [ ImageOnlyFailure ]
webkit.org/b/169988 css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-add.html [ ImageOnlyFailure ]
webkit.org/b/169988 css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection.html [ ImageOnlyFailure ]
Modified: trunk/LayoutTests/platform/win/TestExpectations (287309 => 287310)
--- trunk/LayoutTests/platform/win/TestExpectations 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/LayoutTests/platform/win/TestExpectations 2021-12-21 12:42:19 UTC (rev 287310)
@@ -295,6 +295,7 @@
fast/gradients/conic-extended-stops.html [ Skip ]
fast/gradients/conic-from-angle.html [ Skip ]
fast/gradients/conic-repeating-last-stop.html [ Skip ]
+fast/gradients/conic-gradient-alpha-unpremultiplied.html [ Skip ]
fast/gradients/conic-gradient-alpha.html [ Skip ]
fast/gradients/conic-gradient-extended-stops.html [ Skip ]
fast/gradients/conic-gradient.html [ Skip ]
Modified: trunk/Source/WTF/ChangeLog (287309 => 287310)
--- trunk/Source/WTF/ChangeLog 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WTF/ChangeLog 2021-12-21 12:42:19 UTC (rev 287310)
@@ -1,3 +1,13 @@
+2021-12-21 Sam Weinig <wei...@apple.com>
+
+ Add support for premultiplied alpha interpolated gradients and defaulted off option to use them for CSS Gradients
+ https://bugs.webkit.org/show_bug.cgi?id=234492
+
+ Reviewed by Simon Fraser.
+
+ * Scripts/Preferences/WebPreferencesExperimental.yaml:
+ Add a new experimental setting to enable premultiplied alpha CSS gradients.
+
2021-12-21 Yusuke Suzuki <ysuz...@apple.com>
[WTF] Remove RefCountedArray and use RefCountedFixedVector
Modified: trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml (287309 => 287310)
--- trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml 2021-12-21 12:42:19 UTC (rev 287310)
@@ -284,6 +284,18 @@
WebCore:
default: false
+CSSGradientPremultipliedAlphaInterpolationEnabled:
+ type: bool
+ humanReadableName: "CSS Gradient Premultiplied Alpha Interpolation"
+ humanReadableDescription: "Enable premultiplied alpha interpolated CSS gradients"
+ defaultValue:
+ WebKitLegacy:
+ default: false
+ WebKit:
+ default: false
+ WebCore:
+ default: false
+
# FIXME: This is enabled when ENABLE(EXPERIMENTAL_FEATURES) is true in WebKit2. Perhaps we should consider using that for WebKitLegacy as well.
CSSIndividualTransformPropertiesEnabled:
type: bool
Modified: trunk/Source/WebCore/ChangeLog (287309 => 287310)
--- trunk/Source/WebCore/ChangeLog 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/ChangeLog 2021-12-21 12:42:19 UTC (rev 287310)
@@ -1,3 +1,110 @@
+2021-12-21 Sam Weinig <wei...@apple.com>
+
+ Add support for premultiplied alpha interpolated gradients and defaulted off option to use them for CSS Gradients
+ https://bugs.webkit.org/show_bug.cgi?id=234492
+
+ Reviewed by Simon Fraser.
+
+ Tests: fast/gradients/alpha-premultiplied.html
+ fast/gradients/conic-gradient-alpha-unpremultiplied.html
+
+ Extracts use of CGGradientRef out of Gradient and into the new GradientRendererCG which also implements
+ a CGShadingRef based gradient drawing path. The GradientRendererCG picks which strategy, CGGradientRef
+ or CGShadingRef, based on the intepolation mode and capabilities of the underlying CoreGraphics. For
+ new enough CoreGraphics, both premultiplied and non-premultiplied alpha interpolation for sRGB output
+ are supported in the more optimizable CGGradientRef path, but on older systems we will fallback to a
+ a newly implemented CGShadingRef based implementation.
+
+ In addition to the platform level work in Gradient, this adds a new setting, CSSGradientPremultipliedAlphaInterpolationEnabled,
+ which defaults to off for now and switches what type of interpolation we use for CSS gradients. It
+ does not effect other gradient uses such as by canvas or SVG. Those will be enabled separately.
+
+ * Headers.cmake:
+ * PlatformAppleWin.cmake:
+ * PlatformMac.cmake:
+ * SourcesCocoa.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ Add new files.
+
+ * css/CSSGradientValue.cpp:
+ (WebCore::LinearGradientAdapter::normalizeStopsAndEndpointsOutsideRange):
+ (WebCore::RadialGradientAdapter::normalizeStopsAndEndpointsOutsideRange):
+ (WebCore::ConicGradientAdapter::normalizeStopsAndEndpointsOutsideRange):
+ (WebCore::CSSGradientValue::computeStops):
+ Switch to using the new interpolateColors() function from ColorInterpolation.h
+ which accurately takes into account the current interpolation mode. These
+ blends now match what the created gradient does.
+
+ * css/parser/CSSParserContext.cpp:
+ * css/parser/CSSParserContext.h:
+ Add support for querying CSSGradientPremultipliedAlphaInterpolationEnabled from the CSS parser.
+
+ * css/parser/CSSPropertyParserHelpers.cpp:
+ (WebCore::CSSPropertyParserHelpers::gradientAlphaPremultiplication):
+ (WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradient):
+ (WebCore::CSSPropertyParserHelpers::consumeDeprecatedRadialGradient):
+ (WebCore::CSSPropertyParserHelpers::consumeRadialGradient):
+ (WebCore::CSSPropertyParserHelpers::consumeLinearGradient):
+ (WebCore::CSSPropertyParserHelpers::consumeConicGradient):
+ Depending on how CSSGradientPremultipliedAlphaInterpolationEnabled is set, use either premultiplied
+ or non-premultiplied interpolation for CSS gradients.
+
+ * platform/graphics/ColorComponents.h:
+ (WebCore::ColorComponents::size const):
+ Add size() function for use by the shading strategy.
+
+ * platform/graphics/ColorInterpolation.h:
+ (WebCore::preInterpolationNormalizationForComponent):
+ (WebCore::preInterpolationNormalization):
+ (WebCore::postInterpolationNormalizationForComponent):
+ (WebCore::postInterpolationNormalization):
+ (WebCore::interpolateColorComponents):
+ Update to use the name InterpolationMethodColorSpace consistenly for the color space part of the
+ interpolation method.
+
+ (WebCore::interpolateColors):
+ Add helper which takes and returns Color objects rather than the strongly typed color types,
+ automatically converting to the appropriate interpolation color space based on the provided
+ ColorInterpolationMethod object.
+
+ * platform/graphics/Gradient.h:
+ * platform/graphics/GradientColorStop.h: Added.
+ Move ColorStop and ColorStopVector defintions to new GradientColorStop file, but keep the
+ old nested names via using directives. This is needed to make using the ColorStopVector
+ from GradientRendererCG (which we also want to use in Gradient.h) possible without redeclaration.
+ Replace CGGradientRef member with GradientRendererCG which allows choosing between either
+ a CGGradientRef based implementation or CGShadingRef based one.
+
+ * platform/graphics/cg/GradientCG.cpp:
+ Update to use the GradientRendererCG rathern than a CGGradientRef directly, calling into it
+ to do the actual draw calls.
+
+ * platform/graphics/cg/GradientRendererCG.h: Added.
+ * platform/graphics/cg/GradientRendererCG.cpp: Added.
+ (WebCore::GradientRendererCG::pickStrategy const):
+ Central function to choose which strategy to use based on system capabilities and interpolation needs.
+
+ (WebCore::GradientRendererCG::makeGradient const):
+ Moved from GradientCG.cpp. Removed the CGGradientCreateWithColors() path, as we can always use the
+ more efficient CGGradientCreateWithColorComponents() by doing the conversion to extended sRGB ourselves.
+ Also adds use of the kCGGradientInterpolatesPremultiplied option on supported systems to tell CoreGraphics
+ to use premulitplied interpolation.
+
+ (WebCore::shadingFunction):
+ Core function used by CGShadingRef to interpolate between color stops. Templatized to allow for optimized
+ versions for every ColorInterpolationColorSpace / AlphaPremultiplication pair.
+
+ (WebCore::GradientRendererCG::makeShading const):
+ Builds shading strategy by converting all color stops to the interpolation color space, adding stops at
+ 0 and 1 if necessary, and creating the CGFunctionRef that the shading will own. To avoid a circular
+ reference, the GradientRendererCG itself is not what the CGFunctionRef retains, but rather a subobject
+ Data, which is a peer to the CGFunctionRef.
+
+ (WebCore::GradientRendererCG::drawLinearGradient):
+ (WebCore::GradientRendererCG::drawRadialGradient):
+ (WebCore::GradientRendererCG::drawConicGradient):
+ Draw the gradient or shading based on the strategy selected at construction.
+
2021-12-21 Tim Nguyen <n...@apple.com>
<dialog> should generate implied end tags
Modified: trunk/Source/WebCore/Headers.cmake (287309 => 287310)
--- trunk/Source/WebCore/Headers.cmake 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/Headers.cmake 2021-12-21 12:42:19 UTC (rev 287310)
@@ -1462,6 +1462,7 @@
platform/graphics/GlyphMetricsMap.h
platform/graphics/GlyphPage.h
platform/graphics/Gradient.h
+ platform/graphics/GradientColorStop.h
platform/graphics/GraphicsContext.h
platform/graphics/GraphicsContextFlushIdentifier.h
platform/graphics/GraphicsContextGL.h
Modified: trunk/Source/WebCore/PAL/ChangeLog (287309 => 287310)
--- trunk/Source/WebCore/PAL/ChangeLog 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/PAL/ChangeLog 2021-12-21 12:42:19 UTC (rev 287310)
@@ -1,3 +1,13 @@
+2021-12-21 Sam Weinig <wei...@apple.com>
+
+ Add support for premultiplied alpha interpolated gradients and defaulted off option to use them for CSS Gradients
+ https://bugs.webkit.org/show_bug.cgi?id=234492
+
+ Reviewed by Simon Fraser.
+
+ * pal/spi/cg/CoreGraphicsSPI.h:
+ Add forwards for creating conic shadings and enabling premultiplied alpha interpolation for gradients.
+
2021-12-20 Wenson Hsieh <wenson_hs...@apple.com>
Add PAL soft linking headers for CoreML and NaturalLanguage frameworks
Modified: trunk/Source/WebCore/PAL/pal/spi/cg/CoreGraphicsSPI.h (287309 => 287310)
--- trunk/Source/WebCore/PAL/pal/spi/cg/CoreGraphicsSPI.h 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/PAL/pal/spi/cg/CoreGraphicsSPI.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -41,8 +41,9 @@
#include <CoreGraphics/CGContextDelegatePrivate.h>
#include <CoreGraphics/CGFontCache.h>
#include <CoreGraphics/CGPathPrivate.h>
+#include <CoreGraphics/CGShadingPrivate.h>
+#include <CoreGraphics/CGStylePrivate.h>
#include <CoreGraphics/CoreGraphicsPrivate.h>
-#include <CoreGraphics/CGStylePrivate.h>
#if PLATFORM(MAC)
#include <CoreGraphics/CGAccessibility.h>
@@ -323,7 +324,17 @@
void CGContextDrawConicGradient(CGContextRef, CGGradientRef, CGPoint center, CGFloat angle);
void CGPathAddUnevenCornersRoundedRect(CGMutablePathRef, const CGAffineTransform *, CGRect, const CGSize corners[4]);
bool CGFontRenderingGetFontSmoothingDisabled(void);
+CGShadingRef CGShadingCreateConic(CGColorSpaceRef, CGPoint center, CGFloat angle, CGFunctionRef);
+#if HAVE(CORE_GRAPHICS_GRADIENT_CREATE_WITH_OPTIONS)
+CGGradientRef CGGradientCreateWithColorComponentsAndOptions(CGColorSpaceRef, const CGFloat*, const CGFloat*, size_t, CFDictionaryRef);
+CGGradientRef CGGradientCreateWithColorsAndOptions(CGColorSpaceRef, CFArrayRef, const CGFloat*, CFDictionaryRef);
+#endif
+
+#if HAVE(CORE_GRAPHICS_PREMULTIPLIED_INTERPOLATION_GRADIENT)
+extern const CFStringRef kCGGradientInterpolatesPremultiplied;
+#endif
+
#endif // PLATFORM(COCOA)
#if PLATFORM(WIN)
Modified: trunk/Source/WebCore/PlatformAppleWin.cmake (287309 => 287310)
--- trunk/Source/WebCore/PlatformAppleWin.cmake 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/PlatformAppleWin.cmake 2021-12-21 12:42:19 UTC (rev 287310)
@@ -131,6 +131,7 @@
platform/graphics/cg/FloatRectCG.cpp
platform/graphics/cg/FloatSizeCG.cpp
platform/graphics/cg/GradientCG.cpp
+ platform/graphics/cg/GradientRendererCG.cpp
platform/graphics/cg/GraphicsContextGLCG.cpp
platform/graphics/cg/GraphicsContextCG.cpp
platform/graphics/cg/IOSurfacePool.cpp
@@ -182,6 +183,7 @@
platform/graphics/ca/win/PlatformCALayerWin.h
platform/graphics/cg/ColorSpaceCG.h
+ platform/graphics/cg/GradientRendererCG.h
platform/graphics/cg/GraphicsContextCG.h
platform/graphics/cg/IOSurfacePool.h
platform/graphics/cg/ImageBufferCGBackend.h
Modified: trunk/Source/WebCore/PlatformMac.cmake (287309 => 287310)
--- trunk/Source/WebCore/PlatformMac.cmake 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/PlatformMac.cmake 2021-12-21 12:42:19 UTC (rev 287310)
@@ -291,6 +291,7 @@
platform/graphics/cg/FloatRectCG.cpp
platform/graphics/cg/FloatSizeCG.cpp
platform/graphics/cg/GradientCG.cpp
+ platform/graphics/cg/GradientRendererCG.cpp
platform/graphics/cg/GraphicsContextGLCG.cpp
platform/graphics/cg/GraphicsContextCG.cpp
platform/graphics/cg/IOSurfacePool.cpp
Modified: trunk/Source/WebCore/SourcesCocoa.txt (287309 => 287310)
--- trunk/Source/WebCore/SourcesCocoa.txt 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/SourcesCocoa.txt 2021-12-21 12:42:19 UTC (rev 287310)
@@ -348,6 +348,7 @@
platform/graphics/cg/FloatRectCG.cpp
platform/graphics/cg/FloatSizeCG.cpp
platform/graphics/cg/GradientCG.cpp
+platform/graphics/cg/GradientRendererCG.cpp
platform/graphics/cg/GraphicsContextCG.cpp
platform/graphics/cg/GraphicsContextGLCG.cpp
platform/graphics/cg/IOSurfacePool.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (287309 => 287310)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-21 12:42:19 UTC (rev 287310)
@@ -4087,6 +4087,8 @@
BC124F000C26447A009E2349 /* JSBarProp.h in Headers */ = {isa = PBXBuildFile; fileRef = BC124EFE0C26447A009E2349 /* JSBarProp.h */; };
BC128A73137C867C00CAC845 /* RenderGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = BC128A72137C867C00CAC845 /* RenderGrid.h */; };
BC14028B0E83680800319717 /* ScrollbarThemeComposite.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1402890E83680800319717 /* ScrollbarThemeComposite.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC19CDF2276FFC6D0053F734 /* GradientRendererCG.h in Headers */ = {isa = PBXBuildFile; fileRef = BC19CDF0276FFB260053F734 /* GradientRendererCG.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC19CDF4277106390053F734 /* GradientColorStop.h in Headers */ = {isa = PBXBuildFile; fileRef = BC19CDF3277106390053F734 /* GradientColorStop.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC1A7D9818FCB5B000421879 /* RenderMultiColumnSpannerPlaceholder.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1A7D9618FCB5B000421879 /* RenderMultiColumnSpannerPlaceholder.h */; };
BC2272870E82E70700E7F975 /* StyleReflection.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2272860E82E70700E7F975 /* StyleReflection.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC2272A20E82E87C00E7F975 /* CursorData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2272A10E82E87C00E7F975 /* CursorData.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -15134,6 +15136,9 @@
BC128B00137C8D4600CAC845 /* RenderGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderGrid.cpp; sourceTree = "<group>"; };
BC1402880E83680800319717 /* ScrollbarThemeComposite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarThemeComposite.cpp; sourceTree = "<group>"; };
BC1402890E83680800319717 /* ScrollbarThemeComposite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeComposite.h; sourceTree = "<group>"; };
+ BC19CDEF276FFB260053F734 /* GradientRendererCG.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GradientRendererCG.cpp; sourceTree = "<group>"; };
+ BC19CDF0276FFB260053F734 /* GradientRendererCG.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GradientRendererCG.h; sourceTree = "<group>"; };
+ BC19CDF3277106390053F734 /* GradientColorStop.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GradientColorStop.h; sourceTree = "<group>"; };
BC1A7D9518FCB5B000421879 /* RenderMultiColumnSpannerPlaceholder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMultiColumnSpannerPlaceholder.cpp; sourceTree = "<group>"; };
BC1A7D9618FCB5B000421879 /* RenderMultiColumnSpannerPlaceholder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMultiColumnSpannerPlaceholder.h; sourceTree = "<group>"; };
BC20FB7E0C0E8E6C00D1447F /* JSDeprecatedCSSOMValueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSDeprecatedCSSOMValueCustom.cpp; sourceTree = "<group>"; };
@@ -28571,6 +28576,8 @@
B275352C0B053814002CE64F /* FloatRectCG.cpp */,
B275352D0B053814002CE64F /* FloatSizeCG.cpp */,
BC53C60A0DA56CF10021EB5D /* GradientCG.cpp */,
+ BC19CDEF276FFB260053F734 /* GradientRendererCG.cpp */,
+ BC19CDF0276FFB260053F734 /* GradientRendererCG.h */,
B2ED97700B1F55CE00257D0F /* GraphicsContextCG.cpp */,
934907E3125BBBC8007F23A0 /* GraphicsContextCG.h */,
6E21C6C11126339900A7BE02 /* GraphicsContextGLCG.cpp */,
@@ -28780,6 +28787,7 @@
0873B86A136064EA00A522C2 /* GlyphPage.h */,
BC53C6070DA56C570021EB5D /* Gradient.cpp */,
BC53C5F40DA56B920021EB5D /* Gradient.h */,
+ BC19CDF3277106390053F734 /* GradientColorStop.h */,
2D2FC0561460CD6F00263633 /* GradientImage.cpp */,
2D2FC0571460CD6F00263633 /* GradientImage.h */,
B2A015920AF6CD53006BCE0E /* GraphicsContext.cpp */,
@@ -33341,6 +33349,7 @@
8378878224D8A609000D4A5B /* AudioBufferSourceOptions.h in Headers */,
FD31607C12B026F700C1A359 /* AudioBus.h in Headers */,
FD31607E12B026F700C1A359 /* AudioChannel.h in Headers */,
+ BC19CDF2276FFC6D0053F734 /* GradientRendererCG.h in Headers */,
CD3EEF3A25799F88006563BB /* AudioConfiguration.h in Headers */,
FD31600512B0267600C1A359 /* AudioContext.h in Headers */,
E785D96224B7F7350014DB21 /* AudioContextLatencyCategory.h in Headers */,
@@ -34897,6 +34906,7 @@
A5B81CAD1FAA44620037D1E6 /* InspectorDOMStorageAgent.h in Headers */,
994C603A253A277300BDF060 /* InspectorFrontendAPIDispatcher.h in Headers */,
F344C7141125B82C00F26EEE /* InspectorFrontendClient.h in Headers */,
+ BC19CDF4277106390053F734 /* GradientColorStop.h in Headers */,
F344C75311294D9D00F26EEE /* InspectorFrontendClientLocal.h in Headers */,
7A0E770F10C00A8800A0276E /* InspectorFrontendHost.h in Headers */,
7A54858014E02D51006AE05A /* InspectorHistory.h in Headers */,
Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (287309 => 287310)
--- trunk/Source/WebCore/css/CSSGradientValue.cpp 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp 2021-12-21 12:42:19 UTC (rev 287310)
@@ -26,11 +26,10 @@
#include "config.h"
#include "CSSGradientValue.h"
-#include "AnimationUtilities.h"
#include "CSSCalcValue.h"
#include "CSSToLengthConversionData.h"
#include "CSSValueKeywords.h"
-#include "ColorBlending.h"
+#include "ColorInterpolation.h"
#include "GradientImage.h"
#include "NodeRenderStyle.h"
#include "Pair.h"
@@ -138,7 +137,7 @@
}
float maxExtent(float, float) const { return 1; }
- void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops)
+ void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops, ColorInterpolationMethod)
{
float firstOffset = *stops.first().offset;
float lastOffset = *stops.last().offset;
@@ -181,7 +180,7 @@
return 1;
}
- void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops)
+ void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops, ColorInterpolationMethod colorInterpolationMethod)
{
auto numStops = stops.size();
@@ -205,8 +204,7 @@
float nextOffset = *stops[firstZeroOrGreaterIndex].offset;
float interStopProportion = -prevOffset / (nextOffset - prevOffset);
- // FIXME: when we interpolate gradients using premultiplied colors, this should do premultiplication.
- Color blendedColor = blend(stops[firstZeroOrGreaterIndex - 1].color, stops[firstZeroOrGreaterIndex].color, { interStopProportion });
+ auto blendedColor = interpolateColors(colorInterpolationMethod, stops[firstZeroOrGreaterIndex - 1].color, 1.0f - interStopProportion, stops[firstZeroOrGreaterIndex].color, interStopProportion);
// Clamp the positions to 0 and set the color.
for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i) {
@@ -236,7 +234,7 @@
float gradientLength() const { return 1; }
float maxExtent(float, float) const { return 1; }
- void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops)
+ void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops, ColorInterpolationMethod colorInterpolationMethod)
{
size_t numStops = stops.size();
size_t lastStopIndex = numStops - 1;
@@ -256,8 +254,7 @@
float nextOffset = *stops[index].offset;
float interStopProportion = -previousOffset / (nextOffset - previousOffset);
- // FIXME: when we interpolate gradients using premultiplied colors, this should do premultiplication.
- Color blendedColor = blend(stops[index - 1].color, stops[index].color, { interStopProportion });
+ auto blendedColor = interpolateColors(colorInterpolationMethod, stops[index - 1].color, 1.0f - interStopProportion, stops[index].color, interStopProportion);
// Clamp the positions to 0 and set the color.
for (size_t i = 0; i < index; ++i) {
@@ -286,8 +283,7 @@
float nextOffset = *stops[index + 1].offset;
float interStopProportion = (1 - previousOffset) / (nextOffset - previousOffset);
- // FIXME: when we interpolate gradients using premultiplied colors, this should do premultiplication.
- Color blendedColor = blend(stops[index].color, stops[index + 1].color, { interStopProportion });
+ auto blendedColor = interpolateColors(colorInterpolationMethod, stops[index].color, 1.0f - interStopProportion, stops[index + 1].color, interStopProportion);
// Clamp the positions to 1 and set the color.
for (size_t i = index + 1; i < numStops; ++i) {
@@ -485,8 +481,7 @@
for (size_t y = 0; y < 9; ++y) {
float relativeOffset = (*newStops[y].offset - offset1) / (offset2 - offset1);
float multiplier = std::pow(relativeOffset, std::log(.5f) / std::log(midpoint));
- // FIXME: Why not premultiply here?
- newStops[y].color = blendWithoutPremultiply(color1, color2, { multiplier });
+ newStops[y].color = interpolateColors(m_colorInterpolationMethod, color1, 1.0f - multiplier, color2, multiplier);
}
stops.remove(x);
@@ -557,7 +552,7 @@
// If the gradient goes outside the 0-1 range, normalize it by moving the endpoints, and adjusting the stops.
if (stops.size() > 1 && (*stops.first().offset < 0 || *stops.last().offset > 1))
- gradientAdapter.normalizeStopsAndEndpointsOutsideRange(stops);
+ gradientAdapter.normalizeStopsAndEndpointsOutsideRange(stops, m_colorInterpolationMethod);
Gradient::ColorStopVector result;
result.reserveInitialCapacity(stops.size());
Modified: trunk/Source/WebCore/css/parser/CSSParserContext.cpp (287309 => 287310)
--- trunk/Source/WebCore/css/parser/CSSParserContext.cpp 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/css/parser/CSSParserContext.cpp 2021-12-21 12:42:19 UTC (rev 287310)
@@ -106,10 +106,11 @@
, hasPseudoClassEnabled { document.settings().hasPseudoClassEnabled() }
, cascadeLayersEnabled { document.settings().cssCascadeLayersEnabled() }
, containerQueriesEnabled { document.settings().cssContainerQueriesEnabled() }
+ , overflowClipEnabled { document.settings().overflowClipEnabled() }
+ , gradientPremultipliedAlphaInterpolationEnabled { document.settings().cssGradientPremultipliedAlphaInterpolationEnabled() }
#if ENABLE(ATTACHMENT_ELEMENT)
, attachmentEnabled { RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() }
#endif
- , overflowClipEnabled { document.settings().overflowClipEnabled() }
{
}
@@ -153,10 +154,11 @@
&& a.hasPseudoClassEnabled == b.hasPseudoClassEnabled
&& a.cascadeLayersEnabled == b.cascadeLayersEnabled
&& a.containerQueriesEnabled == b.containerQueriesEnabled
+ && a.overflowClipEnabled == b.overflowClipEnabled
+ && a.gradientPremultipliedAlphaInterpolationEnabled == b.gradientPremultipliedAlphaInterpolationEnabled
#if ENABLE(ATTACHMENT_ELEMENT)
&& a.attachmentEnabled == b.attachmentEnabled
#endif
- && a.overflowClipEnabled == b.overflowClipEnabled
;
}
@@ -193,12 +195,13 @@
| context.hasPseudoClassEnabled << 22
| context.cascadeLayersEnabled << 23
| context.containerQueriesEnabled << 24
+ | context.overflowClipEnabled << 25
+ | context.gradientPremultipliedAlphaInterpolationEnabled << 26
#if ENABLE(ATTACHMENT_ELEMENT)
- | context.attachmentEnabled << 25
+ | context.attachmentEnabled << 27
#endif
- | context.overflowClipEnabled << 26
- | context.accentColorEnabled << 27
- | context.mode << 28; // This is multiple bits, so keep it last.
+ | context.accentColorEnabled << 28
+ | context.mode << 29; // This is multiple bits, so keep it last.
add(hasher, context.baseURL, context.charset, bits);
}
Modified: trunk/Source/WebCore/css/parser/CSSParserContext.h (287309 => 287310)
--- trunk/Source/WebCore/css/parser/CSSParserContext.h 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/css/parser/CSSParserContext.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -85,6 +85,8 @@
bool hasPseudoClassEnabled { false };
bool cascadeLayersEnabled { false };
bool containerQueriesEnabled { false };
+ bool overflowClipEnabled { false };
+ bool gradientPremultipliedAlphaInterpolationEnabled { false };
// RuntimeEnabledFeatures.
#if ENABLE(ATTACHMENT_ELEMENT)
@@ -91,8 +93,6 @@
bool attachmentEnabled { false };
#endif
- bool overflowClipEnabled { false };
-
CSSParserContext(CSSParserMode, const URL& baseURL = URL());
WEBCORE_EXPORT CSSParserContext(const Document&, const URL& baseURL = URL(), const String& charset = emptyString());
bool isPropertyRuntimeDisabled(CSSPropertyID) const;
Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (287309 => 287310)
--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2021-12-21 12:42:19 UTC (rev 287310)
@@ -2439,24 +2439,6 @@
return result;
}
-// After interpolation, if the color is in the HWB or HSL color space, it needs to be canonicalized back to sRGB as
-// is done at parse time.
-
-template<typename ColorType> Color makeCanonicalColor(ColorType color)
-{
- return color;
-}
-
-template<> Color makeCanonicalColor<HWBA<float>>(HWBA<float> color)
-{
- return convertColor<SRGBA<uint8_t>>(color);
-}
-
-template<> Color makeCanonicalColor<HSLA<float>>(HSLA<float> color)
-{
- return convertColor<SRGBA<uint8_t>>(color);
-}
-
template<typename InterpolationMethod> static Color mixColorComponentsUsingColorInterpolationMethod(InterpolationMethod interpolationMethod, ColorMixPercentages mixPercentages, const Color& color1, const Color& color2)
{
using ColorType = typename InterpolationMethod::ColorType;
@@ -2946,6 +2928,11 @@
return stop.color && args.atEnd();
}
+static AlphaPremultiplication gradientAlphaPremultiplication(const CSSParserContext& context)
+{
+ return context.gradientPremultipliedAlphaInterpolationEnabled ? AlphaPremultiplication::Premultiplied : AlphaPremultiplication::Unpremultiplied;
+}
+
static RefPtr<CSSValue> consumeDeprecatedGradient(CSSParserTokenRange& args, const CSSParserContext& context)
{
RefPtr<CSSGradientValue> result;
@@ -2952,9 +2939,9 @@
CSSValueID id = args.consumeIncludingWhitespace().id();
bool isDeprecatedRadialGradient = (id == CSSValueRadial);
if (isDeprecatedRadialGradient)
- result = CSSRadialGradientValue::create(NonRepeating, CSSDeprecatedRadialGradient, { ColorInterpolationMethod::SRGB { }, AlphaPremultiplication::Unpremultiplied });
+ result = CSSRadialGradientValue::create(NonRepeating, CSSDeprecatedRadialGradient, { ColorInterpolationMethod::SRGB { }, gradientAlphaPremultiplication(context) });
else if (id == CSSValueLinear)
- result = CSSLinearGradientValue::create(NonRepeating, CSSDeprecatedLinearGradient, { ColorInterpolationMethod::SRGB { }, AlphaPremultiplication::Unpremultiplied });
+ result = CSSLinearGradientValue::create(NonRepeating, CSSDeprecatedLinearGradient, { ColorInterpolationMethod::SRGB { }, gradientAlphaPremultiplication(context) });
if (!result || !consumeCommaIncludingWhitespace(args))
return nullptr;
@@ -3054,7 +3041,7 @@
static RefPtr<CSSValue> consumeDeprecatedRadialGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
{
- auto result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient, { ColorInterpolationMethod::SRGB { }, AlphaPremultiplication::Unpremultiplied });
+ auto result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient, { ColorInterpolationMethod::SRGB { }, gradientAlphaPremultiplication(context) });
auto centerCoordinate = consumeOneOrTwoValuedPositionCoordinates(args, context.mode, UnitlessQuirk::Forbid);
if (centerCoordinate && !consumeCommaIncludingWhitespace(args))
@@ -3098,7 +3085,7 @@
static RefPtr<CSSValue> consumeRadialGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
{
- RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient, { ColorInterpolationMethod::SRGB { }, AlphaPremultiplication::Unpremultiplied });
+ RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient, { ColorInterpolationMethod::SRGB { }, gradientAlphaPremultiplication(context) });
RefPtr<CSSPrimitiveValue> shape;
RefPtr<CSSPrimitiveValue> sizeKeyword;
@@ -3186,7 +3173,7 @@
static RefPtr<CSSValue> consumeLinearGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating, CSSGradientType gradientType)
{
- RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, gradientType, { ColorInterpolationMethod::SRGB { }, AlphaPremultiplication::Unpremultiplied });
+ RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, gradientType, { ColorInterpolationMethod::SRGB { }, gradientAlphaPremultiplication(context) });
bool expectComma = true;
RefPtr<CSSPrimitiveValue> angle = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
@@ -3220,7 +3207,7 @@
static RefPtr<CSSValue> consumeConicGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
{
#if ENABLE(CSS_CONIC_GRADIENTS)
- RefPtr<CSSConicGradientValue> result = CSSConicGradientValue::create(repeating, { ColorInterpolationMethod::SRGB { }, AlphaPremultiplication::Unpremultiplied });
+ RefPtr<CSSConicGradientValue> result = CSSConicGradientValue::create(repeating, { ColorInterpolationMethod::SRGB { }, gradientAlphaPremultiplication(context) });
bool expectComma = false;
if (args.peek().type() == IdentToken) {
Modified: trunk/Source/WebCore/platform/graphics/ColorComponents.h (287309 => 287310)
--- trunk/Source/WebCore/platform/graphics/ColorComponents.h 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/platform/graphics/ColorComponents.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -68,6 +68,8 @@
template<size_t Start, size_t End>
constexpr ColorComponents<T, End - Start> subset() const;
+ constexpr size_t size() const { return Size; }
+
std::array<T, N> components;
};
Modified: trunk/Source/WebCore/platform/graphics/ColorInterpolation.h (287309 => 287310)
--- trunk/Source/WebCore/platform/graphics/ColorInterpolation.h 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/platform/graphics/ColorInterpolation.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -26,6 +26,7 @@
#pragma once
#include "AlphaPremultiplication.h"
+#include "Color.h"
#include "ColorInterpolationMethod.h"
#include "ColorNormalization.h"
#include "ColorTypes.h"
@@ -36,14 +37,14 @@
std::pair<float, float> fixupHueComponentsPriorToInterpolation(HueInterpolationMethod, float, float);
-template<size_t I, AlphaPremultiplication alphaPremultiplication, typename InterpolationMethod>
-std::pair<float, float> preInterpolationNormalizationForComponent(InterpolationMethod interpolationMethod, ColorComponents<float, 4> colorComponents1, ColorComponents<float, 4> colorComponents2)
+template<size_t I, AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
+std::pair<float, float> preInterpolationNormalizationForComponent(InterpolationMethodColorSpace interpolationMethodColorSpace, ColorComponents<float, 4> colorComponents1, ColorComponents<float, 4> colorComponents2)
{
- using ColorType = typename InterpolationMethod::ColorType;
+ using ColorType = typename InterpolationMethodColorSpace::ColorType;
constexpr auto componentInfo = ColorType::Model::componentInfo;
if constexpr (componentInfo[I].type == ColorComponentType::Angle)
- return fixupHueComponentsPriorToInterpolation(interpolationMethod.hueInterpolationMethod, colorComponents1[I], colorComponents2[I]);
+ return fixupHueComponentsPriorToInterpolation(interpolationMethodColorSpace.hueInterpolationMethod, colorComponents1[I], colorComponents2[I]);
else {
if constexpr (alphaPremultiplication == AlphaPremultiplication::Premultiplied)
return { colorComponents1[I] * colorComponents1[3], colorComponents2[I] * colorComponents2[3] };
@@ -52,12 +53,12 @@
}
}
-template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethod>
-std::pair<ColorComponents<float, 4>, ColorComponents<float, 4>> preInterpolationNormalization(InterpolationMethod interpolationMethod, ColorComponents<float, 4> colorComponents1, ColorComponents<float, 4> colorComponents2)
+template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
+std::pair<ColorComponents<float, 4>, ColorComponents<float, 4>> preInterpolationNormalization(InterpolationMethodColorSpace interpolationMethodColorSpace, ColorComponents<float, 4> colorComponents1, ColorComponents<float, 4> colorComponents2)
{
- auto [colorA0, colorB0] = preInterpolationNormalizationForComponent<0, alphaPremultiplication>(interpolationMethod, colorComponents1, colorComponents2);
- auto [colorA1, colorB1] = preInterpolationNormalizationForComponent<1, alphaPremultiplication>(interpolationMethod, colorComponents1, colorComponents2);
- auto [colorA2, colorB2] = preInterpolationNormalizationForComponent<2, alphaPremultiplication>(interpolationMethod, colorComponents1, colorComponents2);
+ auto [colorA0, colorB0] = preInterpolationNormalizationForComponent<0, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents1, colorComponents2);
+ auto [colorA1, colorB1] = preInterpolationNormalizationForComponent<1, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents1, colorComponents2);
+ auto [colorA2, colorB2] = preInterpolationNormalizationForComponent<2, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents1, colorComponents2);
return {
{ colorA0, colorA1, colorA2, colorComponents1[3] },
@@ -68,10 +69,10 @@
// MARK: - Post-interpolation normalization/fixup
-template<size_t I, AlphaPremultiplication alphaPremultiplication, typename InterpolationMethod>
-float postInterpolationNormalizationForComponent(InterpolationMethod, ColorComponents<float, 4> colorComponents)
+template<size_t I, AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
+float postInterpolationNormalizationForComponent(InterpolationMethodColorSpace, ColorComponents<float, 4> colorComponents)
{
- using ColorType = typename InterpolationMethod::ColorType;
+ using ColorType = typename InterpolationMethodColorSpace::ColorType;
constexpr auto componentInfo = ColorType::Model::componentInfo;
if constexpr (componentInfo[I].type != ColorComponentType::Angle && alphaPremultiplication == AlphaPremultiplication::Premultiplied) {
@@ -82,13 +83,13 @@
return colorComponents[I];
}
-template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethod>
-ColorComponents<float, 4> postInterpolationNormalization(InterpolationMethod interpolationMethod, ColorComponents<float, 4> colorComponents)
+template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
+ColorComponents<float, 4> postInterpolationNormalization(InterpolationMethodColorSpace interpolationMethodColorSpace, ColorComponents<float, 4> colorComponents)
{
return {
- postInterpolationNormalizationForComponent<0, alphaPremultiplication>(interpolationMethod, colorComponents),
- postInterpolationNormalizationForComponent<1, alphaPremultiplication>(interpolationMethod, colorComponents),
- postInterpolationNormalizationForComponent<2, alphaPremultiplication>(interpolationMethod, colorComponents),
+ postInterpolationNormalizationForComponent<0, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents),
+ postInterpolationNormalizationForComponent<1, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents),
+ postInterpolationNormalizationForComponent<2, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents),
colorComponents[3]
};
}
@@ -96,11 +97,11 @@
// MARK: - Interpolation
-template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethod>
-typename InterpolationMethod::ColorType interpolateColorComponents(InterpolationMethod interpolationMethod, typename InterpolationMethod::ColorType color1, double color1Multiplier, typename InterpolationMethod::ColorType color2, double color2Multiplier)
+template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
+typename InterpolationMethodColorSpace::ColorType interpolateColorComponents(InterpolationMethodColorSpace interpolationMethodColorSpace, typename InterpolationMethodColorSpace::ColorType color1, double color1Multiplier, typename InterpolationMethodColorSpace::ColorType color2, double color2Multiplier)
{
// 1. Apply pre-interpolation transforms (hue fixup for polar color spaces, alpha premultiplication if required).
- auto [normalizedColorComponents1, normalizedColorComponents2] = preInterpolationNormalization<alphaPremultiplication>(interpolationMethod, asColorComponents(color1), asColorComponents(color2));
+ auto [normalizedColorComponents1, normalizedColorComponents2] = preInterpolationNormalization<alphaPremultiplication>(interpolationMethodColorSpace, asColorComponents(color1), asColorComponents(color2));
// 2. Interpolate using the normalized components.
auto interpolatedColorComponents = mapColorComponents([&] (auto componentFromColor1, auto componentFromColor2) -> float {
@@ -108,10 +109,25 @@
}, normalizedColorComponents1, normalizedColorComponents2);
// 3. Apply post-interpolation trasforms (alpha un-premultiplication if required).
- auto normalizedInterpolatedColorComponents = postInterpolationNormalization<alphaPremultiplication>(interpolationMethod, interpolatedColorComponents);
+ auto normalizedInterpolatedColorComponents = postInterpolationNormalization<alphaPremultiplication>(interpolationMethodColorSpace, interpolatedColorComponents);
// 4. Create color type from components, normalizing any components that may be out of range.
- return makeColorTypeByNormalizingComponents<typename InterpolationMethod::ColorType>(normalizedInterpolatedColorComponents);
+ return makeColorTypeByNormalizingComponents<typename InterpolationMethodColorSpace::ColorType>(normalizedInterpolatedColorComponents);
}
+inline Color interpolateColors(ColorInterpolationMethod colorInterpolationMethod, Color color1, double color1Multiplier, Color color2, double color2Multiplier)
+{
+ return WTF::switchOn(colorInterpolationMethod.colorSpace,
+ [&] (auto& colorSpace) {
+ using ColorType = typename std::remove_reference_t<decltype(colorSpace)>::ColorType;
+ switch (colorInterpolationMethod.alphaPremultiplication) {
+ case AlphaPremultiplication::Premultiplied:
+ return makeCanonicalColor(interpolateColorComponents<AlphaPremultiplication::Premultiplied>(colorSpace, color1.toColorTypeLossy<ColorType>(), color1Multiplier, color2.toColorTypeLossy<ColorType>(), color2Multiplier));
+ case AlphaPremultiplication::Unpremultiplied:
+ return makeCanonicalColor(interpolateColorComponents<AlphaPremultiplication::Unpremultiplied>(colorSpace, color1.toColorTypeLossy<ColorType>(), color1Multiplier, color2.toColorTypeLossy<ColorType>(), color2Multiplier));
+ }
+ }
+ );
}
+
+}
Modified: trunk/Source/WebCore/platform/graphics/ColorNormalization.h (287309 => 287310)
--- trunk/Source/WebCore/platform/graphics/ColorNormalization.h 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/platform/graphics/ColorNormalization.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -25,6 +25,8 @@
#pragma once
+#include "Color.h"
+#include "ColorConversion.h"
#include "ColorTypes.h"
#include <wtf/MathExtras.h>
@@ -31,8 +33,11 @@
namespace WebCore {
template<typename ColorType> ColorType makeColorTypeByNormalizingComponents(const ColorComponents<float, 4>&);
+template<typename ColorType> Color makeCanonicalColor(ColorType);
+// MARK: - Normalization
+
template<typename ComponentType> struct WhitenessBlackness {
ComponentType whiteness;
ComponentType blackness;
@@ -101,4 +106,21 @@
return { lightness, chroma, normalizedHue, alpha };
}
+// MARK: - Canonicalization
+
+template<typename ColorType> inline Color makeCanonicalColor(ColorType color)
+{
+ return color;
}
+
+template<> inline Color makeCanonicalColor<HWBA<float>>(HWBA<float> color)
+{
+ return convertColor<SRGBA<uint8_t>>(color);
+}
+
+template<> inline Color makeCanonicalColor<HSLA<float>>(HSLA<float> color)
+{
+ return convertColor<SRGBA<uint8_t>>(color);
+}
+
+}
Modified: trunk/Source/WebCore/platform/graphics/Gradient.h (287309 => 287310)
--- trunk/Source/WebCore/platform/graphics/Gradient.h 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/platform/graphics/Gradient.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -27,16 +27,16 @@
#pragma once
-#include "AffineTransform.h"
#include "Color.h"
#include "ColorInterpolationMethod.h"
#include "FloatPoint.h"
+#include "GradientColorStop.h"
#include "GraphicsTypes.h"
#include <variant>
#include <wtf/Vector.h>
#if USE(CG)
-#include <wtf/RetainPtr.h>
+#include "GradientRendererCG.h"
#endif
#if USE(DIRECT2D)
@@ -45,7 +45,6 @@
#if USE(CG)
typedef struct CGContext* CGContextRef;
-typedef struct CGGradient* CGGradientRef;
#endif
#if USE(DIRECT2D)
@@ -59,21 +58,15 @@
namespace WebCore {
+class AffineTransform;
class FloatRect;
class GraphicsContext;
class Gradient : public RefCounted<Gradient> {
public:
- struct ColorStop {
- float offset { 0 };
- Color color;
+ using ColorStop = GradientColorStop;
+ using ColorStopVector = GradientColorStopVector;
- template<typename Encoder> void encode(Encoder&) const;
- template<typename Decoder> static std::optional<ColorStop> decode(Decoder&);
- };
-
- using ColorStopVector = Vector<ColorStop, 2>;
-
struct LinearData {
FloatPoint point0;
FloatPoint point1;
@@ -144,11 +137,6 @@
void sortStops() const;
void stopsChanged();
-#if USE(CG)
- void createCGGradient();
- bool hasOnlyBoundedSRGBColorStops() const;
-#endif
-
Data m_data;
ColorInterpolationMethod m_colorInterpolationMethod;
mutable ColorStopVector m_stops;
@@ -157,7 +145,7 @@
mutable unsigned m_cachedHash { 0 };
#if USE(CG)
- RetainPtr<CGGradientRef> m_gradient;
+ std::optional<GradientRendererCG> m_platformRenderer;
#endif
#if USE(DIRECT2D)
@@ -165,27 +153,6 @@
#endif
};
-template<typename Encoder> void Gradient::ColorStop::encode(Encoder& encoder) const
-{
- encoder << offset;
- encoder << color;
-}
-
-template<typename Decoder> std::optional<Gradient::ColorStop> Gradient::ColorStop::decode(Decoder& decoder)
-{
- std::optional<float> offset;
- decoder >> offset;
- if (!offset)
- return std::nullopt;
-
- std::optional<Color> color;
- decoder >> color;
- if (!color)
- return std::nullopt;
-
- return {{ *offset, *color }};
-}
-
template<typename Encoder> void Gradient::LinearData::encode(Encoder& encoder) const
{
encoder << point0;
Added: trunk/Source/WebCore/platform/graphics/GradientColorStop.h (0 => 287310)
--- trunk/Source/WebCore/platform/graphics/GradientColorStop.h (rev 0)
+++ trunk/Source/WebCore/platform/graphics/GradientColorStop.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Color.h"
+#include <optional>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+struct GradientColorStop {
+ float offset { 0 };
+ Color color;
+
+ template<typename Encoder> void encode(Encoder&) const;
+ template<typename Decoder> static std::optional<GradientColorStop> decode(Decoder&);
+};
+
+using GradientColorStopVector = Vector<GradientColorStop, 2>;
+
+template<typename Encoder> void GradientColorStop::encode(Encoder& encoder) const
+{
+ encoder << offset;
+ encoder << color;
+}
+
+template<typename Decoder> std::optional<GradientColorStop> GradientColorStop::decode(Decoder& decoder)
+{
+ std::optional<float> offset;
+ decoder >> offset;
+ if (!offset)
+ return std::nullopt;
+
+ std::optional<Color> color;
+ decoder >> color;
+ if (!color)
+ return std::nullopt;
+
+ return {{ *offset, *color }};
+}
+
+}
Modified: trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp (287309 => 287310)
--- trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp 2021-12-21 12:42:19 UTC (rev 287310)
@@ -29,72 +29,17 @@
#if USE(CG)
+#include "GradientRendererCG.h"
#include "GraphicsContextCG.h"
#include <pal/spi/cg/CoreGraphicsSPI.h>
-#include <wtf/RetainPtr.h>
namespace WebCore {
void Gradient::stopsChanged()
{
- m_gradient = nullptr;
+ m_platformRenderer = { };
}
-bool Gradient::hasOnlyBoundedSRGBColorStops() const
-{
- for (const auto& stop : m_stops) {
- if (stop.color.colorSpace() != ColorSpace::SRGB)
- return false;
- }
- return true;
-}
-
-void Gradient::createCGGradient()
-{
- sortStops();
-
- unsigned numStops = m_stops.size();
-
- const int reservedStops = 3;
- Vector<CGFloat, reservedStops> locations;
- locations.reserveInitialCapacity(numStops);
-
- // If all the stops are bounded sRGB (as represented by the color having the color space
- // ColorSpace::SRGB), it is faster to create a gradient using components than CGColors.
- if (hasOnlyBoundedSRGBColorStops()) {
- Vector<CGFloat, 4 * reservedStops> colorComponents;
- colorComponents.reserveInitialCapacity(numStops * 4);
-
- for (const auto& stop : m_stops) {
- auto [colorSpace, components] = stop.color.colorSpaceAndComponents();
- auto [r, g, b, a] = components;
- colorComponents.uncheckedAppend(r);
- colorComponents.uncheckedAppend(g);
- colorComponents.uncheckedAppend(b);
- colorComponents.uncheckedAppend(a);
-
- locations.uncheckedAppend(stop.offset);
- }
-
- m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
- return;
- }
-
- auto colorsArray = adoptCF(CFArrayCreateMutable(0, m_stops.size(), &kCFTypeArrayCallBacks));
- for (const auto& stop : m_stops) {
- CFArrayAppendValue(colorsArray.get(), cachedCGColor(stop.color).get());
- locations.uncheckedAppend(stop.offset);
- }
-
-#if HAVE(CORE_GRAPHICS_EXTENDED_SRGB_COLOR_SPACE)
- auto extendedColorsGradientColorSpace = extendedSRGBColorSpaceRef();
-#else
- auto extendedColorsGradientColorSpace = sRGBColorSpaceRef();
-#endif
-
- m_gradient = adoptCF(CGGradientCreateWithColors(extendedColorsGradientColorSpace, colorsArray.get(), locations.data()));
-}
-
void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
{
context.clip(rect);
@@ -108,11 +53,11 @@
void Gradient::paint(CGContextRef platformContext)
{
- CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
+ if (!m_platformRenderer) {
+ sortStops();
+ m_platformRenderer = GradientRendererCG { m_colorInterpolationMethod, m_stops };
+ }
- if (!m_gradient)
- createCGGradient();
-
WTF::switchOn(m_data,
[&] (const LinearData& data) {
switch (m_spreadMethod) {
@@ -119,7 +64,7 @@
case GradientSpreadMethod::Repeat:
case GradientSpreadMethod::Reflect: {
CGContextStateSaver saveState(platformContext);
- extendOptions = 0;
+ CGGradientDrawingOptions extendOptions = 0;
FloatPoint gradientVectorNorm(data.point1 - data.point0);
gradientVectorNorm.normalize();
@@ -143,7 +88,7 @@
CGPoint left = CGPointMake(flip ? end : start, 0);
CGPoint right = CGPointMake(flip ? start : end, 0);
- CGContextDrawLinearGradient(platformContext, m_gradient.get(), left, right, extendOptions);
+ m_platformRenderer->drawLinearGradient(platformContext, left, right, extendOptions);
};
auto isLeftOf = [](CGFloat start, CGFloat end, CGRect boundingBox) -> bool {
@@ -189,12 +134,14 @@
drawLinearGradient(end - dx, end, flip);
flip = !flip && m_spreadMethod == GradientSpreadMethod::Reflect;
}
-
break;
}
- case GradientSpreadMethod::Pad:
- CGContextDrawLinearGradient(platformContext, m_gradient.get(), data.point0, data.point1, extendOptions);
+ case GradientSpreadMethod::Pad: {
+ CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
+ m_platformRenderer->drawLinearGradient(platformContext, data.point0, data.point1, extendOptions);
+ break;
}
+ }
},
[&] (const RadialData& data) {
bool needScaling = data.aspectRatio != 1;
@@ -208,7 +155,8 @@
CGContextTranslateCTM(platformContext, -data.point0.x(), -data.point0.y());
}
- CGContextDrawRadialGradient(platformContext, m_gradient.get(), data.point0, data.startRadius, data.point1, data.endRadius, extendOptions);
+ CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
+ m_platformRenderer->drawRadialGradient(platformContext, data.point0, data.startRadius, data.point1, data.endRadius, extendOptions);
if (needScaling)
CGContextRestoreGState(platformContext);
@@ -221,7 +169,7 @@
CGContextTranslateCTM(platformContext, data.point0.x(), data.point0.y());
CGContextRotateCTM(platformContext, (CGFloat)-M_PI_2);
CGContextTranslateCTM(platformContext, -data.point0.x(), -data.point0.y());
- CGContextDrawConicGradient(platformContext, m_gradient.get(), data.point0, data.angleRadians);
+ m_platformRenderer->drawConicGradient(platformContext, data.point0, data.angleRadians);
CGContextRestoreGState(platformContext);
#else
UNUSED_PARAM(data);
Added: trunk/Source/WebCore/platform/graphics/cg/GradientRendererCG.cpp (0 => 287310)
--- trunk/Source/WebCore/platform/graphics/cg/GradientRendererCG.cpp (rev 0)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientRendererCG.cpp 2021-12-21 12:42:19 UTC (rev 287310)
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GradientRendererCG.h"
+
+#include "ColorInterpolation.h"
+#include "ColorSpaceCG.h"
+#include <pal/spi/cg/CoreGraphicsSPI.h>
+
+namespace WebCore {
+
+GradientRendererCG::GradientRendererCG(ColorInterpolationMethod colorInterpolationMethod, const GradientColorStopVector& stops)
+ : m_strategy { pickStrategy(colorInterpolationMethod, stops) }
+{
+}
+
+// MARK: - Strategy selection.
+
+GradientRendererCG::Strategy GradientRendererCG::pickStrategy(ColorInterpolationMethod colorInterpolationMethod, const GradientColorStopVector& stops) const
+{
+ return WTF::switchOn(colorInterpolationMethod.colorSpace,
+ [&] (const ColorInterpolationMethod::SRGB&) -> Strategy {
+ switch (colorInterpolationMethod.alphaPremultiplication) {
+ case AlphaPremultiplication::Unpremultiplied:
+ return makeGradient(colorInterpolationMethod, stops);
+ case AlphaPremultiplication::Premultiplied:
+#if HAVE(CORE_GRAPHICS_PREMULTIPLIED_INTERPOLATION_GRADIENT)
+ return makeGradient(colorInterpolationMethod, stops);
+#else
+ // FIXME: Use gradient strategy if none of the stops have alpha.
+ return makeShading(colorInterpolationMethod, stops);
+#endif
+ }
+ },
+ [&] (const auto&) -> Strategy {
+ // FIXME: Add support for the other interpolation color spaces.
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ );
+}
+
+// MARK: - Gradient strategy.
+
+GradientRendererCG::Strategy GradientRendererCG::makeGradient(ColorInterpolationMethod colorInterpolationMethod, const GradientColorStopVector& stops) const
+{
+ ASSERT_UNUSED(colorInterpolationMethod, std::holds_alternative<ColorInterpolationMethod::SRGB>(colorInterpolationMethod.colorSpace));
+#if !HAVE(CORE_GRAPHICS_PREMULTIPLIED_INTERPOLATION_GRADIENT)
+ ASSERT_UNUSED(colorInterpolationMethod, colorInterpolationMethod.alphaPremultiplication == AlphaPremultiplication::Unpremultiplied);
+#endif
+
+#if HAVE(CORE_GRAPHICS_GRADIENT_CREATE_WITH_OPTIONS)
+#if HAVE(CORE_GRAPHICS_PREMULTIPLIED_INTERPOLATION_GRADIENT)
+ auto gradientInterpolatesPremultipliedOptionsDictionary = [] () -> CFDictionaryRef {
+ static CFTypeRef keys[] = { kCGGradientInterpolatesPremultiplied };
+ static CFTypeRef values[] = { kCFBooleanTrue };
+ static CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ return options;
+ };
+
+ auto gradientOptionsDictionary = [&] (auto colorInterpolationMethod) -> CFDictionaryRef {
+ switch (colorInterpolationMethod.alphaPremultiplication) {
+ case AlphaPremultiplication::Unpremultiplied:
+ return nullptr;
+ case AlphaPremultiplication::Premultiplied:
+ return gradientInterpolatesPremultipliedOptionsDictionary();
+ }
+ };
+#else
+ auto gradientOptionsDictionary = [] (auto) -> CFDictionaryRef {
+ return nullptr;
+ };
+#endif
+#endif
+
+ auto hasOnlyBoundedSRGBColorStops = [] (const auto& stops) {
+ for (const auto& stop : stops) {
+ if (stop.color.colorSpace() != ColorSpace::SRGB)
+ return false;
+ }
+ return true;
+ };
+
+ auto numberOfStops = stops.size();
+
+ static constexpr auto reservedStops = 3;
+ Vector<CGFloat, reservedStops> locations;
+ locations.reserveInitialCapacity(numberOfStops);
+
+ Vector<CGFloat, 4 * reservedStops> colorComponents;
+ colorComponents.reserveInitialCapacity(numberOfStops * 4);
+
+ auto gradientColorSpace = sRGBColorSpaceRef();
+
+ // FIXME: Now that we only ever use CGGradientCreateWithColorComponents, we should investigate
+ // if there is any real benefit to using sRGB when all the stops are bounded vs just using
+ // extended sRGB for all gradients.
+ if (hasOnlyBoundedSRGBColorStops(stops)) {
+ for (const auto& stop : stops) {
+ auto [colorSpace, components] = stop.color.colorSpaceAndComponents();
+ auto [r, g, b, a] = components;
+ colorComponents.uncheckedAppend(r);
+ colorComponents.uncheckedAppend(g);
+ colorComponents.uncheckedAppend(b);
+ colorComponents.uncheckedAppend(a);
+
+ locations.uncheckedAppend(stop.offset);
+ }
+ } else {
+#if HAVE(CORE_GRAPHICS_EXTENDED_SRGB_COLOR_SPACE)
+ gradientColorSpace = extendedSRGBColorSpaceRef();
+#endif
+
+ for (const auto& stop : stops) {
+#if HAVE(CORE_GRAPHICS_EXTENDED_SRGB_COLOR_SPACE)
+ auto [r, g, b, a] = stop.color.toColorTypeLossy<ExtendedSRGBA<float>>();
+#else
+ auto [r, g, b, a] = stop.color.toColorTypeLossy<SRGBA<float>>();
+#endif
+ colorComponents.uncheckedAppend(r);
+ colorComponents.uncheckedAppend(g);
+ colorComponents.uncheckedAppend(b);
+ colorComponents.uncheckedAppend(a);
+
+ locations.uncheckedAppend(stop.offset);
+ }
+ }
+
+#if HAVE(CORE_GRAPHICS_GRADIENT_CREATE_WITH_OPTIONS)
+ return Gradient { adoptCF(CGGradientCreateWithColorComponentsAndOptions(gradientColorSpace, colorComponents.data(), locations.data(), numberOfStops, gradientOptionsDictionary(colorInterpolationMethod))) };
+#else
+ return Gradient { adoptCF(CGGradientCreateWithColorComponents(gradientColorSpace, colorComponents.data(), locations.data(), numberOfStops)) };
+#endif
+}
+
+// MARK: - Shading strategy.
+
+template<typename InterpolationSpace, AlphaPremultiplication alphaPremultiplication>
+void GradientRendererCG::Shading::shadingFunction(void* info, const CGFloat* in, CGFloat* out)
+{
+ using InterpolationSpaceColorType = typename InterpolationSpace::ColorType;
+#if HAVE(CORE_GRAPHICS_EXTENDED_SRGB_COLOR_SPACE)
+ using OutputSpaceColorType = ExtendedSRGBA<float>;
+#else
+ using OutputSpaceColorType = SRGBA<float>;
+#endif
+
+ auto* data = ""
+
+ // Compute color at offset 'in[0]' and assign the components to out[0 -> 3].
+
+ float requestedOffset = in[0];
+
+ // 1. Find stops that bound the requested offset.
+ auto [stop0, stop1] = [&] {
+ for (size_t stop = 1; stop < data->stops().size(); ++stop) {
+ if (requestedOffset <= data->stops()[stop].offset)
+ return std::tie(data->stops()[stop - 1], data->stops()[stop]);
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+ }();
+
+ // 2. Compute percentage offset between the two stops.
+ float offset = (stop1.offset == stop0.offset) ? 0.0f : (requestedOffset - stop0.offset) / (stop1.offset - stop0.offset);
+
+ // 3. Interpolate the two stops' colors by the computed offset.
+ // FIXME: We don't want to due hue fixup for each call, so we should figure out how to precompute that.
+ auto interpolatedColor = interpolateColorComponents<alphaPremultiplication>(
+ std::get<InterpolationSpace>(data->colorInterpolationMethod().colorSpace),
+ makeFromComponents<InterpolationSpaceColorType>(stop0.colorComponents), 1.0f - offset,
+ makeFromComponents<InterpolationSpaceColorType>(stop1.colorComponents), offset);
+
+ // 4. Convert to the output color space.
+ auto interpolatedColorConvertedToOutputSpace = asColorComponents(convertColor<OutputSpaceColorType>(interpolatedColor));
+
+ // 5. Write color components to 'out' pointer.
+ for (size_t componentIndex = 0; componentIndex < interpolatedColorConvertedToOutputSpace.size(); ++componentIndex)
+ out[componentIndex] = interpolatedColorConvertedToOutputSpace[componentIndex];
+}
+
+GradientRendererCG::Strategy GradientRendererCG::makeShading(ColorInterpolationMethod colorInterpolationMethod, const GradientColorStopVector& stops) const
+{
+ auto makeData = [&] (auto colorInterpolationMethod, auto& stops) {
+ auto convertColorToColorInterpolationSpace = [&] (const Color& color, auto colorInterpolationMethod) -> ColorComponents<float, 4> {
+ return WTF::switchOn(colorInterpolationMethod.colorSpace,
+ [&] (auto& colorSpace) -> ColorComponents<float, 4> {
+ using ColorType = typename std::remove_reference_t<decltype(colorSpace)>::ColorType;
+ return asColorComponents(color.template toColorTypeLossy<ColorType>());
+ }
+ );
+ };
+
+ auto totalNumberOfStops = stops.size();
+ bool hasZero = false;
+ bool hasOne = false;
+
+ for (const auto& stop : stops) {
+ auto offset = stop.offset;
+ ASSERT(offset >= 0);
+ ASSERT(offset <= 1);
+
+ if (offset == 0)
+ hasZero = true;
+ else if (offset == 1)
+ hasOne = true;
+ }
+
+ if (!hasZero)
+ totalNumberOfStops++;
+ if (!hasOne)
+ totalNumberOfStops++;
+
+ Vector<ColorConvertedToInterpolationColorSpaceStop> convertedStops;
+ convertedStops.reserveInitialCapacity(totalNumberOfStops);
+
+ if (!hasZero)
+ convertedStops.uncheckedAppend({ 0.0f, { 0.0f, 0.0f, 0.0f, 0.0f } });
+
+ for (const auto& stop : stops)
+ convertedStops.uncheckedAppend({ stop.offset, convertColorToColorInterpolationSpace(stop.color, colorInterpolationMethod) });
+
+ if (!hasOne)
+ convertedStops.uncheckedAppend({ 1.0f, convertedStops.last().colorComponents });
+
+ if (!hasZero)
+ convertedStops[0].colorComponents = convertedStops[1].colorComponents;
+
+ return Shading::Data::create(colorInterpolationMethod, WTFMove(convertedStops));
+ };
+
+ auto makeFunction = [&] (auto colorInterpolationMethod, auto& data) {
+ auto makeEvaluateCallback = [&] (auto colorInterpolationMethod) -> CGFunctionEvaluateCallback {
+ return WTF::switchOn(colorInterpolationMethod.colorSpace,
+ [&] (auto& colorSpace) -> CGFunctionEvaluateCallback {
+ using InterpolationMethodColorSpace = typename std::remove_reference_t<decltype(colorSpace)>;
+
+ switch (colorInterpolationMethod.alphaPremultiplication) {
+ case AlphaPremultiplication::Unpremultiplied:
+ return &Shading::shadingFunction<InterpolationMethodColorSpace, AlphaPremultiplication::Unpremultiplied>;
+ case AlphaPremultiplication::Premultiplied:
+ return &Shading::shadingFunction<InterpolationMethodColorSpace, AlphaPremultiplication::Premultiplied>;
+ }
+ }
+ );
+ };
+
+ const CGFunctionCallbacks callbacks = {
+ 0,
+ makeEvaluateCallback(colorInterpolationMethod),
+ [] (void* info) {
+ static_cast<GradientRendererCG::Shading::Data*>(info)->deref();
+ }
+ };
+
+ static const CGFloat domain[2] = { 0, 1 };
+#if HAVE(CORE_GRAPHICS_EXTENDED_SRGB_COLOR_SPACE)
+ static const CGFloat range[8] = { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), 0, 1 };
+#else
+ static const CGFloat range[8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
+#endif
+
+ Ref dataRefCopy = data;
+ return adoptCF(CGFunctionCreate(&dataRefCopy.leakRef(), 1, domain, 4, range, &callbacks));
+ };
+
+ auto data = "" stops);
+ auto function = makeFunction(colorInterpolationMethod, data);
+
+ // FIXME: Investigate using bounded sRGB when the input stops are all bounded sRGB.
+#if HAVE(CORE_GRAPHICS_EXTENDED_SRGB_COLOR_SPACE)
+ auto colorSpace = extendedSRGBColorSpaceRef();
+#else
+ auto colorSpace = sRGBColorSpaceRef();
+#endif
+
+ return Shading { WTFMove(data), WTFMove(function), colorSpace };
+}
+
+// MARK: - Drawing functions.
+
+void GradientRendererCG::drawLinearGradient(CGContextRef platformContext, CGPoint startPoint, CGPoint endPoint, CGGradientDrawingOptions options)
+{
+ WTF::switchOn(m_strategy,
+ [&] (Gradient& gradient) {
+ CGContextDrawLinearGradient(platformContext, gradient.gradient.get(), startPoint, endPoint, options);
+ },
+ [&] (Shading& shading) {
+ bool startExtend = (options & kCGGradientDrawsBeforeStartLocation) != 0;
+ bool endExtend = (options & kCGGradientDrawsAfterEndLocation) != 0;
+
+ CGContextDrawShading(platformContext, adoptCF(CGShadingCreateAxial(shading.colorSpace.get(), startPoint, endPoint, shading.function.get(), startExtend, endExtend)).get());
+ }
+ );
+}
+
+void GradientRendererCG::drawRadialGradient(CGContextRef platformContext, CGPoint startCenter, CGFloat startRadius, CGPoint endCenter, CGFloat endRadius, CGGradientDrawingOptions options)
+{
+ WTF::switchOn(m_strategy,
+ [&] (Gradient& gradient) {
+ CGContextDrawRadialGradient(platformContext, gradient.gradient.get(), startCenter, startRadius, endCenter, endRadius, options);
+ },
+ [&] (Shading& shading) {
+ bool startExtend = (options & kCGGradientDrawsBeforeStartLocation) != 0;
+ bool endExtend = (options & kCGGradientDrawsAfterEndLocation) != 0;
+
+ CGContextDrawShading(platformContext, adoptCF(CGShadingCreateRadial(shading.colorSpace.get(), startCenter, startRadius, endCenter, endRadius, shading.function.get(), startExtend, endExtend)).get());
+ }
+ );
+}
+
+void GradientRendererCG::drawConicGradient(CGContextRef platformContext, CGPoint center, CGFloat angle)
+{
+// FIXME: Seems like this should be HAVE(CG_CONTEXT_DRAW_CONIC_GRADIENT).
+// FIXME: Can we change tvOS to be like the other Cocoa platforms?
+#if PLATFORM(COCOA) && !PLATFORM(APPLETV)
+ WTF::switchOn(m_strategy,
+ [&] (Gradient& gradient) {
+ CGContextDrawConicGradient(platformContext, gradient.gradient.get(), center, angle);
+ },
+ [&] (Shading& shading) {
+ CGContextDrawShading(platformContext, adoptCF(CGShadingCreateConic(shading.colorSpace.get(), center, angle, shading.function.get())).get());
+ }
+ );
+#else
+ UNUSED_PARAM(platformContext);
+ UNUSED_PARAM(center);
+ UNUSED_PARAM(angle);
+#endif
+}
+
+}
Added: trunk/Source/WebCore/platform/graphics/cg/GradientRendererCG.h (0 => 287310)
--- trunk/Source/WebCore/platform/graphics/cg/GradientRendererCG.h (rev 0)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientRendererCG.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ColorComponents.h"
+#include "ColorInterpolationMethod.h"
+#include "GradientColorStop.h"
+#include <CoreGraphics/CoreGraphics.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+struct ColorConvertedToInterpolationColorSpaceStop {
+ float offset;
+ ColorComponents<float, 4> colorComponents;
+};
+
+class GradientRendererCG {
+public:
+ GradientRendererCG(ColorInterpolationMethod, const GradientColorStopVector&);
+
+ void drawLinearGradient(CGContextRef, CGPoint startPoint, CGPoint endPoint, CGGradientDrawingOptions);
+ void drawRadialGradient(CGContextRef, CGPoint startCenter, CGFloat startRadius, CGPoint endCenter, CGFloat endRadius, CGGradientDrawingOptions);
+ void drawConicGradient(CGContextRef, CGPoint center, CGFloat angle);
+
+private:
+ struct Gradient {
+ RetainPtr<CGGradientRef> gradient;
+ };
+
+ struct Shading {
+ template<typename InterpolationSpace, AlphaPremultiplication> static void shadingFunction(void*, const CGFloat*, CGFloat*);
+
+ class Data : public ThreadSafeRefCounted<Data> {
+ public:
+ static Ref<Data> create(ColorInterpolationMethod colorInterpolationMethod, Vector<ColorConvertedToInterpolationColorSpaceStop> stops)
+ {
+ return adoptRef(*new Data(colorInterpolationMethod, WTFMove(stops)));
+ }
+
+ ColorInterpolationMethod colorInterpolationMethod() const { return m_colorInterpolationMethod; }
+ const Vector<ColorConvertedToInterpolationColorSpaceStop>& stops() const { return m_stops; }
+
+ private:
+ Data(ColorInterpolationMethod colorInterpolationMethod, Vector<ColorConvertedToInterpolationColorSpaceStop> stops)
+ : m_colorInterpolationMethod { colorInterpolationMethod }
+ , m_stops { WTFMove(stops) }
+ {
+ }
+
+ ColorInterpolationMethod m_colorInterpolationMethod;
+ Vector<ColorConvertedToInterpolationColorSpaceStop> m_stops;
+ };
+
+ Ref<Data> data;
+ RetainPtr<CGFunctionRef> function;
+ RetainPtr<CGColorSpaceRef> colorSpace;
+ };
+
+ using Strategy = std::variant<Gradient, Shading>;
+
+ Strategy pickStrategy(ColorInterpolationMethod, const GradientColorStopVector&) const;
+ Strategy makeGradient(ColorInterpolationMethod, const GradientColorStopVector&) const;
+ Strategy makeShading(ColorInterpolationMethod, const GradientColorStopVector&) const;
+
+ Strategy m_strategy;
+};
+
+}
Modified: trunk/Source/WebKitLegacy/win/ChangeLog (287309 => 287310)
--- trunk/Source/WebKitLegacy/win/ChangeLog 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebKitLegacy/win/ChangeLog 2021-12-21 12:42:19 UTC (rev 287310)
@@ -1,3 +1,18 @@
+2021-12-21 Sam Weinig <wei...@apple.com>
+
+ Add support for premultiplied alpha interpolated gradients and defaulted off option to use them for CSS Gradients
+ https://bugs.webkit.org/show_bug.cgi?id=234492
+
+ Reviewed by Simon Fraser.
+
+ Add support for tests enabling the CSSGradientPremultipliedAlphaInterpolationEnabled preference.
+
+ * WebPreferences.cpp:
+ (WebPreferences::cssGradientPremultipliedAlphaInterpolationEnabled):
+ * WebPreferences.h:
+ * WebView.cpp:
+ (WebView::notifyPreferencesChanged):
+
2021-12-20 Fujii Hironori <hironori.fu...@sony.com>
[Win] MSVC reports "COMPropertyBag.h(233): error C2385: ambiguous access of 'IUnknown'" with /std:c++20
Modified: trunk/Source/WebKitLegacy/win/WebPreferences.cpp (287309 => 287310)
--- trunk/Source/WebKitLegacy/win/WebPreferences.cpp 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebKitLegacy/win/WebPreferences.cpp 2021-12-21 12:42:19 UTC (rev 287310)
@@ -2637,6 +2637,11 @@
return boolValueForKey("WebKitCanvasColorSpaceEnabled");
}
+bool WebPreferences::cssGradientPremultipliedAlphaInterpolationEnabled()
+{
+ return boolValueForKey("WebKitCSSGradientPremultipliedAlphaInterpolationEnabled");
+}
+
bool WebPreferences::mockScrollbarsControllerEnabled()
{
return boolValueForKey("WebKitMockScrollbarsControllerEnabled");
Modified: trunk/Source/WebKitLegacy/win/WebPreferences.h (287309 => 287310)
--- trunk/Source/WebKitLegacy/win/WebPreferences.h 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebKitLegacy/win/WebPreferences.h 2021-12-21 12:42:19 UTC (rev 287310)
@@ -346,6 +346,7 @@
// The following preference accessors are not exposed via IWebPreferences* as they are only
// needed for testing purposes and can be toggled via the set*PreferenceForTesting functions.
bool canvasColorSpaceEnabled();
+ bool cssGradientPremultipliedAlphaInterpolationEnabled();
bool mockScrollbarsControllerEnabled();
private:
Modified: trunk/Source/WebKitLegacy/win/WebView.cpp (287309 => 287310)
--- trunk/Source/WebKitLegacy/win/WebView.cpp 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Source/WebKitLegacy/win/WebView.cpp 2021-12-21 12:42:19 UTC (rev 287310)
@@ -5600,6 +5600,7 @@
settings.setOverscrollBehaviorEnabled(!!enabled);
settings.setCanvasColorSpaceEnabled(m_preferences->canvasColorSpaceEnabled());
+ settings.setCSSGradientPremultipliedAlphaInterpolationEnabled(m_preferences->cssGradientPremultipliedAlphaInterpolationEnabled());
settings.setMockScrollbarsControllerEnabled(m_preferences->mockScrollbarsControllerEnabled());
return S_OK;
Modified: trunk/Tools/ChangeLog (287309 => 287310)
--- trunk/Tools/ChangeLog 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Tools/ChangeLog 2021-12-21 12:42:19 UTC (rev 287310)
@@ -1,3 +1,14 @@
+2021-12-21 Sam Weinig <wei...@apple.com>
+
+ Add support for premultiplied alpha interpolated gradients and defaulted off option to use them for CSS Gradients
+ https://bugs.webkit.org/show_bug.cgi?id=234492
+
+ Reviewed by Simon Fraser.
+
+ * DumpRenderTree/TestOptions.cpp:
+ (WTR::TestOptions::defaults):
+ Add default for Windows WebKitLegacy testing which still requires it.
+
2021-12-21 Carlos Garcia Campos <cgar...@igalia.com>
[GTK][a11y] Implement list markers when building with ATSPI
Modified: trunk/Tools/DumpRenderTree/TestOptions.cpp (287309 => 287310)
--- trunk/Tools/DumpRenderTree/TestOptions.cpp 2021-12-21 12:38:52 UTC (rev 287309)
+++ trunk/Tools/DumpRenderTree/TestOptions.cpp 2021-12-21 12:42:19 UTC (rev 287310)
@@ -135,6 +135,7 @@
{ "CSSContainmentEnabled", false },
{ "CSSCounterStyleAtRuleImageSymbolsEnabled", false },
{ "CSSCounterStyleAtRulesEnabled", false },
+ { "CSSGradientPremultipliedAlphaInterpolationEnabled", true },
{ "CSSLogicalEnabled", false },
{ "CSSOMViewSmoothScrollingEnabled", false },
{ "CanvasColorSpaceEnabled", true },