Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 239811efa2af9defc9ca2ff59d710618f4cba2d6
https://github.com/WebKit/WebKit/commit/239811efa2af9defc9ca2ff59d710618f4cba2d6
Author: Dan Glastonbury <[email protected]>
Date: 2026-06-19 (Fri, 19 Jun 2026)
Changed paths:
M LayoutTests/fast/gradients/alpha-premultiplied-sampled-expected.html
M LayoutTests/fast/gradients/alpha-premultiplied-sampled.html
A LayoutTests/fast/gradients/oklab-transparent-keyword-stop-expected.html
A LayoutTests/fast/gradients/oklab-transparent-keyword-stop.html
M Source/WebCore/platform/graphics/SampledGradientBuilder.h
Log Message:
-----------
REGRESSION(311406@main): Dark band in non-sRGB gradients with transparent
stops
https://bugs.webkit.org/show_bug.cgi?id=317277
rdar://179870903
Reviewed by Simon Fraser.
When SampledGradientBuilder bisects a segment to densify samples for CGGradient,
evaluateLinearOS lerped the interpolation-space color components directly,
ignoring CSS Color 4 §12.3's requirement that rectangular orthogonal color
spaces premultiply by alpha before interpolating. With the `transparent`
keyword (which resolves to rgba(0, 0, 0, 0)) paired with an opaque color in
OKLab, the zero-alpha stop's black RGB bled into the L component at the
midpoint, producing a visible dark band rather than a clean alpha ramp. The
defensive author form `rgb(255 255 255 / 0)` masked the bug because both
endpoints share the same hue.
Route the IS-space lerp for rectangular orthogonal interpolation spaces through
interpolateColorComponents, which already applies the §12.3 premul/lerp/unpremul
algorithm and handles 'none', NaN, and α=0 edge cases. evaluateLinearOS now
takes alphaPremultiplication as a template parameter, and the dispatch site in
sampleGradientStops switches on the runtime flag, mirroring how evaluateColorIS
is dispatched immediately above. Hue color spaces stay on the original plain
component-wise lerp: coarseSampleStops has already baked the
hueInterpolationMethod (e.g. Longer) into the coarse samples, so the angle
deltas between adjacent coarse samples are small. Re-running the hue rule per
bisection — which is what interpolateColorComponents would do — would re-expand
those ~5° deltas back to ≥180° under Longer and scramble the gradient.
evaluateLinearOS detects a hue color space at compile time from
ColorComponentType::Angle in the IS color type's componentInfo and branches
between the two paths.
* LayoutTests/fast/gradients/alpha-premultiplied-sampled-expected.html:
* LayoutTests/fast/gradients/alpha-premultiplied-sampled.html:
* LayoutTests/fast/gradients/oklab-transparent-keyword-stop-expected.html:
Added.
* LayoutTests/fast/gradients/oklab-transparent-keyword-stop.html: Added.
* Source/WebCore/platform/graphics/SampledGradientBuilder.h:
(WebCore::evaluateLinearOS): For rectangular orthogonal interpolation spaces,
use interpolateColorComponents to honor the premultiplied-alpha rule. For hue
spaces, keep the original plain component-wise lerp so per-bisection
interpolation does not re-apply the hue rotation already baked in by
coarseSampleStops.
(WebCore::sampleGradientStops): Switch on alphaPremultiplication when selecting
the evaluateLinearOS specialization.
Canonical link: https://commits.webkit.org/315551@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications