From 1e5079ca009bc0efdab80caea3df3d742a61fc87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 15 Aug 2023 00:50:50 +0200 Subject: [PATCH] style: Fix color-mix() percentage normalization Differential Revision: https://phabricator.services.mozilla.com/D147005 --- components/style/values/animated/color.rs | 25 +++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/components/style/values/animated/color.rs b/components/style/values/animated/color.rs index 8baa2497a01..d3ee616f765 100644 --- a/components/style/values/animated/color.rs +++ b/components/style/values/animated/color.rs @@ -134,10 +134,22 @@ impl Color { pub fn mix( interpolation: &ColorInterpolationMethod, left_color: &Color, - left_weight: f32, + mut left_weight: f32, right_color: &Color, - right_weight: f32, + mut right_weight: f32, ) -> Self { + // https://drafts.csswg.org/css-color-5/#color-mix-percent-norm + let sum = left_weight + right_weight; + let mut alpha_multiplier = 1.0; + if sum != 1.0 { + let scale = 1.0 / sum; + left_weight *= scale; + right_weight *= scale; + if sum < 1.0 { + alpha_multiplier = sum; + } + } + let mix_function = match interpolation.space { ColorSpace::Srgb => Self::mix_in::, ColorSpace::LinearSrgb => Self::mix_in::, @@ -148,7 +160,7 @@ impl Color { ColorSpace::Hsl => Self::mix_in::, ColorSpace::Lch => Self::mix_in::, }; - mix_function(left_color, left_weight, right_color, right_weight, interpolation.hue) + mix_function(left_color, left_weight, right_color, right_weight, interpolation.hue, alpha_multiplier) } fn mix_in( @@ -157,6 +169,7 @@ impl Color { right_color: &Color, right_weight: f32, hue_interpolation: HueInterpolationMethod, + alpha_multiplier: f32, ) -> Self where S: ModelledColor, @@ -166,13 +179,17 @@ impl Color { let color = S::lerp(&left_bg, left_weight, &right_bg, right_weight, hue_interpolation); let rgba: RGBA = color.into(); - let rgba = if !rgba.in_gamut() { + let mut rgba = if !rgba.in_gamut() { // TODO: Better gamut mapping. rgba.clamp() } else { rgba }; + if alpha_multiplier != 1.0 { + rgba.alpha *= alpha_multiplier; + } + let fg = left_color.ratios.fg * left_weight + right_color.ratios.fg * right_weight; Self::new(rgba, ComplexColorRatios { bg: 1., fg }) }