diff --git a/CHANGELOG.md b/CHANGELOG.md index f4d86b700..eba0319fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ - api removed: `dc_contact_get_first_name()` #2165 #2171 - implement Consistent Color Generation (XEP-0392), - that results in contact colors be be changed #2228 #2229 + that results in contact colors be be changed #2228 #2229 #2239 - fetch recent existing messages and create corresponding chats after configure #2106 diff --git a/src/color.rs b/src/color.rs index 457b4c25d..9f3b3e947 100644 --- a/src/color.rs +++ b/src/color.rs @@ -16,23 +16,29 @@ fn str_to_angle(s: impl AsRef) -> f64 { f64::from(checksum) / 65536.0 * 360.0 } -/// Converts an identifier to RGB color. +/// Converts RGB tuple to a 24-bit number. /// /// Returns a 24-bit number with 8 least significant bits corresponding to the blue color and 8 /// most significant bits corresponding to the red color. +fn rgb_to_u32((r, g, b): (f64, f64, f64)) -> u32 { + let r = ((r * 256.0) as u32).min(255); + let g = ((g * 256.0) as u32).min(255); + let b = ((b * 256.0) as u32).min(255); + 65536 * r + 256 * g + b +} + +/// Converts an identifier to RGB color. /// /// Saturation is set to maximum (100.0) to make colors distinguishable, and lightness is set to /// half (50.0) to make colors suitable both for light and dark theme. pub(crate) fn str_to_color(s: impl AsRef) -> u32 { - let (r, g, b) = hsluv_to_rgb((str_to_angle(s), 100.0, 50.0)); - 65536 * (r * 256.0) as u32 + 256 * (g * 256.0) as u32 + (b * 256.0) as u32 + rgb_to_u32(hsluv_to_rgb((str_to_angle(s), 100.0, 50.0))) } #[cfg(test)] mod tests { use super::*; - #[allow(clippy::float_cmp)] #[test] fn test_str_to_angle() { // Test against test vectors from @@ -43,4 +49,14 @@ mod tests { assert!((str_to_angle("council") - 359.994507).abs() < 1e-6); assert!((str_to_angle("Board") - 171.430664).abs() < 1e-6); } + + #[test] + fn test_rgb_to_u32() { + assert_eq!(rgb_to_u32((0.0, 0.0, 0.0)), 0); + assert_eq!(rgb_to_u32((1.0, 1.0, 1.0)), 0xffffff); + assert_eq!(rgb_to_u32((0.0, 0.0, 1.0)), 0x0000ff); + assert_eq!(rgb_to_u32((0.0, 1.0, 0.0)), 0x00ff00); + assert_eq!(rgb_to_u32((1.0, 0.0, 0.0)), 0xff0000); + assert_eq!(rgb_to_u32((1.0, 0.5, 0.0)), 0xff8000); + } }