1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
5pub struct Color {
6 pub r: u8,
7 pub g: u8,
8 pub b: u8,
9 pub a: u8,
10}
11
12impl Color {
13 pub const WHITE: Self = Self::rgb(255, 255, 255);
14 pub const BLACK: Self = Self::rgb(0, 0, 0);
15 pub const RED: Self = Self::rgb(255, 0, 0);
16 pub const GREEN: Self = Self::rgb(0, 255, 0);
17 pub const BLUE: Self = Self::rgb(0, 0, 255);
18 pub const YELLOW: Self = Self::rgb(255, 255, 0);
19 pub const CYAN: Self = Self::rgb(0, 255, 255);
20 pub const MAGENTA: Self = Self::rgb(255, 0, 255);
21
22 pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
23 Self::rgba(r, g, b, 255)
24 }
25
26 pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
27 Self { r, g, b, a }
28 }
29}
30
31impl From<u32> for Color {
32 fn from(value: u32) -> Self {
33 let r = ((value >> 24) & 0xFF) as u8;
34 let g = ((value >> 16) & 0xFF) as u8;
35 let b = ((value >> 8) & 0xFF) as u8;
36 let a = (value & 0xFF) as u8;
37
38 Color::rgba(r, g, b, a)
39 }
40}
41
42impl From<Color> for u32 {
43 fn from(value: Color) -> Self {
44 let r = value.r as u32;
45 let g = value.g as u32;
46 let b = value.b as u32;
47 let a = value.a as u32;
48
49 (r << 24) | (g << 16) | (b << 8) | a
50 }
51}
52
53#[cfg(feature = "bevy")]
54mod _bevy {
55 use super::*;
56
57 impl From<bevy::color::Color> for Color {
58 fn from(value: bevy::color::Color) -> Self {
59 let value = value.to_srgba();
60
61 Self::rgba(
62 (value.red * 255.0) as u8,
63 (value.green * 255.0) as u8,
64 (value.blue * 255.0) as u8,
65 (value.alpha * 255.0) as u8,
66 )
67 }
68 }
69
70 impl From<Color> for bevy::color::Color {
71 fn from(value: Color) -> Self {
72 bevy::color::Color::srgba(
73 value.r as f32 / 255.0,
74 value.g as f32 / 255.0,
75 value.b as f32 / 255.0,
76 value.a as f32 / 255.0,
77 )
78 }
79 }
80}
81
82#[cfg(feature = "image")]
83mod _image {
84 use super::*;
85
86 impl From<image::Rgba<u8>> for Color {
87 fn from(value: image::Rgba<u8>) -> Self {
88 Self::rgba(value[0], value[1], value[2], value[3])
89 }
90 }
91
92 impl From<Color> for image::Rgba<u8> {
93 fn from(value: Color) -> Self {
94 [value.r, value.g, value.b, value.a].into()
95 }
96 }
97}
98
99pub mod textures {
100 use std::borrow::Cow;
101
102 use serde::{Deserialize, Serialize};
103
104 use crate::{
105 content::ContentId,
106 math::{Rectangle, UVec2},
107 };
108
109 use super::Color;
110
111 #[derive(Clone, Serialize, Deserialize)]
113 pub struct TextureCreationOptions<'a> {
114 pub width: u32,
116 pub height: u32,
118 pub data: Option<Cow<'a, [u8]>>,
120 }
121
122 #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
124 #[serde(transparent)]
125 pub struct TextureHandle(u32);
126
127 #[cfg(feature = "internal")]
128 impl TextureHandle {
129 pub fn new(value: u32) -> Self {
131 Self(value)
132 }
133
134 pub fn id(&self) -> u32 {
136 self.0
137 }
138 }
139
140 #[derive(Clone, Serialize, Deserialize)]
142 pub enum TextureAction {
143 Clear(Color),
145 DrawPixels(Box<[DrawPixel]>),
147 DrawRect {
149 start: UVec2,
150 end: UVec2,
151 color: Color,
152 },
153 DrawText {
155 font: ContentId,
156 text: String,
157 top_left: UVec2,
158 letter_spacing: u32,
159 full_color: Option<Color>,
160 alpha_mode: AlphaMode,
161 },
162 DrawScriptTexture {
168 handle: TextureHandle,
169 options: DrawTextureOpts,
170 },
171 }
172
173 #[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
175 pub enum AlphaMode {
176 #[default]
179 Opaque,
180 Mask(f32),
184 Blend,
187 }
188
189 #[derive(Default, Clone, Copy, Serialize, Deserialize)]
191 pub struct DrawTextureOpts {
192 pub source_rect: Option<Rectangle>,
194 pub target_rect: Option<Rectangle>,
196 }
197
198 #[derive(Clone, Copy, Serialize, Deserialize)]
200 pub struct DrawPixel {
201 pub pos: UVec2,
203 pub color: Color,
205 }
206
207 impl From<(UVec2, Color)> for DrawPixel {
208 fn from((position, color): (UVec2, Color)) -> Self {
209 Self {
210 pos: position,
211 color,
212 }
213 }
214 }
215
216 impl From<(u32, u32, Color)> for DrawPixel {
217 fn from((x, y, color): (u32, u32, Color)) -> Self {
218 Self {
219 pos: UVec2 { x, y },
220 color,
221 }
222 }
223 }
224}