1use serde::{Deserialize, Serialize};
2
3#[cfg(feature = "internal")]
4use crate::content::ContentId;
5
6#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
8pub struct Color {
9 pub r: u8,
10 pub g: u8,
11 pub b: u8,
12 pub a: u8,
13}
14
15impl Color {
16 pub const WHITE: Self = Self::rgb(255, 255, 255);
17 pub const BLACK: Self = Self::rgb(0, 0, 0);
18 pub const RED: Self = Self::rgb(255, 0, 0);
19 pub const GREEN: Self = Self::rgb(0, 255, 0);
20 pub const BLUE: Self = Self::rgb(0, 0, 255);
21 pub const YELLOW: Self = Self::rgb(255, 255, 0);
22 pub const CYAN: Self = Self::rgb(0, 255, 255);
23 pub const MAGENTA: Self = Self::rgb(255, 0, 255);
24
25 pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
26 Self::rgba(r, g, b, 255)
27 }
28
29 pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
30 Self { r, g, b, a }
31 }
32}
33
34impl From<u32> for Color {
35 fn from(value: u32) -> Self {
36 let r = ((value >> 24) & 0xFF) as u8;
37 let g = ((value >> 16) & 0xFF) as u8;
38 let b = ((value >> 8) & 0xFF) as u8;
39 let a = (value & 0xFF) as u8;
40
41 Color::rgba(r, g, b, a)
42 }
43}
44
45impl From<Color> for u32 {
46 fn from(value: Color) -> Self {
47 let r = value.r as u32;
48 let g = value.g as u32;
49 let b = value.b as u32;
50 let a = value.a as u32;
51
52 (r << 24) | (g << 16) | (b << 8) | a
53 }
54}
55
56#[cfg(feature = "bevy")]
57mod _bevy {
58 use super::*;
59
60 impl From<bevy::color::Color> for Color {
61 fn from(value: bevy::color::Color) -> Self {
62 let value = value.to_srgba();
63
64 Self::rgba(
65 (value.red * 255.0) as u8,
66 (value.green * 255.0) as u8,
67 (value.blue * 255.0) as u8,
68 (value.alpha * 255.0) as u8,
69 )
70 }
71 }
72
73 impl From<Color> for bevy::color::Color {
74 fn from(value: Color) -> Self {
75 bevy::color::Color::srgba(
76 value.r as f32 / 255.0,
77 value.g as f32 / 255.0,
78 value.b as f32 / 255.0,
79 value.a as f32 / 255.0,
80 )
81 }
82 }
83}
84
85#[cfg(feature = "image")]
86mod _image {
87 use super::*;
88
89 impl From<image::Rgba<u8>> for Color {
90 fn from(value: image::Rgba<u8>) -> Self {
91 Self::rgba(value[0], value[1], value[2], value[3])
92 }
93 }
94
95 impl From<Color> for image::Rgba<u8> {
96 fn from(value: Color) -> Self {
97 [value.r, value.g, value.b, value.a].into()
98 }
99 }
100}
101
102pub mod textures {
103 use std::borrow::Cow;
104
105 use glam::IVec2;
106 use serde::{Deserialize, Serialize};
107
108 use crate::{
109 content::ContentId,
110 math::{Rectangle, UVec2},
111 };
112
113 use super::Color;
114
115 #[derive(Clone, Serialize, Deserialize)]
117 pub struct TextureCreationOptions<'a> {
118 pub width: u32,
120 pub height: u32,
122 pub data: Option<Cow<'a, [u8]>>,
124 pub mipmaps: bool,
126 }
127
128 impl From<(u32, u32)> for TextureCreationOptions<'_> {
129 fn from((width, height): (u32, u32)) -> Self {
130 Self {
131 width,
132 height,
133 data: None,
134 mipmaps: false,
135 }
136 }
137 }
138
139 #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
141 #[serde(transparent)]
142 pub struct TextureHandle(u32);
143
144 #[cfg(feature = "internal")]
145 impl TextureHandle {
146 pub fn new(value: u32) -> Self {
148 Self(value)
149 }
150
151 pub fn id(&self) -> u32 {
153 self.0
154 }
155 }
156
157 #[derive(Clone, Serialize, Deserialize)]
159 pub enum TextureAction {
160 Clear(Color),
162 DrawPixels(Box<[DrawPixel]>),
164 DrawRect {
166 start: UVec2,
167 end: UVec2,
168 color: Color,
169 },
170 DrawText {
172 font: ContentId,
173 text: String,
174 top_left: IVec2,
175 letter_spacing: u32,
176 full_color: Option<Color>,
177 alpha_mode: AlphaMode,
178 target_rect: Option<Rectangle>,
179 },
180 DrawScriptTexture {
186 handle: TextureHandle,
187 options: DrawTextureOpts,
188 },
189 }
190
191 #[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
193 pub enum AlphaMode {
194 #[default]
197 Opaque,
198 Mask(f32),
202 Blend,
205 }
206
207 #[derive(Default, Clone, Copy, Serialize, Deserialize)]
209 pub struct DrawTextureOpts {
210 pub source_rect: Option<Rectangle>,
212 pub target_rect: Option<Rectangle>,
214 }
215
216 #[derive(Clone, Copy, Serialize, Deserialize)]
218 pub struct DrawPixel {
219 pub pos: UVec2,
221 pub color: Color,
223 }
224
225 impl From<(UVec2, Color)> for DrawPixel {
226 fn from((position, color): (UVec2, Color)) -> Self {
227 Self {
228 pos: position,
229 color,
230 }
231 }
232 }
233
234 impl From<(u32, u32, Color)> for DrawPixel {
235 fn from((x, y, color): (u32, u32, Color)) -> Self {
236 Self {
237 pos: UVec2 { x, y },
238 color,
239 }
240 }
241 }
242}
243
244#[cfg(feature = "internal")]
245#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct DrawableTextureProperties {
247 pub width: u32,
248 pub height: u32,
249 pub texture_variable_id: String,
250 pub font: ContentId,
251 pub text_variable_id: String,
252 pub set_color: bool,
253 pub color: Color,
254 pub horizontal_alignment: TextHorizontalAlignment,
255 pub vertical_alignment: TextVerticalAlignment,
256 pub alignment_resolution: u8,
257}
258
259#[cfg(feature = "internal")]
260#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
261pub enum TextHorizontalAlignment {
262 #[default]
263 Center,
264 Left,
265 Right,
266 IntCenterLeft,
267 IntCenterRight,
268}
269
270#[cfg(feature = "internal")]
271#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
272pub enum TextVerticalAlignment {
273 #[default]
274 Center,
275 Top,
276 Bottom,
277}