Skip to main content

gust_render/
color.rs

1//! Color handling module
2
3use std::ops::Add;
4use std::ops::Mul;
5use std::ops::Sub;
6
7#[derive(Debug, Clone, Copy, PartialEq)]
8pub struct Color(pub f32, pub f32, pub f32, pub f32);
9
10lazy_static! {
11    static ref WHITE: Color = Color(1.0, 1.0, 1.0, 1.0);
12    static ref BLACK: Color = Color(0.0, 0.0, 0.0, 1.0);
13    static ref RED: Color = Color(1.0, 0.0, 0.0, 1.0);
14    static ref GREEN: Color = Color(0.0, 1.0, 0.0, 1.0);
15    static ref BLUE: Color = Color(0.0, 0.0, 1.0, 1.0);
16}
17
18/// Color class
19impl Color {
20    /// Create a color with the alpha
21    pub fn new_alpha(r: f32, g: f32, b: f32, a: f32) -> Color {
22        Color(r, g, b, a)
23    }
24
25    /// Create a new color
26    pub fn new(r: f32, g: f32, b: f32) -> Color {
27        Color(r, g, b, 1.0)
28    }
29
30    pub fn white() -> Color {
31        *self::WHITE
32    }
33
34    pub fn red() -> Color {
35        Color(1.0, 0.0, 0.0, 1.0)
36    }
37
38    pub fn green() -> Color {
39        Color(0.0, 1.0, 0.0, 1.0)
40    }
41
42    pub fn blue() -> Color {
43        Color(0.0, 0.0, 1.0, 1.0)
44    }
45
46    pub fn black() -> Color {
47        Color(0.0, 0.0, 0.0, 1.0)
48    }
49}
50
51// Adding ops trait ----------------------------------------------------<
52
53impl Add for Color {
54    type Output = Color;
55
56    fn add(self, other: Color) -> Color {
57        Color(
58            self.0 + other.0,
59            self.1 + other.1,
60            self.2 + other.2,
61            self.3 + other.3,
62        )
63    }
64}
65
66impl Sub for Color {
67    type Output = Color;
68
69    fn sub(self, other: Color) -> Color {
70        Color(
71            self.0 - other.0,
72            self.1 - other.1,
73            self.2 - other.2,
74            self.3 - other.3,
75        )
76    }
77}
78
79impl Mul for Color {
80    type Output = Color;
81
82    fn mul(self, other: Color) -> Color {
83        Color(
84            self.0 * other.0,
85            self.1 * other.1,
86            self.2 * other.2,
87            self.3 * other.3,
88        )
89    }
90}
91
92impl Into<[u8; 4]> for Color {
93    fn into(self) -> [u8; 4] {
94        [
95            (self.0 * 255.0) as u8,
96            (self.1 * 255.0) as u8,
97            (self.2 * 255.0) as u8,
98            (self.3 * 255.0) as u8,
99        ]
100    }
101}
102
103impl Into<(u8, u8, u8, u8)> for Color {
104    fn into(self) -> (u8, u8, u8, u8) {
105        (
106            (self.0 * 255.0) as u8,
107            (self.1 * 255.0) as u8,
108            (self.2 * 255.0) as u8,
109            (self.3 * 255.0) as u8,
110        )
111    }
112}
113
114impl Default for Color {
115    fn default() -> Color {
116        Color(1.0, 1.0, 1.0, 1.0)
117    }
118}
119
120#[cfg(test)]
121mod test {
122    use color::Color;
123
124    #[test]
125    fn color_new() {
126        let blue = Color::new(0.0, 0.0, 1.0);
127        assert!(blue.2 == 1.0);
128        assert!(blue.0 == 0.0);
129    }
130
131    #[test]
132    fn color_add() {
133        let red = Color::new(1.0, 0.0, 0.0);
134        let blue = Color::new(0.0, 0.0, 1.0);
135        let purple = red + blue;
136
137        assert!(purple.0 == 1.0 && purple.2 == 1.0);
138    }
139
140    #[test]
141    fn color_sub() {
142        let green = Color::new(0.0, 1.0, 0.0);
143        let marron = Color::new(0.2, 0.2, 0.2);
144        let sub = green - marron;
145
146        assert!(sub.0 == -0.2 && sub.1 == 0.8);
147    }
148
149    fn color_multiply() {
150        let black = Color::new(0.0, 0.0, 0.0);
151        let rdm = Color::new(0.4, 0.0, 0.6);
152        let multiply = black * rdm;
153
154        assert!(multiply.0 == 0.0 && multiply.2 == 0.0);
155    }
156}