From 4af99884ead82435b2cb45b3b83938c31240e7b1 Mon Sep 17 00:00:00 2001 From: wyhaya Date: Tue, 13 Dec 2022 15:02:47 +0800 Subject: [PATCH 01/12] Optimization Color::hex --- crates/bevy_render/Cargo.toml | 1 - crates/bevy_render/src/color/mod.rs | 137 ++++++++++++---------------- 2 files changed, 58 insertions(+), 80 deletions(-) diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index 605871172c2ec..ad6dd6e969095 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -61,7 +61,6 @@ thread_local = "1.1" thiserror = "1.0" futures-lite = "1.4.0" anyhow = "1.0" -hex = "0.4.2" hexasphere = "8.0" parking_lot = "0.12.1" regex = "1.5" diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index 4fe72e7c3b348..ebdc5e0cfe0bc 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -253,39 +253,30 @@ impl Color { /// ``` /// pub fn hex>(hex: T) -> Result { - 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()); + match hex.as_ref().as_bytes() { + // RGB + &[r, g, b] => match decode_hex([r, r, g, g, b, b]) { + Ok([r, g, b, ..]) => Ok(Color::rgb_u8(r, g, b)), + Err(byte) => Err(HexColorError::Char(byte as char)), + }, + // RGBA + &[r, g, b, a] => match decode_hex([r, r, g, g, b, b, a, a]) { + Ok([r, g, b, a, ..]) => Ok(Color::rgba_u8(r, g, b, a)), + Err(byte) => Err(HexColorError::Char(byte as char)), + }, + // RRGGBB + &[r1, r2, g1, g2, b1, b2] => match decode_hex([r1, r2, g1, g2, b1, b2]) { + Ok([r, g, b, ..]) => Ok(Color::rgb_u8(r, g, b)), + Err(byte) => Err(HexColorError::Char(byte as char)), + }, + // RRGGBBAA + &[r1, r2, g1, g2, b1, b2, a1, a2] => match decode_hex([r1, r2, g1, g2, b1, b2, a1, a2]) + { + Ok([r, g, b, a, ..]) => Ok(Color::rgba_u8(r, g, b, a)), + Err(byte) => Err(HexColorError::Char(byte as char)), + }, + _ => return Err(HexColorError::Length), } - - Err(HexColorError::Length) } /// New `Color` from sRGB colorspace. @@ -1332,38 +1323,38 @@ impl encase::private::CreateFrom for Color { impl encase::ShaderSize for Color {} -#[derive(Debug, Error)] +#[derive(Debug, Error, PartialEq, Eq)] pub enum HexColorError { #[error("Unexpected length of hex string")] Length, - #[error("Error parsing hex value")] - Hex(#[from] hex::FromHexError), + #[error("Invalid hex char")] + Char(char), } -fn decode_rgb(data: &[u8]) -> Result { - 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)), +const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], u8> { + let mut i = 0; + while i < bytes.len() { + let val = match hex_ascii_byte(bytes[i]) { + Ok(val) => val, + Err(byte) => return Err(byte), + }; + bytes[i] = val; + i += 1; + } + i = 0; + while i < bytes.len() / 2 { + bytes[i] = bytes[i * 2] << 4 | bytes[i * 2 + 1]; + i += 1; } + Ok(bytes) } -fn decode_rgba(data: &[u8]) -> Result { - 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)), +const fn hex_ascii_byte(b: u8) -> Result { + match b { + b'0'..=b'9' => Ok(b - b'0'), + b'A'..=b'F' => Ok(b - b'A' + 10), + b'a'..=b'f' => Ok(b - b'a' + 10), + _ => Err(b), } } @@ -1373,29 +1364,17 @@ mod tests { #[test] fn 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()); + assert_eq!(Color::hex("FFF").unwrap(), Color::WHITE); + assert_eq!(Color::hex("FFFF").unwrap(), Color::WHITE); + assert_eq!(Color::hex("FFFFFF").unwrap(), Color::WHITE); + assert_eq!(Color::hex("FFFFFFFF").unwrap(), Color::WHITE); + assert_eq!(Color::hex("000").unwrap(), Color::BLACK); + assert_eq!(Color::hex("000F").unwrap(), Color::BLACK); + assert_eq!(Color::hex("000000").unwrap(), Color::BLACK); + assert_eq!(Color::hex("000000FF").unwrap(), Color::BLACK); + assert_eq!(Color::hex("03a9f4").unwrap(), Color::rgb_u8(3, 169, 244)); + assert_eq!(Color::hex("yy"), Err(HexColorError::Length)); + assert_eq!(Color::hex("yyy"), Err(HexColorError::Char('y'))); } #[test] From 584adb0667fa368285f440235840af338eb0713e Mon Sep 17 00:00:00 2001 From: wyhaya Date: Tue, 13 Dec 2022 15:52:13 +0800 Subject: [PATCH 02/12] Fix clippy --- crates/bevy_render/src/color/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index ebdc5e0cfe0bc..f29dbf5c2d166 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -253,24 +253,24 @@ impl Color { /// ``` /// pub fn hex>(hex: T) -> Result { - match hex.as_ref().as_bytes() { + match *hex.as_ref().as_bytes() { // RGB - &[r, g, b] => match decode_hex([r, r, g, g, b, b]) { + [r, g, b] => match decode_hex([r, r, g, g, b, b]) { Ok([r, g, b, ..]) => Ok(Color::rgb_u8(r, g, b)), Err(byte) => Err(HexColorError::Char(byte as char)), }, // RGBA - &[r, g, b, a] => match decode_hex([r, r, g, g, b, b, a, a]) { + [r, g, b, a] => match decode_hex([r, r, g, g, b, b, a, a]) { Ok([r, g, b, a, ..]) => Ok(Color::rgba_u8(r, g, b, a)), Err(byte) => Err(HexColorError::Char(byte as char)), }, // RRGGBB - &[r1, r2, g1, g2, b1, b2] => match decode_hex([r1, r2, g1, g2, b1, b2]) { + [r1, r2, g1, g2, b1, b2] => match decode_hex([r1, r2, g1, g2, b1, b2]) { Ok([r, g, b, ..]) => Ok(Color::rgb_u8(r, g, b)), Err(byte) => Err(HexColorError::Char(byte as char)), }, // RRGGBBAA - &[r1, r2, g1, g2, b1, b2, a1, a2] => match decode_hex([r1, r2, g1, g2, b1, b2, a1, a2]) + [r1, r2, g1, g2, b1, b2, a1, a2] => match decode_hex([r1, r2, g1, g2, b1, b2, a1, a2]) { Ok([r, g, b, a, ..]) => Ok(Color::rgba_u8(r, g, b, a)), Err(byte) => Err(HexColorError::Char(byte as char)), From 6665776e50d0811382a26179283cee6f23a9486e Mon Sep 17 00:00:00 2001 From: wyhaya Date: Tue, 13 Dec 2022 16:05:03 +0800 Subject: [PATCH 03/12] Fix cargo fmt --- crates/bevy_render/src/color/mod.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index f29dbf5c2d166..f961428c32efa 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -270,11 +270,12 @@ impl Color { Err(byte) => Err(HexColorError::Char(byte as char)), }, // RRGGBBAA - [r1, r2, g1, g2, b1, b2, a1, a2] => match decode_hex([r1, r2, g1, g2, b1, b2, a1, a2]) - { - Ok([r, g, b, a, ..]) => Ok(Color::rgba_u8(r, g, b, a)), - Err(byte) => Err(HexColorError::Char(byte as char)), - }, + [r1, r2, g1, g2, b1, b2, a1, a2] => { + match decode_hex([r1, r2, g1, g2, b1, b2, a1, a2]) { + Ok([r, g, b, a, ..]) => Ok(Color::rgba_u8(r, g, b, a)), + Err(byte) => Err(HexColorError::Char(byte as char)), + } + } _ => return Err(HexColorError::Length), } } From cb4d1b8570b641cd1228cdc0f348fc7ad165ecd2 Mon Sep 17 00:00:00 2001 From: wyhaya Date: Tue, 13 Dec 2022 16:14:34 +0800 Subject: [PATCH 04/12] Fix cargo clippy --- crates/bevy_render/src/color/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index f961428c32efa..483a8e79ca653 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -276,7 +276,7 @@ impl Color { Err(byte) => Err(HexColorError::Char(byte as char)), } } - _ => return Err(HexColorError::Length), + _ => Err(HexColorError::Length), } } From 097d405118cd807e5f0e3cfca95692833869f3f8 Mon Sep 17 00:00:00 2001 From: wyhaya Date: Tue, 13 Dec 2022 19:19:57 +0800 Subject: [PATCH 05/12] Improve readability --- crates/bevy_render/src/color/mod.rs | 34 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index 483a8e79ca653..e817377c77680 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -255,26 +255,24 @@ impl Color { pub fn hex>(hex: T) -> Result { match *hex.as_ref().as_bytes() { // RGB - [r, g, b] => match decode_hex([r, r, g, g, b, b]) { - Ok([r, g, b, ..]) => Ok(Color::rgb_u8(r, g, b)), - Err(byte) => Err(HexColorError::Char(byte as char)), - }, + [r, g, b] => { + let [r, g, b, ..] = decode_hex([r, r, g, g, b, b])?; + Ok(Color::rgb_u8(r, g, b)) + } // RGBA - [r, g, b, a] => match decode_hex([r, r, g, g, b, b, a, a]) { - Ok([r, g, b, a, ..]) => Ok(Color::rgba_u8(r, g, b, a)), - Err(byte) => Err(HexColorError::Char(byte as char)), - }, + [r, g, b, a] => { + let [r, g, b, a, ..] = decode_hex([r, r, g, g, b, b, a, a])?; + Ok(Color::rgba_u8(r, g, b, a)) + } // RRGGBB - [r1, r2, g1, g2, b1, b2] => match decode_hex([r1, r2, g1, g2, b1, b2]) { - Ok([r, g, b, ..]) => Ok(Color::rgb_u8(r, g, b)), - Err(byte) => Err(HexColorError::Char(byte as char)), - }, + [r1, r2, g1, g2, b1, b2] => { + let [r, g, b, ..] = decode_hex([r1, r2, g1, g2, b1, b2])?; + Ok(Color::rgb_u8(r, g, b)) + } // RRGGBBAA [r1, r2, g1, g2, b1, b2, a1, a2] => { - match decode_hex([r1, r2, g1, g2, b1, b2, a1, a2]) { - Ok([r, g, b, a, ..]) => Ok(Color::rgba_u8(r, g, b, a)), - Err(byte) => Err(HexColorError::Char(byte as char)), - } + let [r, g, b, a, ..] = decode_hex([r1, r2, g1, g2, b1, b2, a1, a2])?; + Ok(Color::rgba_u8(r, g, b, a)) } _ => Err(HexColorError::Length), } @@ -1332,12 +1330,12 @@ pub enum HexColorError { Char(char), } -const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], u8> { +const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexColorError> { let mut i = 0; while i < bytes.len() { let val = match hex_ascii_byte(bytes[i]) { Ok(val) => val, - Err(byte) => return Err(byte), + Err(byte) => return Err(HexColorError::Char(byte as char)), }; bytes[i] = val; i += 1; From f0ee6178ca712b09277a5916b492df631e73f716 Mon Sep 17 00:00:00 2001 From: wyhaya Date: Tue, 13 Dec 2022 21:20:40 +0800 Subject: [PATCH 06/12] Add decode hex comment --- crates/bevy_render/src/color/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index e817377c77680..b3e361cc8956e 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -1330,9 +1330,14 @@ pub enum HexColorError { Char(char), } +// Convert hex to rgb[a] u8 +// For rgb: `fff` -> [u8; 6] -> [r, g, b, ..] +// For rgba: `E2E2E2FF` -> [u8; 8] -> [r, g, b, a, ..] const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexColorError> { let mut i = 0; while i < bytes.len() { + // Convert hex to u8 + // e.g `f` -> 102 -> 15 let val = match hex_ascii_byte(bytes[i]) { Ok(val) => val, Err(byte) => return Err(HexColorError::Char(byte as char)), @@ -1342,6 +1347,8 @@ const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexCo } i = 0; while i < bytes.len() / 2 { + // Convert u8 to r/g/b/a + // e.g `ff` -> [102, 102] -> [15, 15] = 255 bytes[i] = bytes[i * 2] << 4 | bytes[i * 2 + 1]; i += 1; } From 6f243139b6b3526038ee3ecba316f7235c668e83 Mon Sep 17 00:00:00 2001 From: wyhaya Date: Wed, 14 Dec 2022 13:59:55 +0800 Subject: [PATCH 07/12] Update crates/bevy_render/src/color/mod.rs Co-authored-by: James Liu --- crates/bevy_render/src/color/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index b3e361cc8956e..21399962c82a7 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -1330,9 +1330,11 @@ pub enum HexColorError { Char(char), } -// Convert hex to rgb[a] u8 -// For rgb: `fff` -> [u8; 6] -> [r, g, b, ..] -// For rgba: `E2E2E2FF` -> [u8; 8] -> [r, g, b, a, ..] +/// Converts ASCII hex digits to an array of rgb[a] components +/// +/// # Example +/// For RGB: "fff" -> `[255, 255, 255, ..]` +/// For RGBA: "E2E2E2FF" -> `[226, 226, 226, 255, ..]` const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexColorError> { let mut i = 0; while i < bytes.len() { From e2ff7c883faddf03cdde457ed307267594f9c27c Mon Sep 17 00:00:00 2001 From: wyhaya Date: Wed, 14 Dec 2022 14:28:40 +0800 Subject: [PATCH 08/12] Update decode_hex and test --- crates/bevy_render/src/color/mod.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index 21399962c82a7..e300f8c310be5 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -1347,11 +1347,12 @@ const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexCo bytes[i] = val; i += 1; } + // Modify the original bytes to give an `N / 2` length result i = 0; while i < bytes.len() / 2 { // Convert u8 to r/g/b/a // e.g `ff` -> [102, 102] -> [15, 15] = 255 - bytes[i] = bytes[i * 2] << 4 | bytes[i * 2 + 1]; + bytes[i] = bytes[i * 2] * 16 + bytes[i * 2 + 1]; i += 1; } Ok(bytes) @@ -1372,15 +1373,15 @@ mod tests { #[test] fn hex_color() { - assert_eq!(Color::hex("FFF").unwrap(), Color::WHITE); - assert_eq!(Color::hex("FFFF").unwrap(), Color::WHITE); - assert_eq!(Color::hex("FFFFFF").unwrap(), Color::WHITE); - assert_eq!(Color::hex("FFFFFFFF").unwrap(), Color::WHITE); - assert_eq!(Color::hex("000").unwrap(), Color::BLACK); - assert_eq!(Color::hex("000F").unwrap(), Color::BLACK); - assert_eq!(Color::hex("000000").unwrap(), Color::BLACK); - assert_eq!(Color::hex("000000FF").unwrap(), Color::BLACK); - assert_eq!(Color::hex("03a9f4").unwrap(), Color::rgb_u8(3, 169, 244)); + assert_eq!(Color::hex("FFF"), Ok(Color::WHITE)); + assert_eq!(Color::hex("FFFF"), Ok(Color::WHITE)); + assert_eq!(Color::hex("FFFFFF"), Ok(Color::WHITE)); + assert_eq!(Color::hex("FFFFFFFF"), Ok(Color::WHITE)); + assert_eq!(Color::hex("000"), Ok(Color::BLACK)); + assert_eq!(Color::hex("000F"), Ok(Color::BLACK)); + assert_eq!(Color::hex("000000"), Ok(Color::BLACK)); + assert_eq!(Color::hex("000000FF"), Ok(Color::BLACK)); + assert_eq!(Color::hex("03a9f4"), Ok(Color::rgb_u8(3, 169, 244))); assert_eq!(Color::hex("yy"), Err(HexColorError::Length)); assert_eq!(Color::hex("yyy"), Err(HexColorError::Char('y'))); } From 7c578a6f235d70d78858aa342555af37033ee56f Mon Sep 17 00:00:00 2001 From: wyhaya Date: Wed, 14 Dec 2022 14:48:24 +0800 Subject: [PATCH 09/12] Fix doc --- crates/bevy_render/src/color/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index e300f8c310be5..744c3e269afa3 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -1330,7 +1330,7 @@ pub enum HexColorError { Char(char), } -/// Converts ASCII hex digits to an array of rgb[a] components +/// Converts ASCII hex digits to an array of rgb\[a\] components /// /// # Example /// For RGB: "fff" -> `[255, 255, 255, ..]` From 4fadb222d8027513de8833b80f8902f50fae3c2a Mon Sep 17 00:00:00 2001 From: wyhaya Date: Thu, 15 Dec 2022 13:05:11 +0800 Subject: [PATCH 10/12] Add hex color comment --- crates/bevy_render/src/color/mod.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index 744c3e269afa3..08323ef1f989e 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -1330,17 +1330,16 @@ pub enum HexColorError { Char(char), } -/// Converts ASCII hex digits to an array of rgb\[a\] components +/// Converts hex bytes to an array of rgb\[a\] components /// /// # Example -/// For RGB: "fff" -> `[255, 255, 255, ..]` -/// For RGBA: "E2E2E2FF" -> `[226, 226, 226, 255, ..]` +/// For RGB: *b"ffffff" -> [255, 255, 255, ..] +/// For RGBA: *b"E2E2E2FF" -> [226, 226, 226, 255, ..] const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexColorError> { let mut i = 0; while i < bytes.len() { - // Convert hex to u8 - // e.g `f` -> 102 -> 15 - let val = match hex_ascii_byte(bytes[i]) { + // Convert single hex character to u8 + let val = match hex_value(bytes[i]) { Ok(val) => val, Err(byte) => return Err(HexColorError::Char(byte as char)), }; @@ -1358,11 +1357,13 @@ const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexCo Ok(bytes) } -const fn hex_ascii_byte(b: u8) -> Result { +/// Parse a single hex character (a-f/A-F/0-9) as a `u8` +const fn hex_value(b: u8) -> Result { match b { b'0'..=b'9' => Ok(b - b'0'), b'A'..=b'F' => Ok(b - b'A' + 10), b'a'..=b'f' => Ok(b - b'a' + 10), + // Wrong hex character _ => Err(b), } } From 869e852dc0a883bf7414ab0fdcd6150f57bf2c6d Mon Sep 17 00:00:00 2001 From: wyhaya Date: Fri, 16 Dec 2022 14:22:07 +0800 Subject: [PATCH 11/12] Update comment --- crates/bevy_render/src/color/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index 08323ef1f989e..714c9c2b7805a 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -1330,7 +1330,7 @@ pub enum HexColorError { Char(char), } -/// Converts hex bytes to an array of rgb\[a\] components +/// Converts hex bytes to an array of RGB\[A\] components /// /// # Example /// For RGB: *b"ffffff" -> [255, 255, 255, ..] @@ -1338,7 +1338,7 @@ pub enum HexColorError { const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexColorError> { let mut i = 0; while i < bytes.len() { - // Convert single hex character to u8 + // Convert single hex digit to u8 let val = match hex_value(bytes[i]) { Ok(val) => val, Err(byte) => return Err(HexColorError::Char(byte as char)), @@ -1349,7 +1349,7 @@ const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexCo // Modify the original bytes to give an `N / 2` length result i = 0; while i < bytes.len() / 2 { - // Convert u8 to r/g/b/a + // Convert pairs of u8 to R/G/B/A // e.g `ff` -> [102, 102] -> [15, 15] = 255 bytes[i] = bytes[i * 2] * 16 + bytes[i * 2 + 1]; i += 1; @@ -1357,13 +1357,13 @@ const fn decode_hex(mut bytes: [u8; N]) -> Result<[u8; N], HexCo Ok(bytes) } -/// Parse a single hex character (a-f/A-F/0-9) as a `u8` +/// Parse a single hex digit (a-f/A-F/0-9) as a `u8` const fn hex_value(b: u8) -> Result { match b { b'0'..=b'9' => Ok(b - b'0'), b'A'..=b'F' => Ok(b - b'A' + 10), b'a'..=b'f' => Ok(b - b'a' + 10), - // Wrong hex character + // Wrong hex digit _ => Err(b), } } From 87dfb20de9a9fcf682cf827af8adb5540aa9f172 Mon Sep 17 00:00:00 2001 From: wyhaya Date: Tue, 17 Jan 2023 12:34:55 +0800 Subject: [PATCH 12/12] Add hex prefix color test --- crates/bevy_render/src/color/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index e45a36c506222..b2d0311a05179 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -1391,6 +1391,10 @@ mod tests { assert_eq!(Color::hex("03a9f4"), Ok(Color::rgb_u8(3, 169, 244))); assert_eq!(Color::hex("yy"), Err(HexColorError::Length)); assert_eq!(Color::hex("yyy"), Err(HexColorError::Char('y'))); + assert_eq!(Color::hex("#f2a"), Ok(Color::rgb_u8(255, 34, 170))); + assert_eq!(Color::hex("#e23030"), Ok(Color::rgb_u8(226, 48, 48))); + assert_eq!(Color::hex("#ff"), Err(HexColorError::Length)); + assert_eq!(Color::hex("##fff"), Err(HexColorError::Char('#'))); } #[test]