Skip to content

Commit

Permalink
Split out ecolor crate (#2399)
Browse files Browse the repository at this point in the history
* split out ecolor crate

* split up ecolor crate in lots of modules

* add changelog notes

* add readme to ecolor

* put clippy::manual_range_contains on cranky allow list

* fix hex color issues

* doc fixes

* more hex_color fixes

* Document features

* Rename hex_color module to avoid warning

* Sort the feature names

* fix link in CHANGELOG.md

* better wording

Co-authored-by: Emil Ernerfeldt <[email protected]>
  • Loading branch information
Wumpf and emilk authored Dec 6, 2022
1 parent e30ac7f commit 5effc68
Show file tree
Hide file tree
Showing 29 changed files with 1,229 additions and 1,101 deletions.
14 changes: 12 additions & 2 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]
resolver = "2"
members = [
"crates/ecolor",
"crates/egui_demo_app",
"crates/egui_demo_lib",
"crates/egui_extras",
Expand Down
1 change: 1 addition & 0 deletions Cranky.toml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ allow = [
# TODO(emilk): enable more lints
"clippy::type_complexity",
"clippy::undocumented_unsafe_blocks",
"clippy::manual_range_contains",
"trivial_casts",
"unsafe_op_in_unsafe_fn", # `unsafe_op_in_unsafe_fn` may become the default in future Rust versions: https://github.com/rust-lang/rust/issues/71668
"unused_qualifications",
Expand Down
6 changes: 6 additions & 0 deletions crates/ecolor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog for ecolor
All notable changes to the `ecolor` crate will be noted in this file.


## Unreleased
* Split out `ecolor` crate from `epaint`
50 changes: 50 additions & 0 deletions crates/ecolor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[package]
name = "ecolor"
version = "0.19.0"
authors = [
"Emil Ernerfeldt <[email protected]>",
"Andreas Reich <[email protected]>",
]
description = "Color structs and color conversion utilities"
edition = "2021"
rust-version = "1.65"
homepage = "https://github.com/emilk/egui"
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/emilk/egui"
categories = ["mathematics", "encoding", "images"]
keywords = ["gui", "color", "conversion", "gamedev", "images"]
include = ["../LICENSE-APACHE", "../LICENSE-MIT", "**/*.rs", "Cargo.toml"]

[package.metadata.docs.rs]
all-features = true

[lib]


[features]
default = []

## Enable additional checks if debug assertions are enabled (debug builds).
extra_debug_asserts = []
## Always enable additional checks.
extra_asserts = []


[dependencies]
#! ### Optional dependencies

## [`bytemuck`](https://docs.rs/bytemuck) enables you to cast `emath` types to `&[u8]`.
bytemuck = { version = "1.7.2", optional = true, features = ["derive"] }

## [`cint`](https://docs.rs/cint) enables interopability with other color libraries.
cint = { version = "0.3.1", optional = true }

## Enable the [`hex_color`] macro.
color-hex = { version = "0.2.0", optional = true }

## Enable this when generating docs.
document-features = { version = "0.2", optional = true }

## Allow serialization using [`serde`](https://docs.rs/serde).
serde = { version = "1", optional = true, features = ["derive"] }
5 changes: 5 additions & 0 deletions crates/ecolor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ecolor - egui color library

A simple color storage and conversion library.

Made for [`egui`](https://github.com/emilk/egui/).
161 changes: 161 additions & 0 deletions crates/ecolor/src/cint_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
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

0 comments on commit 5effc68

Please sign in to comment.