2018-12-06 22:05:11 +03:00
|
|
|
use serde_derive::{Deserialize, Serialize};
|
2018-12-03 20:49:20 +03:00
|
|
|
use std::fmt;
|
|
|
|
|
|
|
|
// Copy could be reconsidered, but eh
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
2019-09-11 02:41:35 +03:00
|
|
|
pub enum Color {
|
|
|
|
RGBA(f32, f32, f32, f32),
|
2019-09-11 20:46:03 +03:00
|
|
|
// (The texture ID to pass to the shader, (texture width, height))
|
|
|
|
// TODO Plumbing dimensions here is a hack. Need to rearrange Prerender to be able to hold onto
|
|
|
|
// textures.
|
|
|
|
Texture(f32, (f64, f64)),
|
2019-09-11 21:06:57 +03:00
|
|
|
Hatching,
|
2019-09-11 02:41:35 +03:00
|
|
|
}
|
2018-12-03 20:49:20 +03:00
|
|
|
|
|
|
|
impl fmt::Display for Color {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2019-09-11 02:41:35 +03:00
|
|
|
match self {
|
|
|
|
Color::RGBA(r, g, b, a) => write!(f, "Color(r={}, g={}, b={}, a={})", r, g, b, a),
|
2019-09-11 20:46:03 +03:00
|
|
|
Color::Texture(id, (w, h)) => {
|
|
|
|
write!(f, "Color::Texture({}, width={}, height={})", id, w, h)
|
|
|
|
}
|
2019-09-11 21:06:57 +03:00
|
|
|
Color::Hatching => write!(f, "Color::Hatching"),
|
2019-09-11 02:41:35 +03:00
|
|
|
}
|
2018-12-03 20:49:20 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Color {
|
2018-12-22 23:29:34 +03:00
|
|
|
pub const BLACK: Color = Color::rgb_f(0.0, 0.0, 0.0);
|
|
|
|
pub const WHITE: Color = Color::rgb_f(1.0, 1.0, 1.0);
|
|
|
|
pub const RED: Color = Color::rgb_f(1.0, 0.0, 0.0);
|
|
|
|
pub const GREEN: Color = Color::rgb_f(0.0, 1.0, 0.0);
|
|
|
|
pub const BLUE: Color = Color::rgb_f(0.0, 0.0, 1.0);
|
|
|
|
pub const CYAN: Color = Color::rgb_f(0.0, 1.0, 1.0);
|
|
|
|
pub const YELLOW: Color = Color::rgb_f(1.0, 1.0, 0.0);
|
|
|
|
pub const PURPLE: Color = Color::rgb_f(0.5, 0.0, 0.5);
|
|
|
|
pub const PINK: Color = Color::rgb_f(1.0, 0.41, 0.71);
|
2019-02-13 00:42:52 +03:00
|
|
|
pub const ORANGE: Color = Color::rgb_f(1.0, 0.55, 0.0);
|
2018-12-03 20:49:20 +03:00
|
|
|
|
|
|
|
// TODO should assert stuff about the inputs
|
|
|
|
|
2018-12-22 23:29:34 +03:00
|
|
|
// TODO Once f32 can be used in const fn, make these const fn too and clean up call sites
|
2019-08-07 19:41:40 +03:00
|
|
|
// dividing by 255.0. https://github.com/rust-lang/rust/issues/57241
|
2018-12-03 20:49:20 +03:00
|
|
|
pub fn rgb(r: usize, g: usize, b: usize) -> Color {
|
|
|
|
Color::rgba(r, g, b, 1.0)
|
|
|
|
}
|
|
|
|
|
2018-12-22 23:29:34 +03:00
|
|
|
pub const fn rgb_f(r: f32, g: f32, b: f32) -> Color {
|
2019-09-11 02:41:35 +03:00
|
|
|
Color::RGBA(r, g, b, 1.0)
|
2018-12-03 20:49:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn rgba(r: usize, g: usize, b: usize, a: f32) -> Color {
|
2019-09-11 02:41:35 +03:00
|
|
|
Color::RGBA(
|
2018-12-03 20:49:20 +03:00
|
|
|
(r as f32) / 255.0,
|
|
|
|
(g as f32) / 255.0,
|
|
|
|
(b as f32) / 255.0,
|
|
|
|
a,
|
2019-09-11 02:41:35 +03:00
|
|
|
)
|
2018-12-03 20:49:20 +03:00
|
|
|
}
|
|
|
|
|
2018-12-22 23:29:34 +03:00
|
|
|
pub const fn rgba_f(r: f32, g: f32, b: f32, a: f32) -> Color {
|
2019-09-11 02:41:35 +03:00
|
|
|
Color::RGBA(r, g, b, a)
|
2018-12-03 20:49:20 +03:00
|
|
|
}
|
|
|
|
|
2018-12-22 23:14:51 +03:00
|
|
|
pub const fn grey(f: f32) -> Color {
|
2019-09-11 02:41:35 +03:00
|
|
|
Color::RGBA(f, f, f, 1.0)
|
2018-12-03 20:49:20 +03:00
|
|
|
}
|
|
|
|
|
2019-09-11 02:41:35 +03:00
|
|
|
pub fn alpha(&self, a: f32) -> Color {
|
|
|
|
match self {
|
|
|
|
Color::RGBA(r, g, b, _) => Color::RGBA(*r, *g, *b, a),
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
2018-12-03 20:49:20 +03:00
|
|
|
}
|
2019-05-30 20:44:53 +03:00
|
|
|
|
2019-06-08 23:11:20 +03:00
|
|
|
pub fn from_hex(raw: &str) -> Color {
|
|
|
|
// Skip the leading '#'
|
|
|
|
let r = usize::from_str_radix(&raw[1..3], 16).unwrap();
|
|
|
|
let g = usize::from_str_radix(&raw[3..5], 16).unwrap();
|
|
|
|
let b = usize::from_str_radix(&raw[5..7], 16).unwrap();
|
|
|
|
Color::rgb(r, g, b)
|
|
|
|
}
|
2018-12-03 20:49:20 +03:00
|
|
|
}
|