Add support for cint
(conversions to and from color types) (#393)
* implement cint for color types under feature flag * upgrade to cint 0.2, remove from default features * upgrade to cint 0.2.1, add a couple more from/into implementations * changelog entry * fix typo in changelog * sort dependency * fmt
This commit is contained in:
parent
ac82cc7be3
commit
c0929014bf
5 changed files with 189 additions and 0 deletions
|
@ -8,6 +8,7 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [
|
|||
## Unreleased
|
||||
|
||||
### Added ⭐
|
||||
* Add support for [cint](https://crates.io/crates/cint) under `cint` feature.
|
||||
* Add features `extra_asserts` and `extra_debug_asserts` to enable additional checks.
|
||||
|
||||
## 0.12.0 - 2021-05-10 - Multitouch, user memory, window pivots, and improved plots
|
||||
|
|
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -294,6 +294,12 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
|
||||
|
||||
[[package]]
|
||||
name = "cint"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00709959bb62458ca8d7f043b1039e0d99e91f5500f004164ec371f546eadc47"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.2.0"
|
||||
|
@ -846,6 +852,7 @@ version = "0.12.0"
|
|||
dependencies = [
|
||||
"ahash",
|
||||
"atomic_refcell",
|
||||
"cint",
|
||||
"emath",
|
||||
"ordered-float",
|
||||
"parking_lot",
|
||||
|
|
|
@ -39,6 +39,9 @@ extra_asserts = ["epaint/extra_asserts"]
|
|||
# Add compatability with https://github.com/kvark/mint
|
||||
mint = ["epaint/mint"]
|
||||
|
||||
# add compatibility with https://crates.io/crates/cint
|
||||
cint = ["epaint/cint"]
|
||||
|
||||
persistence = ["serde", "epaint/persistence", "ron"]
|
||||
|
||||
# Only needed if you plan to use the same egui::Context from multiple threads.
|
||||
|
|
|
@ -26,6 +26,7 @@ emath = { version = "0.12.0", path = "../emath" }
|
|||
|
||||
ahash = { version = "0.7", features = ["std"], default-features = false }
|
||||
atomic_refcell = { version = "0.1", optional = true } # Used instead of parking_lot when you are always using epaint in a single thread. About as fast as parking_lot. Panics on multi-threaded use.
|
||||
cint = { version = "^0.2.1", optional = true }
|
||||
ordered-float = "2"
|
||||
parking_lot = { version = "0.11", optional = true } # Using parking_lot over std::sync::Mutex gives 50% speedups in some real-world scenarios.
|
||||
rusttype = "0.9"
|
||||
|
|
|
@ -292,6 +292,18 @@ impl Rgba {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Premultiplied RGBA
|
||||
#[inline(always)]
|
||||
pub fn to_array(&self) -> [f32; 4] {
|
||||
[self.r(), self.g(), self.b(), self.a()]
|
||||
}
|
||||
|
||||
/// Premultiplied RGBA
|
||||
#[inline(always)]
|
||||
pub fn to_tuple(&self) -> (f32, f32, f32, f32) {
|
||||
(self.r(), self.g(), self.b(), self.a())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add for Rgba {
|
||||
|
@ -759,3 +771,168 @@ pub fn tint_color_towards(color: Color32, target: Color32) -> Color32 {
|
|||
}
|
||||
Color32::from_rgba_premultiplied(r, g, b, a)
|
||||
}
|
||||
|
||||
#[cfg(feature = "cint")]
|
||||
mod impl_cint {
|
||||
use super::*;
|
||||
use cint::{Alpha, ColorInterop, EncodedSrgb, Hsv, LinearSrgb, PremultipliedAlpha};
|
||||
|
||||
// ---- Color32 ----
|
||||
|
||||
impl From<Alpha<EncodedSrgb<u8>>> for Color32 {
|
||||
fn from(srgba: Alpha<EncodedSrgb<u8>>) -> Self {
|
||||
let Alpha {
|
||||
color: EncodedSrgb { r, g, b },
|
||||
alpha: a,
|
||||
} = srgba;
|
||||
|
||||
Color32::from_rgba_unmultiplied(r, g, b, a)
|
||||
}
|
||||
}
|
||||
|
||||
// No From<Color32> for Alpha<_> because Color32 is premultiplied
|
||||
|
||||
impl From<PremultipliedAlpha<EncodedSrgb<u8>>> for Color32 {
|
||||
fn from(srgba: PremultipliedAlpha<EncodedSrgb<u8>>) -> Self {
|
||||
let PremultipliedAlpha {
|
||||
color: EncodedSrgb { r, g, b },
|
||||
alpha: a,
|
||||
} = srgba;
|
||||
|
||||
Color32::from_rgba_premultiplied(r, g, b, a)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Color32> for PremultipliedAlpha<EncodedSrgb<u8>> {
|
||||
fn from(col: Color32) -> Self {
|
||||
let (r, g, b, a) = col.to_tuple();
|
||||
|
||||
PremultipliedAlpha {
|
||||
color: EncodedSrgb { r, g, b },
|
||||
alpha: a,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PremultipliedAlpha<EncodedSrgb<f32>>> for Color32 {
|
||||
fn from(srgba: PremultipliedAlpha<EncodedSrgb<f32>>) -> Self {
|
||||
let PremultipliedAlpha {
|
||||
color: EncodedSrgb { r, g, b },
|
||||
alpha: a,
|
||||
} = srgba;
|
||||
|
||||
// This is a bit of an abuse of the function name but it does what we want.
|
||||
let r = linear_u8_from_linear_f32(r);
|
||||
let g = linear_u8_from_linear_f32(g);
|
||||
let b = linear_u8_from_linear_f32(b);
|
||||
let a = linear_u8_from_linear_f32(a);
|
||||
|
||||
Color32::from_rgba_premultiplied(r, g, b, a)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Color32> for PremultipliedAlpha<EncodedSrgb<f32>> {
|
||||
fn from(col: Color32) -> Self {
|
||||
let (r, g, b, a) = col.to_tuple();
|
||||
|
||||
// This is a bit of an abuse of the function name but it does what we want.
|
||||
let r = linear_f32_from_linear_u8(r);
|
||||
let g = linear_f32_from_linear_u8(g);
|
||||
let b = linear_f32_from_linear_u8(b);
|
||||
let a = linear_f32_from_linear_u8(a);
|
||||
|
||||
PremultipliedAlpha {
|
||||
color: EncodedSrgb { r, g, b },
|
||||
alpha: a,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ColorInterop for Color32 {
|
||||
type CintTy = PremultipliedAlpha<EncodedSrgb<u8>>;
|
||||
}
|
||||
|
||||
// ---- Rgba ----
|
||||
|
||||
impl From<PremultipliedAlpha<LinearSrgb<f32>>> for Rgba {
|
||||
fn from(srgba: PremultipliedAlpha<LinearSrgb<f32>>) -> Self {
|
||||
let PremultipliedAlpha {
|
||||
color: LinearSrgb { r, g, b },
|
||||
alpha: a,
|
||||
} = srgba;
|
||||
|
||||
Rgba([r, g, b, a])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Rgba> for PremultipliedAlpha<LinearSrgb<f32>> {
|
||||
fn from(col: Rgba) -> Self {
|
||||
let (r, g, b, a) = col.to_tuple();
|
||||
|
||||
PremultipliedAlpha {
|
||||
color: LinearSrgb { r, g, b },
|
||||
alpha: a,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ColorInterop for Rgba {
|
||||
type CintTy = PremultipliedAlpha<LinearSrgb<f32>>;
|
||||
}
|
||||
|
||||
// ---- Hsva ----
|
||||
|
||||
impl From<Alpha<Hsv<f32>>> for Hsva {
|
||||
fn from(srgba: Alpha<Hsv<f32>>) -> Self {
|
||||
let Alpha {
|
||||
color: Hsv { h, s, v },
|
||||
alpha: a,
|
||||
} = srgba;
|
||||
|
||||
Hsva::new(h, s, v, a)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Hsva> for Alpha<Hsv<f32>> {
|
||||
fn from(col: Hsva) -> Self {
|
||||
let Hsva { h, s, v, a } = col;
|
||||
|
||||
Alpha {
|
||||
color: Hsv { h, s, v },
|
||||
alpha: a,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ColorInterop for Hsva {
|
||||
type CintTy = Alpha<Hsv<f32>>;
|
||||
}
|
||||
|
||||
// ---- HsvaGamma ----
|
||||
|
||||
impl ColorInterop for HsvaGamma {
|
||||
type CintTy = Alpha<Hsv<f32>>;
|
||||
}
|
||||
|
||||
impl From<Alpha<Hsv<f32>>> for HsvaGamma {
|
||||
fn from(srgba: Alpha<Hsv<f32>>) -> Self {
|
||||
let Alpha {
|
||||
color: Hsv { h, s, v },
|
||||
alpha: a,
|
||||
} = srgba;
|
||||
|
||||
Hsva::new(h, s, v, a).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<HsvaGamma> for Alpha<Hsv<f32>> {
|
||||
fn from(col: HsvaGamma) -> Self {
|
||||
let Hsva { h, s, v, a } = col.into();
|
||||
|
||||
Alpha {
|
||||
color: Hsv { h, s, v },
|
||||
alpha: a,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue