Skip to content

Commit

Permalink
Add Color::hex fn (bevyengine#362)
Browse files Browse the repository at this point in the history
Add Color::hex fn
  • Loading branch information
wyhaya authored and mrk-its committed Oct 6, 2020
1 parent b04b0ac commit c8cd47c
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/bevy_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ once_cell = "1.4.0"
downcast-rs = "1.1.1"
thiserror = "1.0"
anyhow = "1.0"
hex = "0.4.2"
hexasphere = "1.0.0"
parking_lot = "0.10"

Expand Down
96 changes: 96 additions & 0 deletions crates/bevy_render/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,42 @@ impl Color {
Color { r, g, b, a }
}

pub fn hex<T: AsRef<str>>(hex: T) -> Result<Color, HexColorError> {
let hex = hex.as_ref();

// RGB
if hex.len() == 3 {
let mut data = [0; 6];
for (i, ch) in hex.chars().enumerate() {
data[i * 2] = ch as u8;
data[i * 2 + 1] = ch as u8;
}
return decode_rgb(&data);
}

// RGBA
if hex.len() == 4 {
let mut data = [0; 8];
for (i, ch) in hex.chars().enumerate() {
data[i * 2] = ch as u8;
data[i * 2 + 1] = ch as u8;
}
return decode_rgba(&data);
}

// RRGGBB
if hex.len() == 6 {
return decode_rgb(hex.as_bytes());
}

// RRGGBBAA
if hex.len() == 8 {
return decode_rgba(hex.as_bytes());
}

Err(HexColorError::Length)
}

pub fn rgb_u8(r: u8, g: u8, b: u8) -> Color {
Color::rgba_u8(r, g, b, u8::MAX)
}
Expand Down Expand Up @@ -219,3 +255,63 @@ impl From<Handle<Texture>> for ColorSource {
}

impl_render_resource_bytes!(Color);

#[derive(Debug)]
pub enum HexColorError {
Length,
Hex(hex::FromHexError),
}

fn decode_rgb(data: &[u8]) -> Result<Color, HexColorError> {
let mut buf = [0; 3];
match hex::decode_to_slice(data, &mut buf) {
Ok(_) => {
let r = buf[0] as f32 / 255.0;
let g = buf[1] as f32 / 255.0;
let b = buf[2] as f32 / 255.0;
Ok(Color::rgb(r, g, b))
}
Err(err) => Err(HexColorError::Hex(err)),
}
}

fn decode_rgba(data: &[u8]) -> Result<Color, HexColorError> {
let mut buf = [0; 4];
match hex::decode_to_slice(data, &mut buf) {
Ok(_) => {
let r = buf[0] as f32 / 255.0;
let g = buf[1] as f32 / 255.0;
let b = buf[2] as f32 / 255.0;
let a = buf[3] as f32 / 255.0;
Ok(Color::rgba(r, g, b, a))
}
Err(err) => Err(HexColorError::Hex(err)),
}
}

#[test]
fn test_hex_color() {
assert_eq!(Color::hex("FFF").unwrap(), Color::rgb(1.0, 1.0, 1.0));
assert_eq!(Color::hex("000").unwrap(), Color::rgb(0.0, 0.0, 0.0));
assert!(Color::hex("---").is_err());

assert_eq!(Color::hex("FFFF").unwrap(), Color::rgba(1.0, 1.0, 1.0, 1.0));
assert_eq!(Color::hex("0000").unwrap(), Color::rgba(0.0, 0.0, 0.0, 0.0));
assert!(Color::hex("----").is_err());

assert_eq!(Color::hex("FFFFFF").unwrap(), Color::rgb(1.0, 1.0, 1.0));
assert_eq!(Color::hex("000000").unwrap(), Color::rgb(0.0, 0.0, 0.0));
assert!(Color::hex("------").is_err());

assert_eq!(
Color::hex("FFFFFFFF").unwrap(),
Color::rgba(1.0, 1.0, 1.0, 1.0)
);
assert_eq!(
Color::hex("00000000").unwrap(),
Color::rgba(0.0, 0.0, 0.0, 0.0)
);
assert!(Color::hex("--------").is_err());

assert!(Color::hex("1234567890").is_err());
}

0 comments on commit c8cd47c

Please sign in to comment.