use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}
impl Color {
pub const WHITE: Self = Self::rgb(255, 255, 255);
pub const BLACK: Self = Self::rgb(0, 0, 0);
pub const RED: Self = Self::rgb(255, 0, 0);
pub const GREEN: Self = Self::rgb(0, 255, 0);
pub const BLUE: Self = Self::rgb(0, 0, 255);
pub const YELLOW: Self = Self::rgb(255, 255, 0);
pub const CYAN: Self = Self::rgb(0, 255, 255);
pub const MAGENTA: Self = Self::rgb(255, 0, 255);
pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
Self::rgba(r, g, b, 255)
}
pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
Self { r, g, b, a }
}
}
impl From<u32> for Color {
fn from(value: u32) -> Self {
let r = ((value >> 24) & 0xFF) as u8;
let g = ((value >> 16) & 0xFF) as u8;
let b = ((value >> 8) & 0xFF) as u8;
let a = (value & 0xFF) as u8;
Color::rgba(r, g, b, a)
}
}
impl From<Color> for u32 {
fn from(value: Color) -> Self {
let r = value.r as u32;
let g = value.g as u32;
let b = value.b as u32;
let a = value.a as u32;
(r << 24) | (g << 16) | (b << 8) | a
}
}
#[cfg(feature = "bevy")]
mod _bevy {
use super::*;
impl From<bevy::color::Color> for Color {
fn from(value: bevy::color::Color) -> Self {
let value = value.to_srgba();
Self::rgba(
(value.red * 255.0) as u8,
(value.green * 255.0) as u8,
(value.blue * 255.0) as u8,
(value.alpha * 255.0) as u8,
)
}
}
impl From<Color> for bevy::color::Color {
fn from(value: Color) -> Self {
bevy::color::Color::srgba(
value.r as f32 / 255.0,
value.g as f32 / 255.0,
value.b as f32 / 255.0,
value.a as f32 / 255.0,
)
}
}
}
#[cfg(feature = "image")]
mod _image {
use super::*;
impl From<image::Rgba<u8>> for Color {
fn from(value: image::Rgba<u8>) -> Self {
Self::rgba(value[0], value[1], value[2], value[3])
}
}
impl From<Color> for image::Rgba<u8> {
fn from(value: Color) -> Self {
[value.r, value.g, value.b, value.a].into()
}
}
}
pub mod textures {
use std::borrow::Cow;
use serde::{Deserialize, Serialize};
use crate::{
content::ContentId,
math::{Rectangle, UVec2},
};
use super::Color;
#[derive(Clone, Serialize, Deserialize)]
pub struct TextureCreationOptions<'a> {
pub width: u32,
pub height: u32,
pub data: Option<Cow<'a, [u8]>>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(transparent)]
pub struct TextureHandle(u32);
#[cfg(feature = "internal")]
impl TextureHandle {
pub fn new(value: u32) -> Self {
Self(value)
}
pub fn id(&self) -> u32 {
self.0
}
}
#[derive(Clone, Serialize, Deserialize)]
pub enum TextureAction {
Clear(Color),
DrawPixels(Box<[DrawPixel]>),
DrawRect {
start: UVec2,
end: UVec2,
color: Color,
},
DrawText {
font: ContentId,
text: String,
top_left: UVec2,
letter_spacing: u32,
full_color: Option<Color>,
},
DrawScriptTexture {
handle: TextureHandle,
options: DrawTextureOpts,
},
}
#[derive(Default, Clone, Copy, Serialize, Deserialize)]
pub struct DrawTextureOpts {
pub source_rect: Option<Rectangle>,
pub target_rect: Option<Rectangle>,
}
#[derive(Clone, Copy, Serialize, Deserialize)]
pub struct DrawPixel {
pub pos: UVec2,
pub color: Color,
}
impl From<(UVec2, Color)> for DrawPixel {
fn from((position, color): (UVec2, Color)) -> Self {
Self {
pos: position,
color,
}
}
}
impl From<(u32, u32, Color)> for DrawPixel {
fn from((x, y, color): (u32, u32, Color)) -> Self {
Self {
pos: UVec2 { x, y },
color,
}
}
}
}