style: Address spec changes re. color-mix

It was clarified that the percentages are weights, and two weights are
now allowed. Missing percentages are computed as 100% - the other or
50%. Other than that, commas are required etc, which is good since
that's how I implemented it originally.

Differential Revision: https://phabricator.services.mozilla.com/D107295
This commit is contained in:
Oriol Brufau 2023-05-16 07:32:20 +02:00
parent 685d269e31
commit 2bafbb46f5
2 changed files with 85 additions and 13 deletions

View file

@ -105,8 +105,44 @@ impl Color {
}
/// Mix two colors into one.
pub fn mix(left: &Color, right: &Color, progress: f32) -> Self {
left.animate(right, Procedure::Interpolate { progress: progress as f64 }).unwrap()
pub fn mix(
left_color: &Color,
left_weight: f32,
right_color: &Color,
right_weight: f32,
) -> Self {
let left_bg = left_color.scaled_rgba();
let right_bg = right_color.scaled_rgba();
let alpha = (left_bg.alpha * left_weight +
right_bg.alpha * right_weight)
.min(1.);
let mut fg = 0.;
let mut red = 0.;
let mut green = 0.;
let mut blue = 0.;
let colors = [
(left_color, &left_bg, left_weight),
(right_color, &right_bg, right_weight),
];
for &(color, bg, weight) in &colors {
fg += color.ratios.fg * weight;
red += bg.red * bg.alpha * weight;
green += bg.green * bg.alpha * weight;
blue += bg.blue * bg.alpha * weight;
}
let color = if alpha <= 0. {
RGBA::transparent()
} else {
let inv = 1. / alpha;
RGBA::new(red * inv, green * inv, blue * inv, alpha)
};
Self::new(color, ComplexColorRatios { bg: 1., fg })
}
fn scaled_rgba(&self) -> RGBA {