4 releases
Uses new Rust 2024
new 0.1.3 | Mar 27, 2025 |
---|---|
0.1.2 | Mar 26, 2025 |
0.1.1 | Mar 26, 2025 |
0.1.0 | Mar 26, 2025 |
#39 in Data formats
89 downloads per month
49KB
788 lines
tcolour
tcolour is just a crate that I have made for a project I am working on. It is designed to work with ratatui and also has capabilities to convert to and from nalgebra's Vector4<f64>
. I intend to test this crate to some degree but not with extreme rigour, I'll test it as I use it. Feel free to use or contribute.
Examples
Important Note: this crate uses auto_ops
to define all operators for borrowed/owned iterations of f64 (operator) Colour
(and vice versa) along with Colour (operator) Colour
. Every operator is component-wise and all are invariant over the alpha channel. Similarly, the operators do not normalise or clamp the channels (or clean NaN
values). To get around these facts, you can either: use the nalgebra
feature if you have it in your project or follow a suggested tip from this example:
Alpha channel operating
use tcolour::Colour;
let red = Colour::red(1.0);
let blue = Colour::blue(1.0);
// if the alpha channel was also added, it would be 2.
let purple = red + blue;
let translucent_red = Colour::red(1.0).with_alpha(0.3);
let almost_opaque_blue = Colour::blue(1.0).with_alpha(0.7);
// we add the alpha channels manually
let solid_purple = (translucent_red + almost_opaque_blue)
.with_alpha(translucent_red.a + almost_opaque_blue.a);
Cleaning a colour
// RGBA(1, 1, 1, 1)
let white = Colour::grey(1.0);
// RGBA(0, 0, 0, 0)
let transparent = Colour::transparent();
// RGBA(NaN, NaN, NaN, NaN)
let faulty_colour = white / transparent;
/*
`.cleaned(&self) -> Colour` will replace all NaN
values with 1f64 as this is usually the intended
effect for colour division by zero.
*/
assert_eq!(white, faulty_colour.cleaned());
// ...alternatively convert the values to black
assert_eq!(Colour::grey(0.0), faulty_colour.map_rgba(|v|
if value.is_nan() { 0f64 } else { v }
));
Another note: there are many "iterator" like functions for Colour
but not an implementation for iter()
(yet). This is because I felt it best for, at least my code, to keep within the Colour
type and not be converting between iter
to vec
to then Colour::try_from
and so on. For this functionality you can use one of the many Into<>
bindings to convert from Colour
to [f64; 4]
or Vec<f64>
or (f64, f64, f64, f64)
or [u8; 3]
(ignores the alpha channel) and so on. For how to use Colour
, or how I use it at least, feel free to read, fork, and whatever else the AGPL3.0 license permits you to do with the source code (pretty much anything).
Features
The features of this crate just allow you to choose which implementations are valid.
ratatui
I have abused the fact that American English and British English spell color/colour differently to differentiate between ratatui's Color
and tcolour's Colour
but feel free to do use tcolour::Colour as TColor
or something.
use tcolour::Colour;
use approx::assert_relative_eq;
let colour: Colour = Colour::from(ratatui::style::Color::Rgb(10, 15, 12));
// [0, 255] ⊂ ℕ to [0, 1] ⊂ ℝ
assert_relative_eq!(colour, Colour::from_u8(10, 15, 12));
nalgebra
use tcolour::Colour;
let colour: Colour = Colour::from(nalgebra::Vector4::new(0f64, 1f64, 1f64, 0.5f64));
// (x, y, z, w) = (r, g, b, a)
assert_eq!(colour, Colour::new(0f64, 1f64, 1f64, 0.5f64))
approx
RelativeEq, AbsDiffEq and UlpsEq are all defined for Colour
by this crate.
let colour: Colour = Colour::solid(1f64, 1f64, 1f64);
/*
Some mathematics that might result in floating point errors,
especially true after using something like `Colour::blend()`
*/
let new_colour = colour + // ...
/*
Some differet mathematics that might result in floating point
errors but should result in the same value as `new_colour`
*/
let newer_colour = colour + // ...
assert_relative_eq!(new_colour, newer_colour);
By default I have enabled ratatui as this is the intended target for this crate and approx due to blending having a fair possibility in producing some floating point errors and the use of std::f64
.
features = ["naglebra", "ratatui", "approx"]
default-features = ["ratatui", "approx"]
Dependencies
~7–17MB
~250K SLoC