diff --git a/DOCS/CHANGELOG.md b/DOCS/CHANGELOG.md index 20f279e2..51286051 100644 --- a/DOCS/CHANGELOG.md +++ b/DOCS/CHANGELOG.md @@ -38,7 +38,7 @@ The format is based on [Keep a Changelog], and this project adheres to - enum variants: - `DataError::ElementNotFound`. - traits: - - `ExtCellOption`, `ExtOptRes`, `MemPod`, `TypeResourced`, `Unit`. + - `ColorBase`, `ExtCellOption`, `ExtOptRes`, `MemPod`, `TypeResourced`, `Unit`. - `WaveletCompressionVec`, `WaveletTransformVec`. - associated methods and constants for: - `Array`: `from_fn`, `contains_[from|to|between]`. @@ -127,6 +127,7 @@ The format is based on [Keep a Changelog], and this project adheres to - structs: - make `data::dst` types use `MemPod` instead of `bytemuck::Pod`. - rename: + - `COLOR` to `Color`. - `GcdExt` to `GcdResult`. - `AllocMap` to `HashMap` and `AllocSet` to `HashSet`. - `AllocOrdMap` to `BTreeMap` and `AllocOrdSet` to `BTreeSet`. diff --git a/src/rend/color/base.rs b/src/rend/color/base.rs new file mode 100644 index 00000000..2fcbedb0 --- /dev/null +++ b/src/rend/color/base.rs @@ -0,0 +1,41 @@ +// devela::rend::color::base +// +//! +// + +#[cfg(feature = "alloc")] +use crate::{vec_ as vec, Vec}; + +/// Base trait for general color data representation. +/// +/// Provides a core interface for working with color data across different +/// formats and models, supporting both practical and scientific applications. +pub trait ColorBase { + /// The type used for color components. + type Component; + + /// Returns the number of color components. + /// + /// For example: + /// - RGB returns `3` + /// - Spectral data may return `n` + fn color_component_count(&self) -> usize; + + /// Writes the color components to a pre-allocated buffer. + /// + /// # Panics + /// Panics if the buffer size is less than `color_component_count()`. + // TODO: Return Error + fn color_components_write(&self, buffer: &mut [Self::Component]); + + /// Returns a vector containing the color components. + #[cfg(feature = "alloc")] + fn color_components_vec(&self) -> Vec + where + Self::Component: Default + Clone, + { + let mut buffer = vec![Self::Component::default(); self.color_component_count()]; + self.color_components_write(&mut buffer); + buffer + } +} diff --git a/src/rend/color/mod.rs b/src/rend/color/mod.rs index 2e8268da..b13e0991 100644 --- a/src/rend/color/mod.rs +++ b/src/rend/color/mod.rs @@ -3,14 +3,14 @@ //! Chromatic functionality. // +mod base; mod error; -mod r#struct; -mod r#trait; +mod namespace; #[allow(unused_imports)] -pub use {error::*, r#struct::*, r#trait::*}; +pub use {base::*, error::*, namespace::*}; pub(crate) mod all { #[doc(inline)] #[allow(unused_imports)] - pub use super::{error::*, r#struct::*, r#trait::*}; + pub use super::{base::*, error::*, namespace::*}; } diff --git a/src/rend/color/struct.rs b/src/rend/color/namespace.rs similarity index 55% rename from src/rend/color/struct.rs rename to src/rend/color/namespace.rs index 71420e3c..bdb33e74 100644 --- a/src/rend/color/struct.rs +++ b/src/rend/color/namespace.rs @@ -1,41 +1,28 @@ -// devela::rend::color::fns +// devela::rend::color::namespace // //! Standalone color functions and constants. // #[allow(unused_imports)] -use crate::code::{iif, paste, sf}; +use crate::code::{iif, paste, sf, CONST}; #[cfg(all(_float_·, not(feature = "std")))] #[allow(unused_imports, reason = "!std: powf, powi")] use crate::num::ExtFloat; -/// color namespace for constants and methods -pub struct COLOR; +/// Color namespace for constants and methods +pub struct Color; -sf! { macro_rules! LUMINANCE_RED { () => { 0.212639 }; } pub(crate) use LUMINANCE_RED; } -sf! { macro_rules! LUMINANCE_GREEN { () => { 0.715169 }; } pub(crate) use LUMINANCE_GREEN; } -sf! { macro_rules! LUMINANCE_BLUE { () => { 0.072192 }; } pub(crate) use LUMINANCE_BLUE; } - -impl COLOR { - /* constants */ - - /// The coefficient used for calculating the red luminance. - pub const LUMINANCE_RED: f32 = LUMINANCE_RED![]; - - /// The coefficient used for calculating the green luminance. - pub const LUMINANCE_GREEN: f32 = LUMINANCE_GREEN![]; - - /// The coefficient used for calculating the blue luminance. - pub const LUMINANCE_BLUE: f32 = LUMINANCE_BLUE![]; -} - -// $t: the floating-point primitive -// $cap: the capability feature that enables the given implementation. E.g "_f32". +#[doc = crate::doc_private!()] +/// +/// +/// # Args +/// $t: the floating-point primitive +/// $cap: the capability feature that enables the given implementation. E.g "_f32". macro_rules! color_gamma_fns { ($($t:ty : $cap:literal),+) => { $( color_gamma_fns![@$t:$cap]; )+ }; (@$t:ty : $cap:literal) => { paste! { - impl COLOR { + impl Color { #[doc = "Applies the `gamma` *(γ)* to a linear `" $t "` channel to make it non-linear."] /// /// # Algorithm @@ -50,8 +37,8 @@ macro_rules! color_gamma_fns { /// $$ #[cfg(any(feature = "std", feature = $cap))] #[cfg_attr(feature = "nightly_doc", doc(cfg(any(feature = "std", feature = $cap))))] - pub fn [](c: $t, gamma: $t) -> $t { - iif![c <= 0.0031308; 12.92 * c; 1.055 * c.powf(1.0 / gamma) - 0.055] + pub fn [](c: $t, gamma: $t) -> $t { + iif![c <= 0.003_130_8; 12.92 * c; 1.055 * c.powf(1.0 / gamma) - 0.055] } #[doc = "Removes the `gamma` *(γ)* from a non-linear `" $t "` channel to make it linear."] @@ -59,8 +46,8 @@ macro_rules! color_gamma_fns { /// # Algorithm /// $$ /// \begin{align} - /// \notag f_\text{remove}(c) = \large\begin{cases} - /// \Large\frac{c}{12.92}, + /// \notag f_\text{remove}(c) = \begin{cases} + /// c / 12.92, /// & \normalsize\text{if } c <= 0.04045 \cr /// \left(\Large\frac{c+0.055}{1.055} - \normalsize 0.055\right)^{\gamma}, /// & \normalsize \text{if } c > 0.04045 \end{cases} \cr @@ -68,8 +55,8 @@ macro_rules! color_gamma_fns { /// $$ #[cfg(any(feature = "std", feature = $cap))] #[cfg_attr(feature = "nightly_doc", doc(cfg(any(feature = "std", feature = $cap))))] - pub fn [](c: $t, gamma: $t) -> $t { - iif![c <= 0.04045; c / 12.92; ((c + 0.055) / (1.055)).powf(gamma)] + pub fn [](c: $t, gamma: $t) -> $t { + iif![c <= 0.040_45; c / 12.92; ((c + 0.055) / (1.055)).powf(gamma)] } } }}; diff --git a/src/rend/color/trait.rs b/src/rend/color/trait.rs deleted file mode 100644 index 085049f0..00000000 --- a/src/rend/color/trait.rs +++ /dev/null @@ -1,46 +0,0 @@ -// devela::rend::color::trait -// -//! -// - -/// Common color trait. -pub trait Color { - /// The type of the inner color components. - type Inner: Copy + PartialEq; - - /* methods */ - - /// Returns the red luminosity. - fn color_red(&self) -> Self::Inner; - - /// Returns the green luminosity. - fn color_green(&self) -> Self::Inner; - - /// Returns the blue luminosity. - fn color_blue(&self) -> Self::Inner; - - /// Returns the alpha luminosity. - fn color_alpha(&self) -> Self::Inner; - - /// Returns the overall luminosity. - // - // If the color is not in [`Oklab32`] or [`Oklch32`] format, - // it will be converted to `Oklab32` for the operation. - fn color_luminosity(&self) -> Self::Inner; - - /// Returns the hue. - // - // If the color is not in [`Oklch32`] format - // it will be converted to it for the operation. - fn color_hue(&self) -> Self::Inner; - - /* conversions */ - - /// Returns the 3 components, without alpha. - fn color_to_array3(&self) -> [Self::Inner; 3]; - - /// Returns the 4 components, with alpha. - /// - /// If the specific color type has no alpha the maximum value is returned. - fn color_to_array4(&self) -> [Self::Inner; 4]; -}