mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 17:36:29 +03:00
color: prevent rare overflow if some component is exactly 1.0
This commit is contained in:
@@ -30,7 +30,7 @@
|
|||||||
- api removed: `dc_contact_get_first_name()` #2165 #2171
|
- api removed: `dc_contact_get_first_name()` #2165 #2171
|
||||||
|
|
||||||
- implement Consistent Color Generation (XEP-0392),
|
- 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
|
- fetch recent existing messages
|
||||||
and create corresponding chats after configure #2106
|
and create corresponding chats after configure #2106
|
||||||
|
|||||||
24
src/color.rs
24
src/color.rs
@@ -16,23 +16,29 @@ fn str_to_angle(s: impl AsRef<str>) -> f64 {
|
|||||||
f64::from(checksum) / 65536.0 * 360.0
|
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
|
/// 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.
|
/// 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
|
/// 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.
|
/// half (50.0) to make colors suitable both for light and dark theme.
|
||||||
pub(crate) fn str_to_color(s: impl AsRef<str>) -> u32 {
|
pub(crate) fn str_to_color(s: impl AsRef<str>) -> u32 {
|
||||||
let (r, g, b) = hsluv_to_rgb((str_to_angle(s), 100.0, 50.0));
|
rgb_to_u32(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[allow(clippy::float_cmp)]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_str_to_angle() {
|
fn test_str_to_angle() {
|
||||||
// Test against test vectors from
|
// 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("council") - 359.994507).abs() < 1e-6);
|
||||||
assert!((str_to_angle("Board") - 171.430664).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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user