1use super::Corners;
2use glam::{Vec2, Vec3, Vec4, vec4};
3
4#[derive(Clone, Copy, Debug, PartialEq)]
8pub struct FillColor(Corners<Vec4>);
9
10impl FillColor {
11 pub const fn new(corners: Corners<Vec4>) -> Self {
12 Self(corners)
13 }
14
15 pub const TRANSPARENT: Self = Self::rgba(0., 0., 0., 0.);
17
18 pub const fn transparent() -> Self {
20 Self::TRANSPARENT
21 }
22
23 pub fn is_transparent(&self) -> bool {
27 self.0.top_left.w == 0. &&
28 self.0.top_right.w == 0. &&
29 self.0.bottom_left.w == 0. &&
30 self.0.bottom_right.w == 0.
31 }
32
33 pub fn is_opaque(&self) -> bool {
37 self.0.top_left.w == 1. &&
38 self.0.top_right.w == 1. &&
39 self.0.bottom_left.w == 1. &&
40 self.0.bottom_right.w == 1.
41 }
42
43 pub const fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
45 Self(Corners {
46 top_left: vec4(r, g, b, a),
47 top_right: vec4(r, g, b, a),
48 bottom_left: vec4(r, g, b, a),
49 bottom_right: vec4(r, g, b, a),
50 })
51 }
52
53 pub const fn rgb(r: f32, g: f32, b: f32) -> Self {
55 Self(Corners {
56 top_left: vec4(r, g, b, 1.0),
57 top_right: vec4(r, g, b, 1.0),
58 bottom_left: vec4(r, g, b, 1.0),
59 bottom_right: vec4(r, g, b, 1.0),
60 })
61 }
62
63 pub const fn from_corners(corners: Corners<Vec4>) -> Self {
65 Self(corners)
66 }
67
68 pub const fn corners(&self) -> Corners<Vec4> {
70 self.0
71 }
72
73 pub fn interpolate(&self, uv: Vec2) -> Vec4 {
75 let c = self.corners();
76 let top = c.top_left.lerp(c.top_right, uv.x);
77 let bottom = c.bottom_left.lerp(c.bottom_right, uv.x);
78 top.lerp(bottom, uv.y)
79 }
80}
81
82impl Default for FillColor {
83 fn default() -> Self {
84 Self(Corners::all(vec4(0.0, 0.0, 0.0, 1.0)))
85 }
86}
87
88impl From<Corners<Vec4>> for FillColor {
89 fn from(corners: Corners<Vec4>) -> Self {
90 Self(corners)
91 }
92}
93
94impl From<FillColor> for Corners<Vec4> {
95 fn from(corners: FillColor) -> Self {
96 corners.0
97 }
98}
99
100impl From<Vec4> for FillColor {
101 fn from(value: Vec4) -> Self {
102 Self(Corners::all(value))
103 }
104}
105
106impl From<(f32, f32, f32, f32)> for FillColor {
107 fn from((r, g, b, a): (f32, f32, f32, f32)) -> Self {
108 Self(Corners::all(vec4(r, g, b, a)))
109 }
110}
111
112impl From<[f32; 4]> for FillColor {
113 fn from([r, g, b, a]: [f32; 4]) -> Self {
114 Self(Corners::all(vec4(r, g, b, a)))
115 }
116}
117
118impl From<Vec3> for FillColor {
119 fn from(value: Vec3) -> Self {
120 Self(Corners::all(vec4(value.x, value.y, value.z, 1.0)))
121 }
122}
123
124impl From<(f32, f32, f32)> for FillColor {
125 fn from((r, g, b): (f32, f32, f32)) -> Self {
126 Self(Corners::all(vec4(r, g, b, 1.0)))
127 }
128}
129
130impl From<[f32; 3]> for FillColor {
131 fn from([r, g, b]: [f32; 3]) -> Self {
132 Self(Corners::all(vec4(r, g, b, 1.0)))
133 }
134}
135
136impl From<(Vec4, Vec4, Vec4, Vec4)> for FillColor {
137 fn from((top_left, top_right, bottom_left, bottom_right): (Vec4, Vec4, Vec4, Vec4)) -> Self {
138 Self(Corners { top_left, top_right, bottom_left, bottom_right })
139 }
140}
141
142impl From<((f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32))> for FillColor {
143 fn from(value: ((f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32))) -> Self {
144 Self(Corners {
145 top_left: vec4(value.0.0, value.0.1, value.0.2, value.0.3),
146 top_right: vec4(value.1.0, value.1.1, value.1.2, value.1.3),
147 bottom_left: vec4(value.2.0, value.2.1, value.2.2, value.2.3),
148 bottom_right: vec4(value.3.0, value.3.1, value.3.2, value.3.3),
149 })
150 }
151}
152
153impl From<[[f32; 4]; 4]> for FillColor {
154 fn from(value: [[f32; 4]; 4]) -> Self {
155 Self(Corners {
156 top_left: vec4(value[0][0], value[0][1], value[0][2], value[0][3]),
157 top_right: vec4(value[1][0], value[1][1], value[1][2], value[1][3]),
158 bottom_left: vec4(value[2][0], value[2][1], value[2][2], value[2][3]),
159 bottom_right: vec4(value[3][0], value[3][1], value[3][2], value[3][3]),
160 })
161 }
162}
163
164impl From<Corners<Vec3>> for FillColor {
165 fn from(corners: Corners<Vec3>) -> Self {
166 Self(Corners {
167 top_left: corners.top_left.extend(1.),
168 top_right: corners.top_right.extend(1.),
169 bottom_left: corners.bottom_left.extend(1.),
170 bottom_right: corners.bottom_right.extend(1.),
171 })
172 }
173}
174
175impl From<(Vec3, Vec3, Vec3, Vec3)> for FillColor {
176 fn from((top_left, top_right, bottom_left, bottom_right): (Vec3, Vec3, Vec3, Vec3)) -> Self {
177 Self(Corners {
178 top_left: vec4(top_left.x, top_left.y, top_left.z, 1.0),
179 top_right: vec4(top_right.x, top_right.y, top_right.z, 1.0),
180 bottom_left: vec4(bottom_left.x, bottom_left.y, bottom_left.z, 1.0),
181 bottom_right: vec4(bottom_right.x, bottom_right.y, bottom_right.z, 1.0),
182 })
183 }
184}
185
186impl From<((f32, f32, f32), (f32, f32, f32), (f32, f32, f32), (f32, f32, f32))> for FillColor {
187 fn from(value: ((f32, f32, f32), (f32, f32, f32), (f32, f32, f32), (f32, f32, f32))) -> Self {
188 Self(Corners {
189 top_left: vec4(value.0.0, value.0.1, value.0.2, 1.0),
190 top_right: vec4(value.1.0, value.1.1, value.1.2, 1.0),
191 bottom_left: vec4(value.2.0, value.2.1, value.2.2, 1.0),
192 bottom_right: vec4(value.3.0, value.3.1, value.3.2, 1.0),
193 })
194 }
195}
196
197impl From<[[f32; 3]; 4]> for FillColor {
198 fn from(value: [[f32; 3]; 4]) -> Self {
199 Self(Corners {
200 top_left: vec4(value[0][0], value[0][1], value[0][2], 1.0),
201 top_right: vec4(value[1][0], value[1][1], value[1][2], 1.0),
202 bottom_left: vec4(value[2][0], value[2][1], value[2][2], 1.0),
203 bottom_right: vec4(value[3][0], value[3][1], value[3][2], 1.0),
204 })
205 }
206}