Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to convert from a hex string to Color32 using macros #1596

Merged
merged 9 commits into from
May 15, 2022
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion epaint/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ All notable changes to the epaint crate will be documented in this file.

## Unreleased
* Optimize tessellation of filled circles by 10x or more ([#1616](https://github.com/emilk/egui/pull/1616)).

* 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.
Expand Down
3 changes: 2 additions & 1 deletion epaint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Expand Down
52 changes: 44 additions & 8 deletions epaint/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}

Expand All @@ -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())
}

Expand All @@ -186,6 +186,42 @@ 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]
newcomb-luke marked this conversation as resolved.
Show resolved Hide resolved
macro_rules! hex_color {
($s:literal) => {{
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_color!("#202122"));
assert_eq!(
Color32::from_rgb_additive(0x20, 0x21, 0x22),
hex_color!("#202122").additive()
);
}

#[test]
fn test_from_rgba_hex() {
assert_eq!(
Color32::from_rgba_unmultiplied(0x20, 0x21, 0x22, 0x50),
hex_color!("20212250")
);
}

// ----------------------------------------------------------------------------

/// 0-1 linear space `RGBA` color with premultiplied alpha.
Expand Down
2 changes: 2 additions & 0 deletions epaint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down