From 41660aee20de6d01f1b8cdf0ba2373eb969b6743 Mon Sep 17 00:00:00 2001 From: Thomas Teixeira Date: Wed, 1 Nov 2023 11:45:44 +0100 Subject: [PATCH] Fix CMYK from-conversion and add it as possible color function --- src/cli/cli.rs | 3 ++- src/lib.rs | 16 +++++----------- src/parser.rs | 29 +++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/cli/cli.rs b/src/cli/cli.rs index b0cccda..37c6ab9 100644 --- a/src/cli/cli.rs +++ b/src/cli/cli.rs @@ -24,7 +24,8 @@ pub fn build_cli() -> Command<'static> { \n - 789\ \n - 'rgb(119, 136, 153)'\ \n - '119,136,153'\ - \n - 'hsl(210, 14.3%, 53.3%)'\n\ + \n - 'hsl(210, 14.3%, 53.3%)'\ + \n - 'cmyk(22, 11, 0, 40)'\n\ Alpha transparency is also supported:\ \n - '#77889980'\ \n - 'rgba(119, 136, 153, 0.5)'\ diff --git a/src/lib.rs b/src/lib.rs index 31b5784..25248c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -960,11 +960,11 @@ impl From<&LCh> for Color { impl From<&CMYK> for Color { fn from(color: &CMYK) -> Self { #![allow(clippy::many_single_char_names)] - let r = 255.0 * ((1.0 - color.c) / 100.0) * ((1.0 - color.k) / 100.0); - let g = 255.0 * ((1.0 - color.m) / 100.0) * ((1.0 - color.k) / 100.0); - let b = 255.0 * ((1.0 - color.y) / 100.0) * ((1.0 - color.k) / 100.0); + let r = Scalar::round(255.0 * (1.0 - color.c / 100.0) * (1.0 - color.k / 100.0)) as u8; + let g = Scalar::round(255.0 * (1.0 - color.m / 100.0) * (1.0 - color.k / 100.0)) as u8; + let b = Scalar::round(255.0 * (1.0 - color.y / 100.0) * (1.0 - color.k / 100.0)) as u8; - Color::from(&RGBA:: { + Color::from(&RGBA:: { r, g, b, @@ -1429,13 +1429,7 @@ impl From<&Color> for CMYK { let r = (rgba.r as f64) / 255.0; let g = (rgba.g as f64) / 255.0; let b = (rgba.b as f64) / 255.0; - let biggest = if r >= g && r >= b { - r - } else if g >= r && g >= b { - g - } else { - b - }; + let biggest = r.max(g).max(b); let out_k = 1.0 - biggest; let out_c = (1.0 - r - out_k) / biggest; let out_m = (1.0 - g - out_k) / biggest; diff --git a/src/parser.rs b/src/parser.rs index 3df10b8..b5df433 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -147,6 +147,24 @@ fn parse_numeric_rgb(input: &str) -> IResult<&str, Color> { Ok((input, c)) } +fn parse_cmyk(input: &str) -> IResult<&str, Color> { + let (input, _) = tag("cmyk(")(input)?; + let (input, _) = space0(input)?; + let (input, c) = double(input)?; + let (input, _) = parse_separator(input)?; + let (input, m) = double(input)?; + let (input, _) = parse_separator(input)?; + let (input, y) = double(input)?; + let (input, _) = parse_separator(input)?; + let (input, k) = double(input)?; + let (input, _) = space0(input)?; + let (input, _) = char(')')(input)?; + + let color = Color::from_cmyk(c, m, y, k); + + Ok((input, color)) +} + fn parse_percentage_rgb(input: &str) -> IResult<&str, Color> { let (input, prefixed) = opt(alt((tag("rgb("), tag("rgba("))))(input)?; let is_prefixed = prefixed.is_some(); @@ -284,6 +302,7 @@ pub fn parse_color(input: &str) -> Option { all_consuming(parse_hex), all_consuming(parse_numeric_rgb), all_consuming(parse_percentage_rgb), + all_consuming(parse_cmyk), all_consuming(parse_hsl), all_consuming(parse_hsv), all_consuming(parse_gray), @@ -380,6 +399,16 @@ fn parse_rgb_standalone_syntax() { assert_eq!(Some(rgb(1, 2, 3)), parse_color("1,2,3")); } +#[test] +fn parse_cmyk_syntax() { + assert_eq!(Some(Color::black()), parse_color("cmyk(0, 0, 0, 100)")); + assert_eq!(Some(Color::white()), parse_color("cmyk(0, 0, 0, 0)")); + assert_eq!(Some(Color::red()), parse_color("cmyk(0, 100, 100, 0)")); + assert_eq!(Some(Color::green()), parse_color("cmyk(100, 0, 100, 50)")); + assert_eq!(Some(Color::blue()), parse_color("cmyk(100, 100,0,0)")); + assert_eq!(Some(Color::yellow()), parse_color("cmyk( 0,0, 100, 0)")); +} + #[test] fn parse_hsl_syntax() { assert_eq!(