Fix color conversions (#3445)

This commit is contained in:
frozolotl 2024-02-20 15:33:41 +01:00 committed by GitHub
parent 1ca3d9204a
commit 96fba58cf2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 41 additions and 54 deletions

View File

@ -1008,8 +1008,9 @@ fn render_pattern_frame(state: &State, pattern: &Pattern) -> sk::Pixmap {
} }
fn to_sk_color(color: Color) -> sk::Color { fn to_sk_color(color: Color) -> sk::Color {
let [r, g, b, a] = color.to_rgb().to_vec4_u8(); let [r, g, b, a] = color.to_rgb().to_vec4();
sk::Color::from_rgba8(r, g, b, a) sk::Color::from_rgba(r, g, b, a)
.expect("components must always be in the range [0..=1]")
} }
fn to_sk_color_u8(color: Color) -> sk::ColorU8 { fn to_sk_color_u8(color: Color) -> sk::ColorU8 {

View File

@ -1306,14 +1306,13 @@ impl Color {
Self::Luma(c) => c, Self::Luma(c) => c,
// Perform sRGB gamut mapping by converting to Okhsv first. // Perform sRGB gamut mapping by converting to Okhsv first.
// This yields better results than clamping. // This yields better results than clamping.
Self::Oklab(c) => Luma::from_color_unclamped(Okhsva::from_color(c)), Self::Oklab(c) => Luma::from_color(Okhsva::from_color(c)),
Self::Oklch(c) => Luma::from_color_unclamped(Okhsva::from_color(c)), Self::Oklch(c) => Luma::from_color(Okhsva::from_color(c)),
// No clamping necessary because these color spaces are all within sRGB, same as [`Luma`]. Self::Rgb(c) => Luma::from_color(c),
Self::Rgb(c) => Luma::from_color_unclamped(c), Self::LinearRgb(c) => Luma::from_color(c),
Self::LinearRgb(c) => Luma::from_color_unclamped(c), Self::Cmyk(c) => Luma::from_color(c.to_rgba()),
Self::Cmyk(c) => Luma::from_color_unclamped(c.to_rgba()), Self::Hsl(c) => Luma::from_color(c),
Self::Hsl(c) => Luma::from_color_unclamped(c), Self::Hsv(c) => Luma::from_color(c),
Self::Hsv(c) => Luma::from_color_unclamped(c),
}) })
} }
@ -1349,35 +1348,31 @@ impl Color {
pub fn to_rgb(self) -> Self { pub fn to_rgb(self) -> Self {
Self::Rgb(match self { Self::Rgb(match self {
// No clamping necessary because Luma is within sRGB, same as [`Rgb`]. Self::Luma(c) => Rgb::from_color(c),
Self::Luma(c) => Rgb::from_color_unclamped(c),
// Perform sRGB gamut mapping by converting to Okhsv first. // Perform sRGB gamut mapping by converting to Okhsv first.
// This yields better results than clamping. // This yields better results than clamping.
Self::Oklab(c) => Rgb::from_color_unclamped(Okhsva::from_color(c)), Self::Oklab(c) => Rgb::from_color(Okhsva::from_color(c)),
Self::Oklch(c) => Rgb::from_color_unclamped(Okhsva::from_color(c)), Self::Oklch(c) => Rgb::from_color(Okhsva::from_color(c)),
// No clamping necessary because these color spaces are all within sRGB, same as [`Rgb`].
Self::Rgb(c) => c, Self::Rgb(c) => c,
Self::LinearRgb(c) => Rgb::from_linear(c), Self::LinearRgb(c) => Rgb::from_linear(c),
Self::Cmyk(c) => Rgb::from_color_unclamped(c.to_rgba()), Self::Cmyk(c) => Rgb::from_color(c.to_rgba()),
Self::Hsl(c) => Rgb::from_color_unclamped(c), Self::Hsl(c) => Rgb::from_color(c),
Self::Hsv(c) => Rgb::from_color_unclamped(c), Self::Hsv(c) => Rgb::from_color(c),
}) })
} }
pub fn to_linear_rgb(self) -> Self { pub fn to_linear_rgb(self) -> Self {
Self::LinearRgb(match self { Self::LinearRgb(match self {
// No clamping necessary because Luma is within sRGB, same as $to. Self::Luma(c) => LinearRgb::from_color(c),
Self::Luma(c) => LinearRgb::from_color_unclamped(c),
// Perform sRGB gamut mapping by converting to Okhsv first. // Perform sRGB gamut mapping by converting to Okhsv first.
// This yields better results than clamping. // This yields better results than clamping.
Self::Oklab(c) => LinearRgb::from_color_unclamped(Okhsva::from_color(c)), Self::Oklab(c) => LinearRgb::from_color(Okhsva::from_color(c)),
Self::Oklch(c) => LinearRgb::from_color_unclamped(Okhsva::from_color(c)), Self::Oklch(c) => LinearRgb::from_color(Okhsva::from_color(c)),
// No clamping necessary because these color spaces are all within sRGB, same as $to. Self::Rgb(c) => LinearRgb::from_color(c),
Self::Rgb(c) => LinearRgb::from_color_unclamped(c),
Self::LinearRgb(c) => c, Self::LinearRgb(c) => c,
Self::Cmyk(c) => LinearRgb::from_color_unclamped(c.to_rgba()), Self::Cmyk(c) => LinearRgb::from_color(c.to_rgba()),
Self::Hsl(c) => Rgb::from_color_unclamped(c).into_linear(), Self::Hsl(c) => Rgb::from_color(c).into_linear(),
Self::Hsv(c) => Rgb::from_color_unclamped(c).into_linear(), Self::Hsv(c) => Rgb::from_color(c).into_linear(),
}) })
} }
@ -1386,51 +1381,42 @@ impl Color {
Self::Luma(c) => Cmyk::from_luma(c), Self::Luma(c) => Cmyk::from_luma(c),
// Perform sRGB gamut mapping by converting to Okhsv first. // Perform sRGB gamut mapping by converting to Okhsv first.
// This yields better results than clamping. // This yields better results than clamping.
Self::Oklab(c) => { Self::Oklab(c) => Cmyk::from_rgba(Rgb::from_color(Okhsva::from_color(c))),
Cmyk::from_rgba(Rgb::from_color_unclamped(Okhsva::from_color(c))) Self::Oklch(c) => Cmyk::from_rgba(Rgb::from_color(Okhsva::from_color(c))),
}
Self::Oklch(c) => {
Cmyk::from_rgba(Rgb::from_color_unclamped(Okhsva::from_color(c)))
}
Self::Rgb(c) => Cmyk::from_rgba(c), Self::Rgb(c) => Cmyk::from_rgba(c),
Self::LinearRgb(c) => Cmyk::from_rgba(Rgb::from_linear(c)), Self::LinearRgb(c) => Cmyk::from_rgba(Rgb::from_linear(c)),
Self::Cmyk(c) => c, Self::Cmyk(c) => c,
// No clamping necessary because these color spaces are all within sRGB, same as [`Cmyk`]. Self::Hsl(c) => Cmyk::from_rgba(Rgb::from_color(c)),
Self::Hsl(c) => Cmyk::from_rgba(Rgb::from_color_unclamped(c)), Self::Hsv(c) => Cmyk::from_rgba(Rgb::from_color(c)),
Self::Hsv(c) => Cmyk::from_rgba(Rgb::from_color_unclamped(c)),
}) })
} }
pub fn to_hsl(self) -> Self { pub fn to_hsl(self) -> Self {
Self::Hsl(match self { Self::Hsl(match self {
// No clamping necessary because Luma is within sRGB, same as [`Hsl`]. Self::Luma(c) => Hsl::from_color(c),
Self::Luma(c) => Hsl::from_color_unclamped(c),
// Perform sRGB gamut mapping by converting to Okhsv first. // Perform sRGB gamut mapping by converting to Okhsv first.
// This yields better results than clamping. // This yields better results than clamping.
Self::Oklab(c) => Hsl::from_color_unclamped(Okhsva::from_color(c)), Self::Oklab(c) => Hsl::from_color(Okhsva::from_color(c)),
Self::Oklch(c) => Hsl::from_color_unclamped(Okhsva::from_color(c)), Self::Oklch(c) => Hsl::from_color(Okhsva::from_color(c)),
// No clamping necessary because these color spaces are all within sRGB, same as [`Hsl`]. Self::Rgb(c) => Hsl::from_color(c),
Self::Rgb(c) => Hsl::from_color_unclamped(c), Self::LinearRgb(c) => Hsl::from_color(Rgb::from_linear(c)),
Self::LinearRgb(c) => Hsl::from_color_unclamped(Rgb::from_linear(c)), Self::Cmyk(c) => Hsl::from_color(c.to_rgba()),
Self::Cmyk(c) => Hsl::from_color_unclamped(c.to_rgba()),
Self::Hsl(c) => c, Self::Hsl(c) => c,
Self::Hsv(c) => Hsl::from_color_unclamped(c), Self::Hsv(c) => Hsl::from_color(c),
}) })
} }
pub fn to_hsv(self) -> Self { pub fn to_hsv(self) -> Self {
Self::Hsv(match self { Self::Hsv(match self {
// No clamping necessary because Luma is within sRGB, same as [`Hsv`]. Self::Luma(c) => Hsv::from_color(c),
Self::Luma(c) => Hsv::from_color_unclamped(c),
// Perform sRGB gamut mapping by converting to Okhsv first. // Perform sRGB gamut mapping by converting to Okhsv first.
// This yields better results than clamping. // This yields better results than clamping.
Self::Oklab(c) => Hsv::from_color_unclamped(Okhsva::from_color(c)), Self::Oklab(c) => Hsv::from_color(Okhsva::from_color(c)),
Self::Oklch(c) => Hsv::from_color_unclamped(Okhsva::from_color(c)), Self::Oklch(c) => Hsv::from_color(Okhsva::from_color(c)),
// No clamping necessary because these color spaces are all within sRGB, same as [`Hsv`]. Self::Rgb(c) => Hsv::from_color(c),
Self::Rgb(c) => Hsv::from_color_unclamped(c), Self::LinearRgb(c) => Hsv::from_color(Rgb::from_linear(c)),
Self::LinearRgb(c) => Hsv::from_color_unclamped(Rgb::from_linear(c)), Self::Cmyk(c) => Hsv::from_color(c.to_rgba()),
Self::Cmyk(c) => Hsv::from_color_unclamped(c.to_rgba()), Self::Hsl(c) => Hsv::from_color(c),
Self::Hsl(c) => Hsv::from_color_unclamped(c),
Self::Hsv(c) => c, Self::Hsv(c) => c,
}) })
} }