1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! The colour struct module
/// A struct containing RGBA Colours (spelled properly) with some predefind colour consts
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Colour {
    r: f32,
    g: f32,
    b: f32,
    a: f32,
}

impl Colour {
    pub const WHITE: Self = Self {
        r: 1.0,
        g: 1.0,
        b: 1.0,
        a: 1.0,
    };

    pub const BLACK: Self = Self {
        r: 0.0,
        g: 0.0,
        b: 0.0,
        a: 1.0,
    };

    pub const RED: Self = Self {
        r: 1.0,
        g: 0.0,
        b: 0.0,
        a: 1.0,
    };

    pub const GREEN: Self = Self {
        r: 0.0,
        g: 1.0,
        b: 0.0,
        a: 1.0,
    };

    pub const BLUE: Self = Self {
        r: 0.0,
        g: 0.0,
        b: 1.0,
        a: 1.0,
    };

    pub const YELLOW: Self = Self {
        r: 1.0,
        g: 1.0,
        b: 0.0,
        a: 1.0,
    };

    pub const ORANGE: Self = Self {
        r: 1.0,
        g: 0.64705884,
        b: 0.0,
        a: 1.0,
    };

    pub const PINK: Self = Self {
        r: 1.0,
        g: 0.7529412,
        b: 0.79607844,
        a: 1.0,
    };

    pub const BROWN: Self = Self {
        r: 0.63529414,
        g: 0.16470589,
        b: 0.16470589,
        a: 1.0,
    };

    /// Takes a hex string like `#805E4E` and turns into a colour. Can fail if an
    /// invaild string is provided
    pub fn from_hex(hex_str: &str) -> Result<Self, std::num::ParseIntError> {
        let colour_values = i32::from_str_radix(hex_str, 16)?;
        let b = colour_values % 0x100;
        let g = (colour_values - b) / 0x100 % 0x100;
        let r = (colour_values - g) / 0x10000;
        Ok(Self {
            r: r as f32 / 255.0,
            g: g as f32 / 255.0,
            b: b as f32 / 255.0,
            a: 1.0,
        })
    }

    /// Creates a colour from seperate values beteen 0.0 and 255.0
    pub fn from_rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Self {
            r: r / 255.0,
            g: g / 255.0,
            b: b / 255.0,
            a: a / 255.0,
        }
    }

    /// Interpolates between two colours by the specified fraction which should be between 1.0
    /// and 0.0
    pub fn linear_interpolation(start: Colour, end: Colour, fraction: f32) -> Self {
        Self {
            r: (end.r - start.r) * fraction + start.r,
            g: (end.g - start.g) * fraction + start.g,
            b: (end.b - start.b) * fraction + start.b,
            a: (end.a - start.a) * fraction + start.a,
        }
    }

    pub(crate) fn as_raw(&self) -> [f32; 4] {
        [self.r, self.g, self.b, self.a]
    }
}

impl From<Colour> for wgpu::Color {
    fn from(value: Colour) -> Self {
        wgpu::Color {
            r: value.r as f64,
            g: value.g as f64,
            b: value.b as f64,
            a: value.a as f64,
        }
    }
}

impl From<Colour> for crate::glyphon::Color {
    fn from(value: Colour) -> Self {
        // should work as it is always a number betweeon 1-0
        let r = (value.r * 255.0) as u8;
        let g = (value.g * 255.0) as u8;
        let b = (value.b * 255.0) as u8;
        let a = (value.a * 255.0) as u8;
        Self::rgba(r, g, b, a)
    }
}

impl From<Colour> for [f32; 4] {
    fn from(value: Colour) -> Self {
        [value.r, value.g, value.b, value.a]
    }
}