xref: /StarryEngine/starry_client/src/base/color.rs (revision bee61dca287acb4b9fd6d747ba3f687aebacab90)
1 use core::fmt;
2 
3 /// 一个像素的颜色值
4 #[derive(Clone, Copy)]
5 pub struct Color {
6     /// ARGB
7     pub data: u32,
8 }
9 
10 #[allow(dead_code)]
11 impl Color {
12     /// 通过RGB值创建颜色(不透明)
13     pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
14         Color {
15             data: 0xFF000000 | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32),
16         }
17     }
18 
19     /// 通过RGBA值创建颜色
20     pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
21         Color {
22             data : ((a as u32) << 24) | ((r as u32) << 16) | (g as u32) << 8 | (b as u32),
23         }
24     }
25 
26     /// 获取R值
27     pub fn r(&self) -> u8 {
28         ((self.data & 0x00FF0000) >> 16) as u8
29     }
30 
31     /// 获取G值
32     pub fn g(&self) -> u8 {
33         ((self.data & 0x0000FF00) >> 8) as u8
34     }
35 
36     /// 获取B值
37     pub fn b(&self) -> u8 {
38         (self.data & 0x000000FF) as u8
39     }
40 
41     /// 获取A值
42     pub fn a(&self) -> u8 {
43         ((self.data & 0xFF000000) >> 24) as u8
44     }
45 
46     /// 颜色插值
47     pub fn interpolate(from_color: Color, to_color: Color, scale: f64) -> Color {
48         let r = Color::value_interpolate(from_color.r(), to_color.r(), scale);
49         let g = Color::value_interpolate(from_color.r(), to_color.r(), scale);
50         let b = Color::value_interpolate(from_color.r(), to_color.r(), scale);
51         let a = Color::value_interpolate(from_color.r(), to_color.r(), scale);
52         Color::rgba(r, g, b, a)
53     }
54 
55     /// 颜色值插值
56     fn value_interpolate(from_value: u8, to_value: u8, scale: f64) -> u8 {
57         ((to_value as f64 - from_value as f64) * scale + from_value as f64) as u8
58     }
59 
60     /// 转化为RGBA字节形式
61     pub fn to_rgba_bytes(&self) -> [u8; 4] {
62         [self.r(), self.g(), self.b(), self.a()]
63     }
64 
65     /// 转化为BGRA字节形式(DragonOS帧缓冲数据格式)
66     pub fn to_bgra_bytes(&self) -> [u8; 4] {
67         [self.b(), self.g(), self.r(), self.a()]
68     }
69 }
70 
71 /// 比较两个颜色值(不考虑透明度)
72 impl PartialEq for Color {
73     fn eq(&self, other: &Self) -> bool {
74         self.r() == other.r() && self.g() == other.g() && self.b() == other.b()
75     }
76 }
77 
78 impl fmt::Debug for Color {
79     fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
80         write!(f, "{:#010X}", { self.data })
81     }
82 }