From 6cd50c2da1219cfcb21da0b82160357c5f932b40 Mon Sep 17 00:00:00 2001 From: newcomb-luke Date: Sat, 7 May 2022 01:10:38 -0400 Subject: [PATCH 1/6] Added ability to convert from a hex string to Color32 using macros --- Cargo.lock | 11 ++++++++-- epaint/Cargo.toml | 3 ++- epaint/src/color.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++ epaint/src/lib.rs | 2 ++ 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9bcdb912967..951c4a7673e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -583,6 +583,12 @@ dependencies = [ "objc", ] +[[package]] +name = "color-hex" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecdffb913a326b6c642290a0d0ec8e8d6597291acdc07cc4c9cb4b3635d44cf9" + [[package]] name = "color_quant" version = "1.1.0" @@ -1293,6 +1299,7 @@ dependencies = [ "atomic_refcell", "bytemuck", "cint", + "color-hex", "criterion", "emath", "nohash-hasher", @@ -3506,7 +3513,7 @@ version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "static_assertions", ] @@ -3856,7 +3863,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a3cffdb686fbb24d9fb8f03a213803277ed2300f11026a3afe1f108dc021b" dependencies = [ "jni", - "ndk-glue 0.5.2", + "ndk-glue 0.6.2", "url", "web-sys", "widestring", diff --git a/epaint/Cargo.toml b/epaint/Cargo.toml index 1c1ff6be3fb..2a39aad026c 100644 --- a/epaint/Cargo.toml +++ b/epaint/Cargo.toml @@ -47,13 +47,14 @@ mint = ["emath/mint"] # implement serde on most types. serde = ["dep:serde", "ahash/serde", "emath/serde"] - [dependencies] emath = { version = "0.18.0", path = "../emath" } ab_glyph = "0.2.11" nohash-hasher = "0.2" +color-hex = "0.2.0" + # Optional: ahash = { version = "0.7", default-features = false, features = ["std"] } bytemuck = { version = "1.7.2", optional = true, features = ["derive"] } diff --git a/epaint/src/color.rs b/epaint/src/color.rs index c88daacf2ed..150b0830547 100644 --- a/epaint/src/color.rs +++ b/epaint/src/color.rs @@ -186,6 +186,59 @@ impl Color32 { } } +#[macro_export] +macro_rules! hex_rgb { + ($s:literal) => {{ + let color: [u8; 3] = $crate::color_hex::color_from_hex!($s); + $crate::Color32::from_rgb(color[0], color[1], color[2]) + }}; +} + +#[macro_export] +macro_rules! hex_rgb_additive { + ($s:literal) => {{ + let color: [u8; 3] = $crate::color_hex::color_from_hex!($s); + $crate::Color32::from_rgb_additive(color[0], color[1], color[2]) + }}; +} + +#[macro_export] +macro_rules! hex_rgba_premultiplied { + ($s:literal) => {{ + let color: [u8; 4] = $crate::color_hex::color_from_hex!($s); + $crate::Color32::from_rgba_premultiplied(color[0], color[1], color[2], color[3]) + }}; +} + +#[macro_export] +macro_rules! hex_rgba_unmultiplied { + ($s:literal) => {{ + let color: [u8; 4] = $crate::color_hex::color_from_hex!($s); + $crate::Color32::from_rgba_unmultiplied(color[0], color[1], color[2], color[3]) + }}; +} + +#[test] +fn test_from_rgb_hex() { + assert_eq!(Color32::from_rgb(0x20, 0x21, 0x22), hex_rgb!("#202122")); + assert_eq!( + Color32::from_rgb_additive(0x20, 0x21, 0x22), + hex_rgb_additive!("#202122") + ); +} + +#[test] +fn test_from_rgba_hex() { + assert_eq!( + Color32::from_rgba_premultiplied(0x20, 0x21, 0x22, 0xff), + hex_rgba_premultiplied!("202122ff") + ); + assert_eq!( + Color32::from_rgba_unmultiplied(0x20, 0x21, 0x22, 0x50), + hex_rgba_unmultiplied!("20212250") + ); +} + // ---------------------------------------------------------------------------- /// 0-1 linear space `RGBA` color with premultiplied alpha. diff --git a/epaint/src/lib.rs b/epaint/src/lib.rs index 3c642297708..5cd17c1fa61 100644 --- a/epaint/src/lib.rs +++ b/epaint/src/lib.rs @@ -49,6 +49,8 @@ pub use emath::{pos2, vec2, Pos2, Rect, Vec2}; pub use ahash; pub use emath; +pub use color_hex; + /// The UV coordinate of a white region of the texture mesh. /// The default egui texture has the top-left corner pixel fully white. /// You need need use a clamping texture sampler for this to work From bf5b400e8ba169dd136e706761bcc6c641afd4ba Mon Sep 17 00:00:00 2001 From: newcomb-luke Date: Sat, 7 May 2022 01:20:07 -0400 Subject: [PATCH 2/6] Added changes to CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 440fa8fc630..2d329d772df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui-w ## Unreleased * Add `*_released` & `*_clicked` methods for `PointerState`. +* Add `epaint::hex_rgb*!()` macros to create Color32's from hex strings ## 0.18.1 - 2022-05-01 * Change `Shape::Callback` from `&dyn Any` to `&mut dyn Any` to support more backends. From 68635999d54077bf9b31524297ae2be4e76a7127 Mon Sep 17 00:00:00 2001 From: newcomb-luke Date: Sat, 7 May 2022 01:29:38 -0400 Subject: [PATCH 3/6] Moved changes over to epaint/CHANGELOG.md --- CHANGELOG.md | 1 - epaint/CHANGELOG.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d329d772df..440fa8fc630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,6 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui-w ## Unreleased * Add `*_released` & `*_clicked` methods for `PointerState`. -* Add `epaint::hex_rgb*!()` macros to create Color32's from hex strings ## 0.18.1 - 2022-05-01 * Change `Shape::Callback` from `&dyn Any` to `&mut dyn Any` to support more backends. diff --git a/epaint/CHANGELOG.md b/epaint/CHANGELOG.md index e0a42144198..25b9ebcad5c 100644 --- a/epaint/CHANGELOG.md +++ b/epaint/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to the epaint crate will be documented in this file. ## Unreleased - +* Added `epaint::hex_rgb*!()` macros to create Color32's from hex strings ([#1596](https://github.com/emilk/egui/pull/1596)). ## 0.18.1 - 2022-05-01 * Change `Shape::Callback` from `&dyn Any` to `&mut dyn Any` to support more backends. From 0702fd9078241d6b4557a767bb98b8e28192d2fa Mon Sep 17 00:00:00 2001 From: newcomb-luke Date: Wed, 11 May 2022 14:22:15 -0400 Subject: [PATCH 4/6] Const-ified several functions on Color32 --- epaint/src/color.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/epaint/src/color.rs b/epaint/src/color.rs index 150b0830547..22f48bccdfc 100644 --- a/epaint/src/color.rs +++ b/epaint/src/color.rs @@ -125,27 +125,27 @@ impl Color32 { } #[inline(always)] - pub fn is_opaque(&self) -> bool { + pub const fn is_opaque(&self) -> bool { self.a() == 255 } #[inline(always)] - pub fn r(&self) -> u8 { + pub const fn r(&self) -> u8 { self.0[0] } #[inline(always)] - pub fn g(&self) -> u8 { + pub const fn g(&self) -> u8 { self.0[1] } #[inline(always)] - pub fn b(&self) -> u8 { + pub const fn b(&self) -> u8 { self.0[2] } #[inline(always)] - pub fn a(&self) -> u8 { + pub const fn a(&self) -> u8 { self.0[3] } @@ -156,20 +156,20 @@ impl Color32 { /// Returns an additive version of self #[inline(always)] - pub fn additive(self) -> Self { + pub const fn additive(self) -> Self { let [r, g, b, _] = self.to_array(); Self([r, g, b, 0]) } /// Premultiplied RGBA #[inline(always)] - pub fn to_array(&self) -> [u8; 4] { + pub const fn to_array(&self) -> [u8; 4] { [self.r(), self.g(), self.b(), self.a()] } /// Premultiplied RGBA #[inline(always)] - pub fn to_tuple(&self) -> (u8, u8, u8, u8) { + pub const fn to_tuple(&self) -> (u8, u8, u8, u8) { (self.r(), self.g(), self.b(), self.a()) } From 2eead7da8b7a8cc8e80691189932bca34d48ae64 Mon Sep 17 00:00:00 2001 From: newcomb-luke Date: Wed, 11 May 2022 14:58:18 -0400 Subject: [PATCH 5/6] Changed macros over to a single hex_color! macro --- egui/src/lib.rs | 2 +- epaint/src/color.rs | 45 +++++++++++---------------------------------- 2 files changed, 12 insertions(+), 35 deletions(-) diff --git a/egui/src/lib.rs b/egui/src/lib.rs index d521eb5dbe5..0f5d45a1fb0 100644 --- a/egui/src/lib.rs +++ b/egui/src/lib.rs @@ -323,7 +323,7 @@ pub use epaint::emath; pub use emath::{lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rect, Vec2}; pub use epaint::{ - color, mutex, + color, hex_color, mutex, text::{FontData, FontDefinitions, FontFamily, FontId, FontTweak}, textures::TexturesDelta, ClippedPrimitive, Color32, ColorImage, FontImage, ImageData, Mesh, PaintCallback, diff --git a/epaint/src/color.rs b/epaint/src/color.rs index 22f48bccdfc..4bd8274e292 100644 --- a/epaint/src/color.rs +++ b/epaint/src/color.rs @@ -187,55 +187,32 @@ impl Color32 { } #[macro_export] -macro_rules! hex_rgb { +macro_rules! hex_color { ($s:literal) => {{ - let color: [u8; 3] = $crate::color_hex::color_from_hex!($s); - $crate::Color32::from_rgb(color[0], color[1], color[2]) - }}; -} - -#[macro_export] -macro_rules! hex_rgb_additive { - ($s:literal) => {{ - let color: [u8; 3] = $crate::color_hex::color_from_hex!($s); - $crate::Color32::from_rgb_additive(color[0], color[1], color[2]) - }}; -} - -#[macro_export] -macro_rules! hex_rgba_premultiplied { - ($s:literal) => {{ - let color: [u8; 4] = $crate::color_hex::color_from_hex!($s); - $crate::Color32::from_rgba_premultiplied(color[0], color[1], color[2], color[3]) - }}; -} - -#[macro_export] -macro_rules! hex_rgba_unmultiplied { - ($s:literal) => {{ - let color: [u8; 4] = $crate::color_hex::color_from_hex!($s); - $crate::Color32::from_rgba_unmultiplied(color[0], color[1], color[2], color[3]) + let array = $crate::color_hex::color_from_hex!($s); + if array.len() == 3 { + $crate::Color32::from_rgb(array[0], array[1], array[2]) + } else { + #[allow(unconditional_panic)] + $crate::Color32::from_rgba_unmultiplied(array[0], array[1], array[2], array[3]) + } }}; } #[test] fn test_from_rgb_hex() { - assert_eq!(Color32::from_rgb(0x20, 0x21, 0x22), hex_rgb!("#202122")); + assert_eq!(Color32::from_rgb(0x20, 0x21, 0x22), hex_color!("#202122")); assert_eq!( Color32::from_rgb_additive(0x20, 0x21, 0x22), - hex_rgb_additive!("#202122") + hex_color!("#202122").additive() ); } #[test] fn test_from_rgba_hex() { - assert_eq!( - Color32::from_rgba_premultiplied(0x20, 0x21, 0x22, 0xff), - hex_rgba_premultiplied!("202122ff") - ); assert_eq!( Color32::from_rgba_unmultiplied(0x20, 0x21, 0x22, 0x50), - hex_rgba_unmultiplied!("20212250") + hex_color!("20212250") ); } From d07904251cacbf49ac91bdfa3fc3fce353a63fd2 Mon Sep 17 00:00:00 2001 From: newcomb-luke Date: Sat, 14 May 2022 15:42:04 -0400 Subject: [PATCH 6/6] Added macro docstring --- epaint/src/color.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/epaint/src/color.rs b/epaint/src/color.rs index 4bd8274e292..c603872db7d 100644 --- a/epaint/src/color.rs +++ b/epaint/src/color.rs @@ -186,6 +186,12 @@ impl Color32 { } } +/// Construct a [`Color32`] from a hex RGB or RGBA string. +/// +/// ```ignore +/// assert_eq!(hex_color!("#202122"), Color32::from_rgb(0x20, 0x21, 0x22)); +/// assert_eq!(hex_color!("#abcdef12"), Color32::from_rgba_unmultiplied(0xab, 0xcd, 0xef, 0x12)); +/// ``` #[macro_export] macro_rules! hex_color { ($s:literal) => {{