From 09043a8197913d34e8b3b739fe85cc870b43fcaf Mon Sep 17 00:00:00 2001 From: Erik Hedvall Date: Sun, 19 Jan 2020 17:11:07 +0100 Subject: [PATCH] Split the Component trait into more specific traits --- palette/src/blend/blend.rs | 13 +- palette/src/chromatic_adaptation.rs | 75 +++---- palette/src/component.rs | 181 +++++++++++++++++ palette/src/convert.rs | 51 ++--- palette/src/encoding/gamma.rs | 20 +- palette/src/encoding/mod.rs | 9 +- palette/src/encoding/srgb.rs | 38 ++-- palette/src/equality.rs | 49 +++-- palette/src/gradient.rs | 67 +++++-- palette/src/hsl.rs | 122 ++++++----- palette/src/hsv.rs | 132 ++++++------ palette/src/hues.rs | 32 ++- palette/src/hwb.rs | 111 +++++----- palette/src/lab.rs | 154 +++++++------- palette/src/lch.rs | 82 ++++---- palette/src/lib.rs | 142 ++----------- palette/src/luma/luma.rs | 54 +++-- palette/src/matrix.rs | 26 +-- palette/src/rgb/mod.rs | 43 ++-- palette/src/rgb/rgb.rs | 189 +++++++++--------- palette/src/white_point.rs | 64 +++--- palette/src/xyz.rs | 104 +++++----- palette/src/yxy.rs | 108 +++++----- palette/tests/pointer_dataset/pointer_data.rs | 9 +- palette_derive/src/convert/shared.rs | 2 +- 25 files changed, 995 insertions(+), 882 deletions(-) create mode 100644 palette/src/component.rs diff --git a/palette/src/blend/blend.rs b/palette/src/blend/blend.rs index 0ea51a12d..c27ff1b8b 100644 --- a/palette/src/blend/blend.rs +++ b/palette/src/blend/blend.rs @@ -2,7 +2,7 @@ use float::Float; use num_traits::{One, Zero}; use blend::{BlendFunction, PreAlpha}; -use {cast, clamp, ComponentWise}; +use {clamp, ComponentWise}; ///A trait for colors that can be blended together. /// @@ -353,6 +353,10 @@ where let one = ::Scalar::one(); let zero = ::Scalar::zero(); let two = one + one; + let three = two + one; + let four = two + two; + let twelve = four + four + four; + let sixteen = twelve + four; let src = self.into_premultiplied(); let dst = other.into_premultiplied(); @@ -369,14 +373,11 @@ where b * (src.alpha + (two * a - src.alpha) * (one - m)) + a * (one - dst.alpha) + b * (one - src.alpha) - } else if b * cast(4.0) <= dst.alpha { + } else if b * four <= dst.alpha { let m2 = m * m; let m3 = m2 * m; - dst.alpha - * (two * a - src.alpha) - * (m3 * cast(16.0) - m2 * cast(12.0) - m * cast(3.0)) - + a + dst.alpha * (two * a - src.alpha) * (m3 * sixteen - m2 * twelve - m * three) + a - a * dst.alpha + b } else { diff --git a/palette/src/chromatic_adaptation.rs b/palette/src/chromatic_adaptation.rs index 9281674bf..cc0c6ac47 100644 --- a/palette/src/chromatic_adaptation.rs +++ b/palette/src/chromatic_adaptation.rs @@ -24,9 +24,10 @@ //!``` use float::Float; -use {cast, Component, FromColor, IntoColor, Xyz}; +use from_f64; +use matrix::{multiply_3x3, multiply_xyz, Mat3}; use white_point::WhitePoint; -use matrix::{multiply_xyz, Mat3, multiply_3x3}; +use {FloatComponent, FromColor, IntoColor, Xyz}; ///Chromatic adaptation methods implemented in the library pub enum Method { @@ -50,7 +51,7 @@ pub struct ConeResponseMatrices { ///one illuminant to another (Swp -> Dwp) pub trait TransformMatrix where - T: Component + Float, + T: FloatComponent, Swp: WhitePoint, Dwp: WhitePoint, { @@ -86,7 +87,7 @@ where impl TransformMatrix for Method where - T: Component + Float, + T: FloatComponent, Swp: WhitePoint, Dwp: WhitePoint, { @@ -95,38 +96,44 @@ where match *self { Method::Bradford => { ConeResponseMatrices:: { - ma: [cast(0.8951000), cast(0.2664000), cast(-0.1614000), - cast(-0.7502000), cast(1.7135000), cast(0.0367000), - cast(0.0389000), cast(-0.0685000), cast(1.0296000) - ], - inv_ma: [cast(0.9869929), cast(-0.1470543), cast(0.1599627), - cast(0.4323053), cast(0.5183603), cast(0.0492912), - cast(-0.0085287), cast(0.0400428), cast(0.9684867) - ], + ma: [ + from_f64(0.8951000), from_f64(0.2664000), from_f64(-0.1614000), + from_f64(-0.7502000), from_f64(1.7135000), from_f64(0.0367000), + from_f64(0.0389000), from_f64(-0.0685000), from_f64(1.0296000) + ], + inv_ma: [ + from_f64(0.9869929), from_f64(-0.1470543), from_f64(0.1599627), + from_f64(0.4323053), from_f64(0.5183603), from_f64(0.0492912), + from_f64(-0.0085287), from_f64(0.0400428), from_f64(0.9684867) + ], } } Method::VonKries => { ConeResponseMatrices:: { - ma: [cast(0.4002400), cast(0.7076000), cast(-0.0808100), - cast(-0.2263000), cast(1.1653200), cast(0.0457000), - cast(0.0000000), cast(0.0000000), cast(0.9182200) - ], - inv_ma: [cast(1.8599364), cast(-1.1293816), cast(0.2198974), - cast(0.3611914), cast(0.6388125), cast(-0.0000064), - cast(0.0000000), cast(0.0000000), cast(1.0890636) - ], + ma: [ + from_f64(0.4002400), from_f64(0.7076000), from_f64(-0.0808100), + from_f64(-0.2263000), from_f64(1.1653200), from_f64(0.0457000), + from_f64(0.0000000), from_f64(0.0000000), from_f64(0.9182200) + ], + inv_ma: [ + from_f64(1.8599364), from_f64(-1.1293816), from_f64(0.2198974), + from_f64(0.3611914), from_f64(0.6388125), from_f64(-0.0000064), + from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0890636) + ], } } Method::XyzScaling => { ConeResponseMatrices:: { - ma: [cast(1.0000000), cast(0.0000000), cast(0.0000000), - cast(0.0000000), cast(1.0000000), cast(0.0000000), - cast(0.0000000), cast(0.0000000), cast(1.0000000) - ], - inv_ma: [cast(1.0000000), cast(0.0000000), cast(0.0000000), - cast(0.0000000), cast(1.0000000), cast(0.0000000), - cast(0.0000000), cast(0.0000000), cast(1.0000000) - ], + ma: [ + from_f64(1.0000000), from_f64(0.0000000), from_f64(0.0000000), + from_f64(0.0000000), from_f64(1.0000000), from_f64(0.0000000), + from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0000000) + ], + inv_ma: [ + from_f64(1.0000000), from_f64(0.0000000), from_f64(0.0000000), + from_f64(0.0000000), from_f64(1.0000000), from_f64(0.0000000), + from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0000000) + ], } } } @@ -139,7 +146,7 @@ where ///Uses the bradford method for conversion by default. pub trait AdaptFrom: Sized where - T: Component + Float, + T: FloatComponent, Swp: WhitePoint, Dwp: WhitePoint, { @@ -155,7 +162,7 @@ where impl AdaptFrom for D where - T: Component + Float, + T: FloatComponent, Swp: WhitePoint, Dwp: WhitePoint, S: IntoColor, @@ -175,7 +182,7 @@ where ///Uses the bradford method for conversion by default. pub trait AdaptInto: Sized where - T: Component + Float, + T: FloatComponent, Swp: WhitePoint, Dwp: WhitePoint, { @@ -191,7 +198,7 @@ where impl AdaptInto for S where - T: Component + Float, + T: FloatComponent, Swp: WhitePoint, Dwp: WhitePoint, D: AdaptFrom, @@ -204,9 +211,9 @@ where #[cfg(test)] mod test { - use Xyz; - use white_point::{D50, D65, A, C}; use super::{AdaptFrom, AdaptInto, Method, TransformMatrix}; + use white_point::{A, C, D50, D65}; + use Xyz; #[test] fn d65_to_d50_matrix_xyz_scaling() { diff --git a/palette/src/component.rs b/palette/src/component.rs new file mode 100644 index 000000000..3ed1904bc --- /dev/null +++ b/palette/src/component.rs @@ -0,0 +1,181 @@ +use num_traits::Zero; + +use float::Float; +use {clamp, FromF64}; + +/// Common trait for color components. +pub trait Component: Copy + Zero + PartialOrd { + /// The highest displayable value this component type can reach. Higher + /// values are allowed, but they may be lowered to this before + /// converting to another format. + fn max_intensity() -> Self; +} + +/// Common trait for floating point color components. +pub trait FloatComponent: Component + Float + FromF64 {} + +impl FloatComponent for T {} + +macro_rules! impl_float_components { + ($($ty: ident),+) => { + $( + impl Component for $ty { + fn max_intensity() -> Self { + 1.0 + } + } + )* + }; +} + +impl_float_components!(f32, f64); + +macro_rules! impl_uint_components { + ($($ty: ident),+) => { + $( + impl Component for $ty { + fn max_intensity() -> Self { + core::$ty::MAX + } + } + )* + }; +} + +impl_uint_components!(u8, u16, u32, u64, u128); + +/// Converts from a color component type, while performing the appropriate scaling, rounding and clamping. +/// +/// ``` +/// use palette::FromComponent; +/// +/// // Scales the value up to u8::MAX while converting. +/// let u8_component = u8::from_component(1.0f32); +/// assert_eq!(u8_component, 255); +/// ``` +pub trait FromComponent { + /// Converts `other` into `Self`, while performing the appropriate scaling, rounding and clamping. + fn from_component(other: T) -> Self; +} + +impl + Component> FromComponent for T { + #[inline] + fn from_component(other: U) -> T { + other.into_component() + } +} + +/// Converts into a color component type, while performing the appropriate scaling, rounding and clamping. +/// +/// ``` +/// use palette::IntoComponent; +/// +/// // Scales the value up to u8::MAX while converting. +/// let u8_component: u8 = 1.0f32.into_component(); +/// assert_eq!(u8_component, 255); +/// ``` +pub trait IntoComponent { + /// Converts `self` into `T`, while performing the appropriate scaling, rounding and clamping. + fn into_component(self) -> T; +} + +impl IntoComponent for T { + #[inline] + fn into_component(self) -> T { + self + } +} + +macro_rules! convert_float_to_uint { + ($float: ident; direct ($($direct_target: ident),+); $(via $temporary: ident ($($target: ident),+);)*) => { + $( + impl IntoComponent<$direct_target> for $float { + #[inline] + fn into_component(self) -> $direct_target { + let max = $direct_target::max_intensity() as $float; + let scaled = self * max; + clamp(scaled.round(), 0.0, max) as $direct_target + } + } + )+ + + $( + $( + impl IntoComponent<$target> for $float { + #[inline] + fn into_component(self) -> $target { + let max = $target::max_intensity() as $temporary; + let scaled = self as $temporary * max; + clamp(scaled.round(), 0.0, max) as $target + } + } + )+ + )* + }; +} + +macro_rules! convert_uint_to_float { + ($uint: ident; $(via $temporary: ident ($($target: ident),+);)*) => { + $( + $( + impl IntoComponent<$target> for $uint { + #[inline] + fn into_component(self) -> $target { + let max = $uint::max_intensity() as $temporary; + let scaled = self as $temporary / max; + scaled as $target + } + } + )+ + )* + }; +} + +macro_rules! convert_uint_to_uint { + ($uint: ident; $(via $temporary: ident ($($target: ident),+);)*) => { + $( + $( + impl IntoComponent<$target> for $uint { + #[inline] + fn into_component(self) -> $target { + let target_max = $target::max_intensity() as $temporary; + let own_max = $uint::max_intensity() as $temporary; + let scaled = (self as $temporary / own_max) * target_max; + clamp(scaled.round(), 0.0, target_max) as $target + } + } + )+ + )* + }; +} + +impl IntoComponent for f32 { + #[inline] + fn into_component(self) -> f64 { + self as f64 + } +} +convert_float_to_uint!(f32; direct (u8, u16); via f64 (u32, u64, u128);); + +impl IntoComponent for f64 { + #[inline] + fn into_component(self) -> f32 { + self as f32 + } +} +convert_float_to_uint!(f64; direct (u8, u16, u32, u64, u128);); + +convert_uint_to_float!(u8; via f32 (f32); via f64 (f64);); +convert_uint_to_uint!(u8; via f32 (u16); via f64 (u32, u64, u128);); + +convert_uint_to_float!(u16; via f32 (f32); via f64 (f64);); +convert_uint_to_uint!(u16; via f32 (u8); via f64 (u32, u64, u128);); + +convert_uint_to_float!(u32; via f64 (f32, f64);); +convert_uint_to_uint!(u32; via f64 (u8, u16, u64, u128);); + +convert_uint_to_float!(u64; via f64 (f32, f64);); +convert_uint_to_uint!(u64; via f64 (u8, u16, u32, u128);); + +convert_uint_to_float!(u128; via f64 (f32, f64);); +convert_uint_to_uint!(u128; via f64 (u8, u16, u32, u64);); diff --git a/palette/src/convert.rs b/palette/src/convert.rs index ee3c1fb51..5a7bd2412 100644 --- a/palette/src/convert.rs +++ b/palette/src/convert.rs @@ -1,11 +1,9 @@ -use float::Float; - use core::fmt::{self, Display, Formatter}; -use {Component, Limited, Hsl, Hsv, Hwb, Lab, Lch, Xyz, Yxy}; -use white_point::{D65, WhitePoint}; -use rgb::{Rgb, RgbSpace}; -use luma::Luma; use encoding::Linear; +use luma::Luma; +use rgb::{Rgb, RgbSpace}; +use white_point::{WhitePoint, D65}; +use {FloatComponent, Hsl, Hsv, Hwb, Lab, Lch, Limited, Xyz, Yxy}; /// FromColor provides conversion from the colors. /// @@ -102,11 +100,10 @@ use encoding::Linear; /// #[macro_use] /// extern crate approx; /// -/// use palette::{Component, FromColor, Hsv, Pixel, Srgb}; +/// use palette::{FloatComponent, FromColor, Hsv, Pixel, Srgb}; /// use palette::rgb::{Rgb, RgbSpace}; /// use palette::encoding::Linear; /// use palette::white_point::D65; -/// use palette::float::Float; /// /// /// sRGB, but with a reversed memory layout. /// #[derive(PartialEq, Debug, FromColor, Pixel)] @@ -123,7 +120,7 @@ use encoding::Linear; /// // implementing a private conversion function and letting it /// // derive `From` automatically. It will take a round trip /// // through linear format, but that's fine in this case. -/// impl Bgr { +/// impl Bgr { /// // It converts from any linear Rgb type that has the D65 /// // white point, which is the default if we don't specify /// // anything else with the `palette_white_point` attribute. @@ -209,7 +206,7 @@ use encoding::Linear; /// ``` pub trait FromColor: Sized where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///Convert from XYZ color space @@ -343,11 +340,10 @@ where /// #[macro_use] /// extern crate approx; /// -/// use palette::{Component, Hsv, IntoColor, Pixel, Srgb}; +/// use palette::{FloatComponent, Hsv, IntoColor, Pixel, Srgb}; /// use palette::rgb::{Rgb, RgbSpace}; /// use palette::encoding::{Linear, self}; /// use palette::white_point::D65; -/// use palette::float::Float; /// /// type Hsv64 = Hsv; /// @@ -365,7 +361,7 @@ where /// // Rgb is a bit more complex than other colors, so we are /// // implementing a private conversion function and letting it /// // derive `Into` automatically. -/// impl Bgr { +/// impl Bgr { /// // It converts from any linear Rgb type that has the D65 /// // white point, which is the default if we don't specify /// // anything else with the `palette_white_point` attribute. @@ -441,7 +437,7 @@ where /// ``` pub trait IntoColor: Sized where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///Convert into XYZ space @@ -619,7 +615,10 @@ pub trait ConvertFrom: From { fn try_convert_from(_: T) -> Result>; } -impl ConvertFrom for U where U: From + Limited { +impl ConvertFrom for U +where + U: From + Limited, +{ fn convert_from(t: T) -> U { let mut this = U::from(t); if !this.is_valid() { @@ -639,7 +638,10 @@ impl ConvertFrom for U where U: From + Limited { } // ConvertFrom implies ConvertInto -impl ConvertInto for T where U: ConvertFrom { +impl ConvertInto for T +where + U: ConvertFrom, +{ #[inline] fn convert_into(self) -> U { U::convert_from(self) @@ -660,7 +662,7 @@ macro_rules! impl_into_color { ($self_ty: ident, $from_fn: ident) => { impl IntoColor for $self_ty where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn into_xyz(self) -> Xyz { @@ -702,7 +704,7 @@ macro_rules! impl_into_color_rgb { ($self_ty: ident, $from_fn: ident) => { impl IntoColor for $self_ty where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, S: RgbSpace, { @@ -752,11 +754,10 @@ impl_into_color_rgb!(Hwb, from_hwb); #[cfg(test)] mod tests { use core::marker::PhantomData; - use float::Float; - use Component; use encoding::linear::Linear; - use rgb::{Rgb, RgbSpace}; use luma::Luma; + use rgb::{Rgb, RgbSpace}; + use FloatComponent; use {Hsl, Hsv, Hwb, Lab, Lch, Xyz, Yxy}; #[derive(Copy, Clone, FromColor, IntoColor)] @@ -797,9 +798,9 @@ mod tests { #[palette_component = "T"] #[palette_rgb_space = "(::encoding::Srgb, ::white_point::E)"] #[palette_internal] - struct WithoutXyz(PhantomData); + struct WithoutXyz(PhantomData); - impl WithoutXyz { + impl WithoutXyz { fn from_luma_internal(_color: Luma, T>) -> Self { WithoutXyz(PhantomData) } @@ -809,13 +810,13 @@ mod tests { } } - impl From> for WithoutXyz { + impl From> for WithoutXyz { fn from(_color: Lch<::white_point::E, T>) -> Self { WithoutXyz(PhantomData) } } - impl Into> for WithoutXyz { + impl Into> for WithoutXyz { fn into(self) -> Lch<::white_point::E, T> { Lch::with_wp(T::one(), T::zero(), T::zero()) } diff --git a/palette/src/encoding/gamma.rs b/palette/src/encoding/gamma.rs index e270167dd..71d96de51 100644 --- a/palette/src/encoding/gamma.rs +++ b/palette/src/encoding/gamma.rs @@ -4,11 +4,11 @@ use core::marker::PhantomData; use float::Float; -use cast; -use rgb::{RgbSpace, RgbStandard}; -use luma::LumaStandard; use encoding::TransferFn; +use luma::LumaStandard; +use rgb::{RgbSpace, RgbStandard}; use white_point::WhitePoint; +use {from_f64, FromF64}; /// Gamma encoding. /// @@ -40,25 +40,25 @@ impl LumaStandard for Gamma { pub struct GammaFn(PhantomData); impl TransferFn for GammaFn { - fn into_linear(x: T) -> T { - x.powf(T::one() / cast(N::VALUE)) + fn into_linear(x: T) -> T { + x.powf(T::one() / from_f64(N::VALUE)) } - fn from_linear(x: T) -> T { - x.powf(cast(N::VALUE)) + fn from_linear(x: T) -> T { + x.powf(from_f64(N::VALUE)) } } /// A type level float constant. pub trait Number { /// The represented number. - const VALUE: f32; + const VALUE: f64; } -/// Represents `2.2f32`. +/// Represents `2.2f64`. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct F2p2; impl Number for F2p2 { - const VALUE: f32 = 2.2; + const VALUE: f64 = 2.2; } diff --git a/palette/src/encoding/mod.rs b/palette/src/encoding/mod.rs index a8ebba26f..0dff417ce 100644 --- a/palette/src/encoding/mod.rs +++ b/palette/src/encoding/mod.rs @@ -1,21 +1,22 @@ //! Various encoding traits, types and standards. use float::Float; +use FromF64; -pub use self::srgb::Srgb; pub use self::gamma::{F2p2, Gamma}; pub use self::linear::Linear; +pub use self::srgb::Srgb; -pub mod srgb; pub mod gamma; pub mod linear; pub mod pixel; +pub mod srgb; /// A transfer function to and from linear space. pub trait TransferFn { /// Convert the color component `x` from linear space. - fn from_linear(x: T) -> T; + fn from_linear(x: T) -> T; /// Convert the color component `x` into linear space. - fn into_linear(x: T) -> T; + fn into_linear(x: T) -> T; } diff --git a/palette/src/encoding/srgb.rs b/palette/src/encoding/srgb.rs index 522a8ede1..a92ec1cab 100644 --- a/palette/src/encoding/srgb.rs +++ b/palette/src/encoding/srgb.rs @@ -1,26 +1,26 @@ //! The sRGB standard. +use encoding::TransferFn; use float::Float; - -use rgb::{Primaries, RgbSpace, RgbStandard}; use luma::LumaStandard; -use encoding::TransferFn; -use white_point::{D65, WhitePoint}; -use {cast, Component, Yxy}; +use rgb::{Primaries, RgbSpace, RgbStandard}; +use white_point::{WhitePoint, D65}; +use {from_f64, FromF64}; +use {FloatComponent, Yxy}; ///The sRGB color space. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Srgb; impl Primaries for Srgb { - fn red() -> Yxy { - Yxy::with_wp(cast(0.6400), cast(0.3300), cast(0.212656)) + fn red() -> Yxy { + Yxy::with_wp(from_f64(0.6400), from_f64(0.3300), from_f64(0.212656)) } - fn green() -> Yxy { - Yxy::with_wp(cast(0.3000), cast(0.6000), cast(0.715158)) + fn green() -> Yxy { + Yxy::with_wp(from_f64(0.3000), from_f64(0.6000), from_f64(0.715158)) } - fn blue() -> Yxy { - Yxy::with_wp(cast(0.1500), cast(0.0600), cast(0.072186)) + fn blue() -> Yxy { + Yxy::with_wp(from_f64(0.1500), from_f64(0.0600), from_f64(0.072186)) } } @@ -40,19 +40,19 @@ impl LumaStandard for Srgb { } impl TransferFn for Srgb { - fn into_linear(x: T) -> T { - if x <= cast(0.04045) { - x / cast(12.92) + fn into_linear(x: T) -> T { + if x <= from_f64(0.04045) { + x / from_f64(12.92) } else { - ((x + cast(0.055)) / cast(1.055)).powf(cast(2.4)) + ((x + from_f64(0.055)) / from_f64(1.055)).powf(from_f64(2.4)) } } - fn from_linear(x: T) -> T { - if x <= cast(0.0031308) { - x * cast(12.92) + fn from_linear(x: T) -> T { + if x <= from_f64(0.0031308) { + x * from_f64(12.92) } else { - x.powf(T::one() / cast(2.4)) * cast(1.055) - cast(0.055) + x.powf(T::one() / from_f64(2.4)) * from_f64(1.055) - from_f64(0.055) } } } diff --git a/palette/src/equality.rs b/palette/src/equality.rs index 95de209dd..a933eb8a9 100644 --- a/palette/src/equality.rs +++ b/palette/src/equality.rs @@ -2,14 +2,14 @@ use float::Float; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use {cast, Component, Lab, LabHue, Lch, RgbHue, Xyz, Yxy}; use white_point::WhitePoint; +use {from_f64, FloatComponent, FromF64, Lab, LabHue, Lch, RgbHue, Xyz, Yxy}; macro_rules! impl_eq { ( $self_ty: ident , [$($element: ident),+]) => { impl AbsDiffEq for $self_ty - where T: Component + Float + AbsDiffEq, - T::Epsilon: Copy + Float, + where T: FloatComponent + AbsDiffEq, + T::Epsilon: Copy + FloatComponent, Wp: WhitePoint + PartialEq { type Epsilon = T::Epsilon; @@ -27,8 +27,8 @@ macro_rules! impl_eq { } impl RelativeEq for $self_ty - where T: Component + Float + RelativeEq, - T::Epsilon: Copy + Float, + where T: FloatComponent + RelativeEq, + T::Epsilon: Copy + FloatComponent, Wp: WhitePoint + PartialEq { fn default_max_relative() -> T::Epsilon { @@ -44,8 +44,8 @@ macro_rules! impl_eq { } impl UlpsEq for $self_ty - where T: Component + Float + UlpsEq, - T::Epsilon: Copy + Float, + where T: FloatComponent + UlpsEq, + T::Epsilon: Copy + FloatComponent, Wp: WhitePoint + PartialEq { fn default_max_ulps() -> u32 { @@ -77,13 +77,14 @@ impl_eq!(Lch, [l, chroma, hue]); // ulps. Because of this we loose some precision for values close to 0.0. macro_rules! impl_eq_hue { ( $self_ty: ident ) => { - impl AbsDiffEq for $self_ty - where T::Epsilon: Float + impl AbsDiffEq for $self_ty + where + T::Epsilon: Float + FromF64, { type Epsilon = T::Epsilon; fn default_epsilon() -> Self::Epsilon { - T::default_epsilon() * cast(180.0) + T::default_epsilon() * from_f64(180.0) } fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool { @@ -96,25 +97,37 @@ macro_rules! impl_eq_hue { } } - impl RelativeEq for $self_ty - where T::Epsilon: Float + impl RelativeEq for $self_ty + where + T::Epsilon: Float + FromF64, { fn default_max_relative() -> Self::Epsilon { - T::default_max_relative() * cast(180.0) + T::default_max_relative() * from_f64(180.0) } - fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool { + fn relative_eq( + &self, + other: &Self, + epsilon: T::Epsilon, + max_relative: T::Epsilon, + ) -> bool { let diff: T = (*self - *other).to_degrees(); T::relative_eq(&diff, &T::zero(), epsilon, max_relative) } - fn relative_ne(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool { + fn relative_ne( + &self, + other: &Self, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon, + ) -> bool { let diff: T = (*self - *other).to_degrees(); T::relative_ne(&diff, &T::zero(), epsilon, max_relative) } } - impl UlpsEq for $self_ty - where T::Epsilon: Float + impl UlpsEq for $self_ty + where + T::Epsilon: Float + FromF64, { fn default_max_ulps() -> u32 { T::default_max_ulps() * 180 @@ -129,7 +142,7 @@ macro_rules! impl_eq_hue { T::ulps_ne(&diff, &T::zero(), epsilon, max_ulps) } } - } + }; } impl_eq_hue!(LabHue); diff --git a/palette/src/gradient.rs b/palette/src/gradient.rs index 76c57dd98..dc921ddf4 100644 --- a/palette/src/gradient.rs +++ b/palette/src/gradient.rs @@ -3,12 +3,12 @@ //!This module is only available if the `std` feature is enabled (this is the //!default). -use num_traits::{One, Zero}; +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use float::Float; +use num_traits::{One, Zero}; use std::cmp::max; -use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use cast; +use {from_f64, FromF64}; use Mix; @@ -26,13 +26,16 @@ pub struct Gradient(Vec<(C::Scalar, C)>); impl Gradient { ///Create a gradient of evenly spaced colors with the domain [0.0, 1.0]. ///There must be at least one color. - pub fn new>(colors: I) -> Gradient { + pub fn new>(colors: I) -> Gradient + where + C::Scalar: FromF64, + { let mut points: Vec<_> = colors.into_iter().map(|c| (C::Scalar::zero(), c)).collect(); assert!(points.len() > 0); - let step_size = C::Scalar::one() / cast(max(points.len() - 1, 1) as f64); + let step_size = C::Scalar::one() / from_f64(max(points.len() - 1, 1) as f64); for (i, &mut (ref mut p, _)) in points.iter_mut().enumerate() { - *p = cast::(i) * step_size; + *p = from_f64::(i as f64) * step_size; } Gradient(points) @@ -51,7 +54,8 @@ impl Gradient { ///Get a color from the gradient. The color of the closest control point ///will be returned if `i` is outside the domain. pub fn get(&self, i: C::Scalar) -> C { - let &(mut min, ref min_color) = self.0 + let &(mut min, ref min_color) = self + .0 .get(0) .expect("a Gradient must contain at least one color"); let mut min_color = min_color; @@ -61,7 +65,8 @@ impl Gradient { return min_color.clone(); } - let &(mut max, ref max_color) = self.0 + let &(mut max, ref max_color) = self + .0 .last() .expect("a Gradient must contain at least one color"); let mut max_color = max_color; @@ -143,10 +148,12 @@ impl Gradient { ///Get the limits of this gradient's domain. pub fn domain(&self) -> (C::Scalar, C::Scalar) { - let &(min, _) = self.0 + let &(min, _) = self + .0 .get(0) .expect("a Gradient must contain at least one color"); - let &(max, _) = self.0 + let &(max, _) = self + .0 .last() .expect("a Gradient must contain at least one color"); (min, max) @@ -164,7 +171,10 @@ pub struct Take<'a, C: Mix + Clone + 'a> { from_end: usize, } -impl<'a, C: Mix + Clone> Iterator for Take<'a, C> { +impl<'a, C: Mix + Clone> Iterator for Take<'a, C> +where + C::Scalar: FromF64, +{ type Item = C; fn next(&mut self) -> Option { @@ -173,7 +183,9 @@ impl<'a, C: Mix + Clone> Iterator for Take<'a, C> { self.from_head += 1; Some(self.gradient.get(self.from)) } else { - let i = self.from + (self.diff / cast(self.len - 1)) * cast(self.from_head); + let i = self.from + + (self.diff / from_f64((self.len - 1) as f64)) + * from_f64(self.from_head as f64); self.from_head += 1; Some(self.gradient.get(i)) } @@ -183,20 +195,27 @@ impl<'a, C: Mix + Clone> Iterator for Take<'a, C> { } fn size_hint(&self) -> (usize, Option) { - (self.len - self.from_head - self.from_end, Some(self.len - self.from_head - self.from_end)) + ( + self.len - self.from_head - self.from_end, + Some(self.len - self.from_head - self.from_end), + ) } } -impl<'a, C: Mix + Clone> ExactSizeIterator for Take<'a, C> {} +impl<'a, C: Mix + Clone> ExactSizeIterator for Take<'a, C> where C::Scalar: FromF64 {} -impl<'a, C: Mix + Clone> DoubleEndedIterator for Take<'a, C> { +impl<'a, C: Mix + Clone> DoubleEndedIterator for Take<'a, C> +where + C::Scalar: FromF64, +{ fn next_back(&mut self) -> Option { if self.from_head + self.from_end < self.len { if self.len == 1 { self.from_end += 1; Some(self.gradient.get(self.from)) } else { - let i = self.from + (self.diff / cast(self.len - 1)) * cast(self.len - self.from_end - 1); + let i = self.from + + (self.diff / from_f64((self.len - 1) as f64)) * from_f64((self.len - self.from_end - 1) as f64); self.from_end += 1; Some(self.gradient.get(i)) } @@ -490,13 +509,25 @@ mod test { LinSrgb::new(0.0, 0.0, 1.0), ]); - let v1: Vec<_> = g.take(10).collect::>().iter().rev().cloned().collect(); + let v1: Vec<_> = g + .take(10) + .collect::>() + .iter() + .rev() + .cloned() + .collect(); let v2: Vec<_> = g.take(10).rev().collect(); for (t1, t2) in v1.iter().zip(v2.iter()) { assert_relative_eq!(t1, t2); } //make sure `take(1).rev()` doesn't produce NaN results - let v1: Vec<_> = g.take(1).collect::>().iter().rev().cloned().collect(); + let v1: Vec<_> = g + .take(1) + .collect::>() + .iter() + .rev() + .cloned() + .collect(); let v2: Vec<_> = g.take(1).rev().collect(); for (t1, t2) in v1.iter().zip(v2.iter()) { assert_relative_eq!(t1, t2); diff --git a/palette/src/hsl.rs b/palette/src/hsl.rs index b0256d6de..2fbbd7845 100644 --- a/palette/src/hsl.rs +++ b/palette/src/hsl.rs @@ -9,8 +9,8 @@ use encoding::pixel::RawPixel; use encoding::{Linear, Srgb}; use rgb::{Rgb, RgbSpace}; use { - cast, clamp, Alpha, Component, FromColor, GetHue, Hsv, Hue, IntoColor, Limited, Mix, Pixel, - RgbHue, Saturate, Shade, Xyz, + clamp, from_f64, Alpha, Component, FloatComponent, FromColor, FromF64, GetHue, Hsv, Hue, + IntoColor, Limited, Mix, Pixel, RgbHue, Saturate, Shade, Xyz, }; /// Linear HSL with an alpha component. See the [`Hsla` implementation in @@ -38,7 +38,7 @@ pub type Hsla = Alpha, T>; #[repr(C)] pub struct Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { ///The hue of the color, in degrees. Decides if it's red, blue, purple, @@ -63,14 +63,14 @@ where impl Copy for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { } impl Clone for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn clone(&self) -> Hsl { @@ -80,7 +80,7 @@ where impl Hsl where - T: Component + Float, + T: FloatComponent, { ///HSL for linear sRGB. pub fn new>>(hue: H, saturation: T, lightness: T) -> Hsl { @@ -95,7 +95,7 @@ where impl Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { ///Linear HSL. @@ -135,16 +135,12 @@ where let (max, min, sep, coeff) = if rgb.red > rgb.green { (rgb.red, rgb.green, rgb.green - rgb.blue, T::zero()) } else { - (rgb.green, rgb.red, rgb.blue - rgb.red, cast(2.0)) + (rgb.green, rgb.red, rgb.blue - rgb.red, from_f64(2.0)) }; if rgb.blue > max { - (rgb.blue, min, rgb.red - rgb.green, cast(4.0)) + (rgb.blue, min, rgb.red - rgb.green, from_f64(4.0)) } else { - let min_val = if rgb.blue < min { - rgb.blue - } else { - min - }; + let min_val = if rgb.blue < min { rgb.blue } else { min }; (max, min_val, sep, coeff) } }; @@ -153,15 +149,15 @@ where let mut s = T::zero(); let sum = max + min; - let l = sum / cast(2.0); + let l = sum / from_f64(2.0); if max != min { let d = max - min; s = if sum > T::one() { - d / (cast::(2.0) - sum) + d / (from_f64::(2.0) - sum) } else { d / sum }; - h = ((sep / d) + coeff) * cast(60.0); + h = ((sep / d) + coeff) * from_f64(60.0); }; Hsl { @@ -186,7 +182,7 @@ where ///[`Hsla`](type.Hsla.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, { ///HSL and transparency for linear sRGB. @@ -201,7 +197,7 @@ where ///[`Hsla`](type.Hsla.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, S: RgbSpace, { @@ -228,7 +224,7 @@ where impl From> for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn from(color: Xyz) -> Self { @@ -239,14 +235,14 @@ where impl From> for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, Sp: RgbSpace, { fn from(color: Hsv) -> Self { let hsv = Hsv::::from_hsv(color); - let x = (cast::(2.0) - hsv.saturation) * hsv.value; + let x = (from_f64::(2.0) - hsv.saturation) * hsv.value; let saturation = if !hsv.value.is_normal() { T::zero() } else if x < T::one() { @@ -256,7 +252,7 @@ where T::zero() } } else { - let denom = cast::(2.0) - x; + let denom = from_f64::(2.0) - x; if denom.is_normal() { hsv.saturation * hsv.value / denom } else { @@ -267,25 +263,25 @@ where Hsl { hue: hsv.hue, saturation: saturation, - lightness: x / cast(2.0), + lightness: x / from_f64(2.0), space: PhantomData, } } } -impl>> From<(H, T, T)> for Hsl { +impl>> From<(H, T, T)> for Hsl { fn from(components: (H, T, T)) -> Self { Self::from_components(components) } } -impl Into<(RgbHue, T, T)> for Hsl { +impl Into<(RgbHue, T, T)> for Hsl { fn into(self) -> (RgbHue, T, T) { self.into_components() } } -impl>, A: Component> From<(H, T, T, A)> +impl>, A: Component> From<(H, T, T, A)> for Alpha, A> { fn from(components: (H, T, T, A)) -> Self { @@ -293,7 +289,7 @@ impl>, A: Component> From<( } } -impl Into<(RgbHue, T, T, A)> +impl Into<(RgbHue, T, T, A)> for Alpha, A> { fn into(self) -> (RgbHue, T, T, A) { @@ -303,7 +299,7 @@ impl Into<(RgbHue, T, T, A)> impl Limited for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { #[cfg_attr(rustfmt, rustfmt_skip)] @@ -326,7 +322,7 @@ where impl Mix for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Scalar = T; @@ -346,7 +342,7 @@ where impl Shade for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Scalar = T; @@ -363,7 +359,7 @@ where impl GetHue for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Hue = RgbHue; @@ -379,7 +375,7 @@ where impl Hue for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn with_hue>(&self, hue: H) -> Hsl { @@ -403,7 +399,7 @@ where impl Saturate for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Scalar = T; @@ -420,7 +416,7 @@ where impl Default for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn default() -> Hsl { @@ -430,7 +426,7 @@ where impl Add> for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hsl; @@ -447,7 +443,7 @@ where impl Add for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hsl; @@ -463,9 +459,9 @@ where } impl AddAssign> for Hsl - where - T: Component + Float + AddAssign, - S: RgbSpace, +where + T: FloatComponent + AddAssign, + S: RgbSpace, { fn add_assign(&mut self, other: Hsl) { self.hue += other.hue; @@ -475,9 +471,9 @@ impl AddAssign> for Hsl } impl AddAssign for Hsl - where - T: Component + Float + AddAssign, - S: RgbSpace, +where + T: FloatComponent + AddAssign, + S: RgbSpace, { fn add_assign(&mut self, c: T) { self.hue += c; @@ -488,7 +484,7 @@ impl AddAssign for Hsl impl Sub> for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hsl; @@ -505,7 +501,7 @@ where impl Sub for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hsl; @@ -521,9 +517,9 @@ where } impl SubAssign> for Hsl - where - T: Component + Float + SubAssign, - S: RgbSpace, +where + T: FloatComponent + SubAssign, + S: RgbSpace, { fn sub_assign(&mut self, other: Hsl) { self.hue -= other.hue; @@ -533,9 +529,9 @@ impl SubAssign> for Hsl } impl SubAssign for Hsl - where - T: Component + Float + SubAssign, - S: RgbSpace, +where + T: FloatComponent + SubAssign, + S: RgbSpace, { fn sub_assign(&mut self, c: T) { self.hue -= c; @@ -546,7 +542,7 @@ impl SubAssign for Hsl impl AsRef

for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, P: RawPixel + ?Sized, { @@ -557,7 +553,7 @@ where impl AsMut

for Hsl where - T: Component + Float, + T: FloatComponent, S: RgbSpace, P: RawPixel + ?Sized, { @@ -568,8 +564,8 @@ where impl AbsDiffEq for Hsl where - T: Component + Float + AbsDiffEq, - T::Epsilon: Copy + Float, + T: FloatComponent + AbsDiffEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { type Epsilon = T::Epsilon; @@ -579,16 +575,16 @@ where } fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool { - self.hue.abs_diff_eq(&other.hue, epsilon) && - self.saturation.abs_diff_eq(&other.saturation, epsilon) && - self.lightness.abs_diff_eq(&other.lightness, epsilon) + self.hue.abs_diff_eq(&other.hue, epsilon) + && self.saturation.abs_diff_eq(&other.saturation, epsilon) + && self.lightness.abs_diff_eq(&other.lightness, epsilon) } } impl RelativeEq for Hsl where - T: Component + Float + RelativeEq, - T::Epsilon: Copy + Float, + T: FloatComponent + RelativeEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { fn default_max_relative() -> Self::Epsilon { @@ -610,8 +606,8 @@ where impl UlpsEq for Hsl where - T: Component + Float + UlpsEq, - T::Epsilon: Copy + Float, + T: FloatComponent + UlpsEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { fn default_max_ulps() -> u32 { @@ -684,7 +680,7 @@ mod test { #[test] fn ranges() { - assert_ranges!{ + assert_ranges! { Hsl; limited { saturation: 0.0 => 1.0, diff --git a/palette/src/hsv.rs b/palette/src/hsv.rs index fd147f868..7296c5f03 100644 --- a/palette/src/hsv.rs +++ b/palette/src/hsv.rs @@ -8,9 +8,12 @@ use core::ops::{Add, AddAssign, Sub, SubAssign}; use encoding::pixel::RawPixel; use encoding::{Linear, Srgb}; use rgb::{Rgb, RgbSpace}; -use {cast, clamp}; +use {clamp, from_f64}; use {Alpha, Hsl, Hwb, Xyz}; -use {Component, FromColor, GetHue, Hue, Limited, Mix, Pixel, RgbHue, Saturate, Shade}; +use { + Component, FloatComponent, FromColor, FromF64, GetHue, Hue, Limited, Mix, Pixel, RgbHue, + Saturate, Shade, +}; /// Linear HSV with an alpha component. See the [`Hsva` implementation in /// `Alpha`](struct.Alpha.html#Hsva). @@ -34,7 +37,7 @@ pub type Hsva = Alpha, T>; #[repr(C)] pub struct Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { ///The hue of the color, in degrees. Decides if it's red, blue, purple, @@ -60,14 +63,14 @@ where impl Copy for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { } impl Clone for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn clone(&self) -> Hsv { @@ -77,7 +80,7 @@ where impl Hsv where - T: Component + Float, + T: FloatComponent, { ///HSV for linear sRGB. pub fn new>>(hue: H, saturation: T, value: T) -> Hsv { @@ -92,7 +95,7 @@ where impl Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { ///Linear HSV. @@ -132,16 +135,12 @@ where let (max, min, sep, coeff) = if rgb.red > rgb.green { (rgb.red, rgb.green, rgb.green - rgb.blue, T::zero()) } else { - (rgb.green, rgb.red, rgb.blue - rgb.red, cast(2.0)) + (rgb.green, rgb.red, rgb.blue - rgb.red, from_f64(2.0)) }; if rgb.blue > max { - (rgb.blue, min, rgb.red - rgb.green, cast(4.0)) + (rgb.blue, min, rgb.red - rgb.green, from_f64(4.0)) } else { - let min_val = if rgb.blue < min { - rgb.blue - } else { - min - }; + let min_val = if rgb.blue < min { rgb.blue } else { min }; (max, min_val, sep, coeff) } }; @@ -153,7 +152,7 @@ where if max != min { let d = max - min; s = d / max; - h = ((sep / d) + coeff) * cast(60.0); + h = ((sep / d) + coeff) * from_f64(60.0); }; Hsv { @@ -178,7 +177,7 @@ where ///[`Hsva`](type.Hsva.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, { ///HSV and transparency for linear sRGB. @@ -193,7 +192,7 @@ where ///[`Hsva`](type.Hsva.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, S: RgbSpace, { @@ -220,7 +219,7 @@ where impl From> for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn from(color: Xyz) -> Self { @@ -231,24 +230,25 @@ where impl From> for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, Sp: RgbSpace, { fn from(color: Hsl) -> Self { let hsl = Hsl::::from_hsl(color); - let x = hsl.saturation * if hsl.lightness < cast(0.5) { - hsl.lightness - } else { - T::one() - hsl.lightness - }; + let x = hsl.saturation + * if hsl.lightness < from_f64(0.5) { + hsl.lightness + } else { + T::one() - hsl.lightness + }; let mut s = T::zero(); // avoid divide by zero let denom = hsl.lightness + x; if denom.is_normal() { - s = x * cast(2.0) / denom; + s = x * from_f64(2.0) / denom; } Hsv { hue: hsl.hue, @@ -261,7 +261,7 @@ where impl From> for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, Sp: RgbSpace, { @@ -284,19 +284,19 @@ where } } -impl>> From<(H, T, T)> for Hsv { +impl>> From<(H, T, T)> for Hsv { fn from(components: (H, T, T)) -> Self { Self::from_components(components) } } -impl Into<(RgbHue, T, T)> for Hsv { +impl Into<(RgbHue, T, T)> for Hsv { fn into(self) -> (RgbHue, T, T) { self.into_components() } } -impl>, A: Component> From<(H, T, T, A)> +impl>, A: Component> From<(H, T, T, A)> for Alpha, A> { fn from(components: (H, T, T, A)) -> Self { @@ -304,7 +304,7 @@ impl>, A: Component> From<( } } -impl Into<(RgbHue, T, T, A)> +impl Into<(RgbHue, T, T, A)> for Alpha, A> { fn into(self) -> (RgbHue, T, T, A) { @@ -314,7 +314,7 @@ impl Into<(RgbHue, T, T, A)> impl Limited for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { #[cfg_attr(rustfmt, rustfmt_skip)] @@ -337,7 +337,7 @@ where impl Mix for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Scalar = T; @@ -357,7 +357,7 @@ where impl Shade for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Scalar = T; @@ -374,7 +374,7 @@ where impl GetHue for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Hue = RgbHue; @@ -390,7 +390,7 @@ where impl Hue for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn with_hue>(&self, hue: H) -> Hsv { @@ -414,7 +414,7 @@ where impl Saturate for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Scalar = T; @@ -431,7 +431,7 @@ where impl Default for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn default() -> Hsv { @@ -441,7 +441,7 @@ where impl Add> for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hsv; @@ -458,12 +458,12 @@ where impl Add for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hsv; - fn add(self, c: T) -> Self::Output{ + fn add(self, c: T) -> Self::Output { Hsv { hue: self.hue + c, saturation: self.saturation + c, @@ -474,9 +474,9 @@ where } impl AddAssign> for Hsv - where - T: Component + Float + AddAssign, - S: RgbSpace, +where + T: FloatComponent + AddAssign, + S: RgbSpace, { fn add_assign(&mut self, other: Hsv) { self.hue += other.hue; @@ -486,9 +486,9 @@ impl AddAssign> for Hsv } impl AddAssign for Hsv - where - T: Component + Float + AddAssign, - S: RgbSpace, +where + T: FloatComponent + AddAssign, + S: RgbSpace, { fn add_assign(&mut self, c: T) { self.hue += c; @@ -499,7 +499,7 @@ impl AddAssign for Hsv impl Sub> for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hsv; @@ -516,7 +516,7 @@ where impl Sub for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hsv; @@ -532,9 +532,9 @@ where } impl SubAssign> for Hsv - where - T: Component + Float + SubAssign, - S: RgbSpace, +where + T: FloatComponent + SubAssign, + S: RgbSpace, { fn sub_assign(&mut self, other: Hsv) { self.hue -= other.hue; @@ -544,9 +544,9 @@ impl SubAssign> for Hsv } impl SubAssign for Hsv - where - T: Component + Float + SubAssign, - S: RgbSpace, +where + T: FloatComponent + SubAssign, + S: RgbSpace, { fn sub_assign(&mut self, c: T) { self.hue -= c; @@ -557,7 +557,7 @@ impl SubAssign for Hsv impl AsRef

for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, P: RawPixel + ?Sized, { @@ -568,7 +568,7 @@ where impl AsMut

for Hsv where - T: Component + Float, + T: FloatComponent, S: RgbSpace, P: RawPixel + ?Sized, { @@ -579,8 +579,8 @@ where impl AbsDiffEq for Hsv where - T: Component + Float + AbsDiffEq, - T::Epsilon: Copy + Float, + T: FloatComponent + AbsDiffEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { type Epsilon = T::Epsilon; @@ -590,16 +590,16 @@ where } fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool { - self.hue.abs_diff_eq(&other.hue, epsilon) && - self.saturation.abs_diff_eq(&other.saturation, epsilon) && - self.value.abs_diff_eq(&other.value, epsilon) + self.hue.abs_diff_eq(&other.hue, epsilon) + && self.saturation.abs_diff_eq(&other.saturation, epsilon) + && self.value.abs_diff_eq(&other.value, epsilon) } } impl RelativeEq for Hsv where - T: Component + Float + RelativeEq, - T::Epsilon: Copy + Float, + T: FloatComponent + RelativeEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { fn default_max_relative() -> Self::Epsilon { @@ -621,8 +621,8 @@ where impl UlpsEq for Hsv where - T: Component + Float + UlpsEq, - T::Epsilon: Copy + Float, + T: FloatComponent + UlpsEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { fn default_max_ulps() -> u32 { @@ -695,7 +695,7 @@ mod test { #[test] fn ranges() { - assert_ranges!{ + assert_ranges! { Hsv; limited { saturation: 0.0 => 1.0, diff --git a/palette/src/hues.rs b/palette/src/hues.rs index 42148c0cd..657d4d04e 100644 --- a/palette/src/hues.rs +++ b/palette/src/hues.rs @@ -1,10 +1,8 @@ use float::Float; -use core::f64::consts::PI; use core::cmp::PartialEq; use core::ops::{Add, AddAssign, Sub, SubAssign}; - -use cast; +use {from_f64, FromF64}; macro_rules! make_hues { ($($(#[$doc:meta])+ struct $name:ident;)+) => ($( @@ -20,7 +18,7 @@ macro_rules! make_hues { #[repr(C)] pub struct $name(T); - impl $name { + impl $name { /// Create a new hue from degrees. #[inline] pub fn from_degrees(degrees: T) -> $name { @@ -30,7 +28,7 @@ macro_rules! make_hues { /// Create a new hue from radians, instead of degrees. #[inline] pub fn from_radians(radians: T) -> $name { - $name(radians * cast(180.0) / cast(PI)) + $name(radians.to_degrees()) } /// Get the hue as degrees, in the range `(-180, 180]`. @@ -42,7 +40,7 @@ macro_rules! make_hues { /// Convert the hue to radians, in the range `(-π, π]`. #[inline] pub fn to_radians(self) -> T { - normalize_angle(self.0) * cast(PI) / cast(180.0) + normalize_angle(self.0).to_radians() } /// Convert the hue to positive degrees, in the range `[0, 360)`. @@ -54,7 +52,7 @@ macro_rules! make_hues { /// Convert the hue to positive radians, in the range `[0, 2π)`. #[inline] pub fn to_positive_radians(self) -> T { - normalize_angle_positive(self.0) * cast(PI) / cast(180.0) + normalize_angle_positive(self.0).to_radians() } /// Get the internal representation, without normalizing it. @@ -66,7 +64,7 @@ macro_rules! make_hues { /// Get the internal representation as radians, without normalizing it. #[inline] pub fn to_raw_radians(self) -> T { - self.0 * cast(PI) / cast(180.0) + self.0.to_radians() } } @@ -97,7 +95,7 @@ macro_rules! make_hues { } } - impl PartialEq for $name { + impl PartialEq for $name { #[inline] fn eq(&self, other: &$name) -> bool { let hue_s: T = (*self).to_degrees(); @@ -106,7 +104,7 @@ macro_rules! make_hues { } } - impl PartialEq for $name { + impl PartialEq for $name { #[inline] fn eq(&self, other: &T) -> bool { let hue: T = (*self).to_degrees(); @@ -213,7 +211,7 @@ macro_rules! make_hues { $name(self - other.0) } } - + impl SubAssign<$name> for $name { #[inline] fn sub_assign(&mut self, other: $name) { @@ -260,22 +258,22 @@ make_hues! { } #[inline] -fn normalize_angle(deg: T) -> T { - let c360 = cast(360.0); - let c180 = cast(180.0); +fn normalize_angle(deg: T) -> T { + let c360 = from_f64(360.0); + let c180 = from_f64(180.0); deg - (((deg + c180) / c360) - T::one()).ceil() * c360 } #[inline] -fn normalize_angle_positive(deg: T) -> T { - let c360 = cast(360.0); +fn normalize_angle_positive(deg: T) -> T { + let c360 = from_f64(360.0); deg - ((deg / c360).floor() * c360) } #[cfg(test)] mod test { - use RgbHue; use super::{normalize_angle, normalize_angle_positive}; + use RgbHue; #[test] fn normalize_angle_0_360() { diff --git a/palette/src/hwb.rs b/palette/src/hwb.rs index d8f375a88..042b47319 100644 --- a/palette/src/hwb.rs +++ b/palette/src/hwb.rs @@ -9,8 +9,8 @@ use encoding::pixel::RawPixel; use encoding::Srgb; use rgb::RgbSpace; use { - clamp, Alpha, Component, FromColor, GetHue, Hsv, Hue, IntoColor, Limited, Mix, Pixel, RgbHue, - Shade, Xyz, + clamp, Alpha, Component, FloatComponent, FromColor, FromF64, GetHue, Hsv, Hue, IntoColor, + Limited, Mix, Pixel, RgbHue, Shade, Xyz, }; /// Linear HWB with an alpha component. See the [`Hwba` implementation in @@ -36,7 +36,7 @@ pub type Hwba = Alpha, T>; #[repr(C)] pub struct Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { ///The hue of the color, in degrees. Decides if it's red, blue, purple, @@ -66,14 +66,14 @@ where impl Copy for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { } impl Clone for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn clone(&self) -> Hwb { @@ -83,7 +83,7 @@ where impl Hwb where - T: Component + Float, + T: FloatComponent, { ///HWB for linear sRGB. pub fn new>>(hue: H, whiteness: T, blackness: T) -> Hwb { @@ -98,7 +98,7 @@ where impl Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { ///Linear HWB. @@ -143,7 +143,7 @@ where ///[`Hwba`](type.Hwba.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, { ///HWB and transparency for linear sRGB. @@ -158,7 +158,7 @@ where ///[`Hwba`](type.Hwba.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, S: RgbSpace, { @@ -185,7 +185,7 @@ where impl From> for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn from(color: Xyz) -> Self { @@ -196,7 +196,7 @@ where impl From> for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, Sp: RgbSpace, { @@ -212,19 +212,19 @@ where } } -impl>> From<(H, T, T)> for Hwb { +impl>> From<(H, T, T)> for Hwb { fn from(components: (H, T, T)) -> Self { Self::from_components(components) } } -impl Into<(RgbHue, T, T)> for Hwb { +impl Into<(RgbHue, T, T)> for Hwb { fn into(self) -> (RgbHue, T, T) { self.into_components() } } -impl>, A: Component> From<(H, T, T, A)> +impl>, A: Component> From<(H, T, T, A)> for Alpha, A> { fn from(components: (H, T, T, A)) -> Self { @@ -232,7 +232,7 @@ impl>, A: Component> From<( } } -impl Into<(RgbHue, T, T, A)> +impl Into<(RgbHue, T, T, A)> for Alpha, A> { fn into(self) -> (RgbHue, T, T, A) { @@ -242,7 +242,7 @@ impl Into<(RgbHue, T, T, A)> impl Limited for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { #[cfg_attr(rustfmt, rustfmt_skip)] @@ -271,7 +271,7 @@ where impl Mix for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Scalar = T; @@ -291,7 +291,7 @@ where impl Shade for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Scalar = T; @@ -308,7 +308,7 @@ where impl GetHue for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Hue = RgbHue; @@ -324,7 +324,7 @@ where impl Hue for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn with_hue>(&self, hue: H) -> Hwb { @@ -348,7 +348,7 @@ where impl Default for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { fn default() -> Hwb { @@ -358,7 +358,7 @@ where impl Add> for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hwb; @@ -375,7 +375,7 @@ where impl Add for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hwb; @@ -391,9 +391,9 @@ where } impl AddAssign> for Hwb - where - T: Component + Float + AddAssign, - S: RgbSpace, +where + T: FloatComponent + AddAssign, + S: RgbSpace, { fn add_assign(&mut self, other: Hwb) { self.hue += other.hue; @@ -403,9 +403,9 @@ impl AddAssign> for Hwb } impl AddAssign for Hwb - where - T: Component + Float + AddAssign, - S: RgbSpace, +where + T: FloatComponent + AddAssign, + S: RgbSpace, { fn add_assign(&mut self, c: T) { self.hue += c; @@ -416,7 +416,7 @@ impl AddAssign for Hwb impl Sub> for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hwb; @@ -433,7 +433,7 @@ where impl Sub for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, { type Output = Hwb; @@ -448,11 +448,10 @@ where } } - impl SubAssign> for Hwb - where - T: Component + Float + SubAssign, - S: RgbSpace, +where + T: FloatComponent + SubAssign, + S: RgbSpace, { fn sub_assign(&mut self, other: Hwb) { self.hue -= other.hue; @@ -462,9 +461,9 @@ impl SubAssign> for Hwb } impl SubAssign for Hwb - where - T: Component + Float + SubAssign, - S: RgbSpace, +where + T: FloatComponent + SubAssign, + S: RgbSpace, { fn sub_assign(&mut self, c: T) { self.hue -= c; @@ -475,7 +474,7 @@ impl SubAssign for Hwb impl AsRef

for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, P: RawPixel + ?Sized, { @@ -486,7 +485,7 @@ where impl AsMut

for Hwb where - T: Component + Float, + T: FloatComponent, S: RgbSpace, P: RawPixel + ?Sized, { @@ -497,8 +496,8 @@ where impl AbsDiffEq for Hwb where - T: Component + Float + AbsDiffEq, - T::Epsilon: Copy + Float, + T: FloatComponent + AbsDiffEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { type Epsilon = T::Epsilon; @@ -508,12 +507,8 @@ where } fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { - let equal_shade = self - .whiteness - .abs_diff_eq(&other.whiteness, epsilon) - && self - .blackness - .abs_diff_eq(&other.blackness, epsilon); + let equal_shade = self.whiteness.abs_diff_eq(&other.whiteness, epsilon) + && self.blackness.abs_diff_eq(&other.blackness, epsilon); // The hue doesn't matter that much when the color is gray, and may fluctuate // due to precision errors. This is a blunt tool, but works for now. @@ -529,8 +524,8 @@ where impl RelativeEq for Hwb where - T: Component + Float + RelativeEq, - T::Epsilon: Copy + Float, + T: FloatComponent + RelativeEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { fn default_max_relative() -> Self::Epsilon { @@ -547,8 +542,8 @@ where .whiteness .relative_eq(&other.whiteness, epsilon, max_relative) && self - .blackness - .relative_eq(&other.blackness, epsilon, max_relative); + .blackness + .relative_eq(&other.blackness, epsilon, max_relative); // The hue doesn't matter that much when the color is gray, and may fluctuate // due to precision errors. This is a blunt tool, but works for now. @@ -564,8 +559,8 @@ where impl UlpsEq for Hwb where - T: Component + Float + UlpsEq, - T::Epsilon: Copy + Float, + T: FloatComponent + UlpsEq, + T::Epsilon: Copy + Float + FromF64, S: RgbSpace + PartialEq, { fn default_max_ulps() -> u32 { @@ -573,12 +568,8 @@ where } fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { - let equal_shade = self - .whiteness - .ulps_eq(&other.whiteness, epsilon, max_ulps) - && self - .blackness - .ulps_eq(&other.blackness, epsilon, max_ulps); + let equal_shade = self.whiteness.ulps_eq(&other.whiteness, epsilon, max_ulps) + && self.blackness.ulps_eq(&other.blackness, epsilon, max_ulps); // The hue doesn't matter that much when the color is gray, and may fluctuate // due to precision errors. This is a blunt tool, but works for now. diff --git a/palette/src/lab.rs b/palette/src/lab.rs index 8ae7af8d3..6e18c9a2f 100644 --- a/palette/src/lab.rs +++ b/palette/src/lab.rs @@ -1,13 +1,11 @@ -use float::Float; - use core::marker::PhantomData; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; use encoding::pixel::RawPixel; -use white_point::{D65, WhitePoint}; -use {cast, clamp}; +use white_point::{WhitePoint, D65}; +use {clamp, from_f64}; use {Alpha, LabHue, Lch, Xyz}; -use {Component, ComponentWise, GetHue, Limited, Mix, Pixel, Shade}; +use {Component, ComponentWise, FloatComponent, GetHue, Limited, Mix, Pixel, Shade}; /// CIE L\*a\*b\* (CIELAB) with an alpha component. See the [`Laba` /// implementation in `Alpha`](struct.Alpha.html#Laba). @@ -33,7 +31,7 @@ pub type Laba = Alpha, T>; #[repr(C)] pub struct Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///L\* is the lightness of the color. 0.0 gives absolute black and 100 @@ -55,14 +53,14 @@ where impl Copy for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { } impl Clone for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn clone(&self) -> Lab { @@ -72,7 +70,7 @@ where impl Lab where - T: Component + Float, + T: FloatComponent, { ///CIE L\*a\*b\* with white point D65. pub fn new(l: T, a: T, b: T) -> Lab { @@ -87,7 +85,7 @@ where impl Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///CIE L\*a\*b\*. @@ -114,7 +112,7 @@ where ///[`Laba`](type.Laba.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, { ///CIE L\*a\*b\* and transparency and white point D65. @@ -129,7 +127,7 @@ where ///[`Laba`](type.Laba.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, Wp: WhitePoint, { @@ -154,7 +152,7 @@ where impl From> for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn from(color: Xyz) -> Self { @@ -165,10 +163,10 @@ where .. } = color / Wp::get_xyz(); - fn convert(c: T) -> T { - let epsilon: T = (cast::(6.0 / 29.0)).powi(3); - let kappa: T = cast(841.0 / 108.0); - let delta: T = cast(4.0 / 29.0); + fn convert(c: T) -> T { + let epsilon = from_f64::(6.0 / 29.0).powi(3); + let kappa: T = from_f64(841.0 / 108.0); + let delta: T = from_f64(4.0 / 29.0); if c > epsilon { c.cbrt() } else { @@ -181,9 +179,9 @@ where z = convert(z); Lab { - l: ((y * cast(116.0)) - cast(16.0)), - a: ((x - y) * cast(500.0)), - b: ((y - z) * cast(200.0)), + l: ((y * from_f64(116.0)) - from_f64(16.0)), + a: ((x - y) * from_f64(500.0)), + b: ((y - z) * from_f64(200.0)), white_point: PhantomData, } } @@ -191,7 +189,7 @@ where impl From> for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn from(color: Lch) -> Self { @@ -204,29 +202,25 @@ where } } -impl From<(T, T, T)> for Lab { +impl From<(T, T, T)> for Lab { fn from(components: (T, T, T)) -> Self { Self::from_components(components) } } -impl Into<(T, T, T)> for Lab { +impl Into<(T, T, T)> for Lab { fn into(self) -> (T, T, T) { self.into_components() } } -impl From<(T, T, T, A)> - for Alpha, A> -{ +impl From<(T, T, T, A)> for Alpha, A> { fn from(components: (T, T, T, A)) -> Self { Self::from_components(components) } } -impl Into<(T, T, T, A)> - for Alpha, A> -{ +impl Into<(T, T, T, A)> for Alpha, A> { fn into(self) -> (T, T, T, A) { self.into_components() } @@ -234,14 +228,14 @@ impl Into<(T, T, T, A)> impl Limited for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { #[cfg_attr(rustfmt, rustfmt_skip)] fn is_valid(&self) -> bool { - self.l >= T::zero() && self.l <= cast(100.0) && - self.a >= cast(-128) && self.a <= cast(127.0) && - self.b >= cast(-128) && self.b <= cast(127.0) + self.l >= T::zero() && self.l <= from_f64(100.0) && + self.a >= from_f64(-128.0) && self.a <= from_f64(127.0) && + self.b >= from_f64(-128.0) && self.b <= from_f64(127.0) } fn clamp(&self) -> Lab { @@ -251,15 +245,15 @@ where } fn clamp_self(&mut self) { - self.l = clamp(self.l, T::zero(), cast(100.0)); - self.a = clamp(self.a, cast(-128.0), cast(127.0)); - self.b = clamp(self.b, cast(-128.0), cast(127.0)); + self.l = clamp(self.l, T::zero(), from_f64(100.0)); + self.a = clamp(self.a, from_f64(-128.0), from_f64(127.0)); + self.b = clamp(self.b, from_f64(-128.0), from_f64(127.0)); } } impl Mix for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -278,14 +272,14 @@ where impl Shade for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; fn lighten(&self, amount: T) -> Lab { Lab { - l: self.l + amount * cast(100.0), + l: self.l + amount * from_f64(100.0), a: self.a, b: self.b, white_point: PhantomData, @@ -295,7 +289,7 @@ where impl GetHue for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Hue = LabHue; @@ -311,7 +305,7 @@ where impl ComponentWise for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -337,7 +331,7 @@ where impl Default for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn default() -> Lab { @@ -347,7 +341,7 @@ where impl Add> for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lab; @@ -364,7 +358,7 @@ where impl Add for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lab; @@ -380,9 +374,9 @@ where } impl AddAssign> for Lab - where - T: Component + Float + AddAssign, - Wp: WhitePoint, +where + T: FloatComponent + AddAssign, + Wp: WhitePoint, { fn add_assign(&mut self, other: Lab) { self.l += other.l; @@ -392,9 +386,9 @@ impl AddAssign> for Lab } impl AddAssign for Lab - where - T: Component + Float + AddAssign, - Wp: WhitePoint, +where + T: FloatComponent + AddAssign, + Wp: WhitePoint, { fn add_assign(&mut self, c: T) { self.l += c; @@ -405,7 +399,7 @@ impl AddAssign for Lab impl Sub> for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lab; @@ -422,7 +416,7 @@ where impl Sub for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lab; @@ -438,21 +432,21 @@ where } impl SubAssign> for Lab - where - T: Component + Float + SubAssign, - Wp: WhitePoint, +where + T: FloatComponent + SubAssign, + Wp: WhitePoint, { fn sub_assign(&mut self, other: Lab) { - self.l -= other.l; - self.a -= other.a; - self.b -= other.b; + self.l -= other.l; + self.a -= other.a; + self.b -= other.b; } } impl SubAssign for Lab - where - T: Component + Float + SubAssign, - Wp: WhitePoint, +where + T: FloatComponent + SubAssign, + Wp: WhitePoint, { fn sub_assign(&mut self, c: T) { self.l -= c; @@ -463,7 +457,7 @@ impl SubAssign for Lab impl Mul> for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lab; @@ -480,7 +474,7 @@ where impl Mul for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lab; @@ -496,9 +490,9 @@ where } impl MulAssign> for Lab - where - T: Component + Float + MulAssign, - Wp: WhitePoint, +where + T: FloatComponent + MulAssign, + Wp: WhitePoint, { fn mul_assign(&mut self, other: Lab) { self.l *= other.l; @@ -508,9 +502,9 @@ impl MulAssign> for Lab } impl MulAssign for Lab - where - T: Component + Float + MulAssign, - Wp: WhitePoint, +where + T: FloatComponent + MulAssign, + Wp: WhitePoint, { fn mul_assign(&mut self, c: T) { self.l *= c; @@ -521,7 +515,7 @@ impl MulAssign for Lab impl Div> for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lab; @@ -538,7 +532,7 @@ where impl Div for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lab; @@ -554,9 +548,9 @@ where } impl DivAssign> for Lab - where - T: Component + Float + DivAssign, - Wp: WhitePoint, +where + T: FloatComponent + DivAssign, + Wp: WhitePoint, { fn div_assign(&mut self, other: Lab) { self.l /= other.l; @@ -566,9 +560,9 @@ impl DivAssign> for Lab } impl DivAssign for Lab - where - T: Component + Float + DivAssign, - Wp: WhitePoint, +where + T: FloatComponent + DivAssign, + Wp: WhitePoint, { fn div_assign(&mut self, c: T) { self.l /= c; @@ -579,7 +573,7 @@ impl DivAssign for Lab impl AsRef

for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, P: RawPixel + ?Sized, { @@ -590,7 +584,7 @@ where impl AsMut

for Lab where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, P: RawPixel + ?Sized, { @@ -628,7 +622,7 @@ mod test { #[test] fn ranges() { - assert_ranges!{ + assert_ranges! { Lab; limited { l: 0.0 => 100.0, diff --git a/palette/src/lch.rs b/palette/src/lch.rs index 13b06bf67..3cf705d94 100644 --- a/palette/src/lch.rs +++ b/palette/src/lch.rs @@ -1,13 +1,13 @@ -use float::Float; - use core::marker::PhantomData; use core::ops::{Add, AddAssign, Sub, SubAssign}; use encoding::pixel::RawPixel; -use white_point::{D65, WhitePoint}; -use {cast, clamp}; +use white_point::{WhitePoint, D65}; +use {clamp, from_f64}; use {Alpha, Hue, Lab, LabHue, Xyz}; -use {Component, FromColor, GetHue, IntoColor, Limited, Mix, Pixel, Saturate, Shade}; +use { + Component, FloatComponent, FromColor, GetHue, IntoColor, Limited, Mix, Pixel, Saturate, Shade, +}; /// CIE L\*C\*h° with an alpha component. See the [`Lcha` implementation in /// `Alpha`](struct.Alpha.html#Lcha). @@ -28,7 +28,7 @@ pub type Lcha = Alpha, T>; #[repr(C)] pub struct Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///L\* is the lightness of the color. 0.0 gives absolute black and 100.0 @@ -55,14 +55,14 @@ where impl Copy for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { } impl Clone for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn clone(&self) -> Lch { @@ -72,7 +72,7 @@ where impl Lch where - T: Component + Float, + T: FloatComponent, { ///CIE L\*C\*h° with white point D65. pub fn new>>(l: T, chroma: T, hue: H) -> Lch { @@ -87,7 +87,7 @@ where impl Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///CIE L\*C\*h°. @@ -114,7 +114,7 @@ where ///[`Lcha`](type.Lcha.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, { ///CIE L\*C\*h° and transparency with white point D65. @@ -129,7 +129,7 @@ where ///[`Lcha`](type.Lcha.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, Wp: WhitePoint, { @@ -154,7 +154,7 @@ where impl From> for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn from(color: Xyz) -> Self { @@ -165,7 +165,7 @@ where impl From> for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn from(color: Lab) -> Self { @@ -178,19 +178,19 @@ where } } -impl>> From<(T, T, H)> for Lch { +impl>> From<(T, T, H)> for Lch { fn from(components: (T, T, H)) -> Self { Self::from_components(components) } } -impl Into<(T, T, LabHue)> for Lch { +impl Into<(T, T, LabHue)> for Lch { fn into(self) -> (T, T, LabHue) { self.into_components() } } -impl>, A: Component> From<(T, T, H, A)> +impl>, A: Component> From<(T, T, H, A)> for Alpha, A> { fn from(components: (T, T, H, A)) -> Self { @@ -198,7 +198,7 @@ impl>, A: Component> Fro } } -impl Into<(T, T, LabHue, A)> +impl Into<(T, T, LabHue, A)> for Alpha, A> { fn into(self) -> (T, T, LabHue, A) { @@ -208,11 +208,11 @@ impl Into<(T, T, LabHue, impl Limited for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn is_valid(&self) -> bool { - self.l >= T::zero() && self.l <= cast(100.0) && self.chroma >= T::zero() + self.l >= T::zero() && self.l <= from_f64(100.0) && self.chroma >= T::zero() } fn clamp(&self) -> Lch { @@ -222,14 +222,14 @@ where } fn clamp_self(&mut self) { - self.l = clamp(self.l, T::zero(), cast(100.0)); + self.l = clamp(self.l, T::zero(), from_f64(100.0)); self.chroma = self.chroma.max(T::zero()) } } impl Mix for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -248,14 +248,14 @@ where impl Shade for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; fn lighten(&self, amount: T) -> Lch { Lch { - l: self.l + amount * cast(100.0), + l: self.l + amount * from_f64(100.0), chroma: self.chroma, hue: self.hue, white_point: PhantomData, @@ -265,7 +265,7 @@ where impl GetHue for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Hue = LabHue; @@ -281,7 +281,7 @@ where impl Hue for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn with_hue>(&self, hue: H) -> Lch { @@ -305,7 +305,7 @@ where impl Saturate for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -322,7 +322,7 @@ where impl Default for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn default() -> Lch { @@ -332,7 +332,7 @@ where impl Add> for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lch; @@ -349,7 +349,7 @@ where impl Add for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lch; @@ -366,7 +366,7 @@ where impl AddAssign> for Lch where - T: Component + Float + AddAssign, + T: FloatComponent + AddAssign, Wp: WhitePoint, { fn add_assign(&mut self, other: Lch) { @@ -377,9 +377,9 @@ where } impl AddAssign for Lch - where - T: Component + Float + AddAssign, - Wp: WhitePoint, +where + T: FloatComponent + AddAssign, + Wp: WhitePoint, { fn add_assign(&mut self, c: T) { self.l += c; @@ -390,7 +390,7 @@ impl AddAssign for Lch impl Sub> for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lch; @@ -407,7 +407,7 @@ where impl Sub for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Lch; @@ -424,7 +424,7 @@ where impl SubAssign> for Lch where - T: Component + Float + SubAssign, + T: FloatComponent + SubAssign, Wp: WhitePoint, { fn sub_assign(&mut self, other: Lch) { @@ -436,7 +436,7 @@ where impl SubAssign for Lch where - T: Component + Float + SubAssign, + T: FloatComponent + SubAssign, Wp: WhitePoint, { fn sub_assign(&mut self, c: T) { @@ -448,7 +448,7 @@ where impl AsRef

for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, P: RawPixel + ?Sized, { @@ -459,7 +459,7 @@ where impl AsMut

for Lch where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, P: RawPixel + ?Sized, { @@ -475,7 +475,7 @@ mod test { #[test] fn ranges() { - assert_ranges!{ + assert_ranges! { Lch; limited { l: 0.0 => 100.0 diff --git a/palette/src/lib.rs b/palette/src/lib.rs index d78d493db..1e93d7212 100644 --- a/palette/src/lib.rs +++ b/palette/src/lib.rs @@ -137,7 +137,6 @@ // Keep the standard library when running tests, too #![cfg_attr(all(not(feature = "std"), not(test)), no_std)] - #![doc(html_root_url = "https://docs.rs/palette/0.5.0/palette/")] #![cfg_attr(feature = "strict", deny(missing_docs))] #![cfg_attr(feature = "strict", deny(warnings))] @@ -162,7 +161,6 @@ extern crate serde; #[cfg(all(test, feature = "serializing"))] extern crate serde_json; -use num_traits::{NumCast, ToPrimitive, Zero}; use float::Float; use luma::Luma; @@ -185,7 +183,8 @@ pub use rgb::{GammaSrgb, GammaSrgba, LinSrgb, LinSrgba, Srgb, Srgba}; pub use xyz::{Xyz, Xyza}; pub use yxy::{Yxy, Yxya}; -pub use convert::{ConvertFrom, ConvertInto, OutOfBounds, FromColor, IntoColor}; +pub use component::*; +pub use convert::{ConvertFrom, ConvertInto, FromColor, IntoColor, OutOfBounds}; pub use encoding::pixel::Pixel; pub use hues::{LabHue, RgbHue}; pub use matrix::Mat3; @@ -341,7 +340,6 @@ macro_rules! assert_ranges { ); } - #[macro_use] mod macros; @@ -366,6 +364,7 @@ mod yxy; mod hues; pub mod chromatic_adaptation; +mod component; mod convert; pub mod encoding; mod equality; @@ -544,135 +543,28 @@ pub trait ComponentWise { fn component_wise_self Self::Scalar>(&self, f: F) -> Self; } -/// Common trait for color components. -pub trait Component: Copy + Zero + PartialOrd + NumCast { - /// True if the max intensity is also the highest possible value of the - /// type. Conversion to limited types requires clamping. - const LIMITED: bool; - - /// The highest displayable value this component type can reach. Higher - /// values are allowed, but they may be lowered to this before - /// converting to another format. - fn max_intensity() -> Self; - - /// Convert into another color component type, including scaling. - fn convert(&self) -> T; -} - -impl Component for f32 { - const LIMITED: bool = false; - - fn max_intensity() -> Self { - 1.0 - } - - fn convert(&self) -> T { - let scaled = *self * cast::(T::max_intensity()); - - if T::LIMITED { - cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity()))) - } else { - cast(scaled) - } - } -} - -impl Component for f64 { - const LIMITED: bool = false; - - fn max_intensity() -> Self { - 1.0 - } - - fn convert(&self) -> T { - let scaled = *self * cast::(T::max_intensity()); - - if T::LIMITED { - cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity()))) - } else { - cast(scaled) - } - } -} - -impl Component for u8 { - const LIMITED: bool = true; - - fn max_intensity() -> Self { - core::u8::MAX - } - - fn convert(&self) -> T { - let scaled = cast::(T::max_intensity()) - * (cast::(*self) / cast::(Self::max_intensity())); - - if T::LIMITED { - cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity()))) - } else { - cast(scaled) - } - } -} - -impl Component for u16 { - const LIMITED: bool = true; - - fn max_intensity() -> Self { - core::u16::MAX - } - - fn convert(&self) -> T { - let scaled = cast::(T::max_intensity()) - * (cast::(*self) / cast::(Self::max_intensity())); - - if T::LIMITED { - cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity()))) - } else { - cast(scaled) - } - } +/// A trait for infallible conversion from `f64`. The conversion may be lossy. +pub trait FromF64 { + /// Creates a value from an `f64` constant. + fn from_f64(c: f64) -> Self; } -impl Component for u32 { - const LIMITED: bool = true; - - fn max_intensity() -> Self { - core::u32::MAX - } - - fn convert(&self) -> T { - let scaled = cast::(T::max_intensity()) - * (cast::(*self) / cast::(Self::max_intensity())); - - if T::LIMITED { - cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity()))) - } else { - cast(scaled) - } +impl FromF64 for f32 { + #[inline] + fn from_f64(c: f64) -> Self { + c as f32 } } -impl Component for u64 { - const LIMITED: bool = true; - - fn max_intensity() -> Self { - core::u64::MAX - } - - fn convert(&self) -> T { - let scaled = cast::(T::max_intensity()) - * (cast::(*self) / cast::(Self::max_intensity())); - - if T::LIMITED { - cast(clamp(Float::round(scaled), 0.0, cast(T::max_intensity()))) - } else { - cast(scaled) - } +impl FromF64 for f64 { + #[inline] + fn from_f64(c: f64) -> Self { + c } } /// A convenience function to convert a constant number to Float Type #[inline] -fn cast(prim: P) -> T { - NumCast::from(prim).unwrap() +fn from_f64(c: f64) -> T { + T::from_f64(c) } diff --git a/palette/src/luma/luma.rs b/palette/src/luma/luma.rs index b8e9bae12..35dc64075 100644 --- a/palette/src/luma/luma.rs +++ b/palette/src/luma/luma.rs @@ -4,8 +4,6 @@ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use float::Float; - use blend::PreAlpha; use clamp; use encoding::linear::LinearFn; @@ -14,7 +12,10 @@ use encoding::{Linear, Srgb, TransferFn}; use luma::LumaStandard; use white_point::WhitePoint; use {Alpha, Xyz, Yxy}; -use {Blend, Component, ComponentWise, FromColor, IntoColor, Limited, Mix, Pixel, Shade}; +use { + Blend, Component, ComponentWise, FloatComponent, FromColor, FromComponent, IntoColor, Limited, + Mix, Pixel, Shade, +}; /// Luminance with an alpha component. See the [`Lumaa` implementation /// in `Alpha`](struct.Alpha.html#Lumaa). @@ -79,15 +80,22 @@ where } /// Convert into another component type. - pub fn into_format(self) -> Luma { + pub fn into_format(self) -> Luma + where + U: Component + FromComponent, + { Luma { - luma: self.luma.convert(), + luma: U::from_component(self.luma), standard: PhantomData, } } /// Convert from another component type. - pub fn from_format(color: Luma) -> Self { + pub fn from_format(color: Luma) -> Self + where + U: Component, + T: FromComponent, + { color.into_format() } @@ -104,7 +112,7 @@ where impl Luma where - T: Component + Float, + T: FloatComponent, S: LumaStandard, { /// Convert the color to linear luminance. @@ -150,12 +158,22 @@ where } /// Convert into another component type. - pub fn into_format(self) -> Alpha, B> { - Alpha::, B>::new(self.luma.convert(), self.alpha.convert()) + pub fn into_format(self) -> Alpha, B> + where + U: Component + FromComponent, + B: Component + FromComponent, + { + Alpha::, B>::new(U::from_component(self.luma), B::from_component(self.alpha)) } /// Convert from another component type. - pub fn from_format(color: Alpha, B>) -> Self { + pub fn from_format(color: Alpha, B>) -> Self + where + T: FromComponent, + U: Component, + A: FromComponent, + B: Component, + { color.into_format() } @@ -173,7 +191,7 @@ where ///[`Lumaa`](type.Lumaa.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, S: LumaStandard, { @@ -214,7 +232,7 @@ where impl From> for Luma where S: LumaStandard, - T: Component + Float, + T: FloatComponent, { fn from(color: Xyz) -> Self { Self::from_linear(Luma { @@ -227,7 +245,7 @@ where impl From> for Luma where S: LumaStandard, - T: Component + Float, + T: FloatComponent, { fn from(color: Yxy) -> Self { Self::from_linear(Luma { @@ -264,7 +282,7 @@ impl Into<(T, A)> for Alpha IntoColor for Luma where S: LumaStandard, - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn into_xyz(self) -> Xyz { @@ -302,7 +320,7 @@ where impl Mix for Luma where - T: Component + Float, + T: FloatComponent, S: LumaStandard, { type Scalar = T; @@ -319,7 +337,7 @@ where impl Shade for Luma where - T: Component + Float, + T: FloatComponent, S: LumaStandard, { type Scalar = T; @@ -334,7 +352,7 @@ where impl Blend for Luma where - T: Component + Float, + T: FloatComponent, S: LumaStandard, { type Color = Luma; @@ -714,7 +732,7 @@ mod test { #[test] fn ranges() { - assert_ranges!{ + assert_ranges! { Luma; limited { luma: 0.0 => 1.0 diff --git a/palette/src/matrix.rs b/palette/src/matrix.rs index b6ac8da97..8bdddde0e 100644 --- a/palette/src/matrix.rs +++ b/palette/src/matrix.rs @@ -5,17 +5,17 @@ use float::Float; use core::marker::PhantomData; -use {Component, Xyz}; -use white_point::WhitePoint; -use rgb::{Primaries, Rgb, RgbSpace}; -use encoding::Linear; use convert::IntoColor; +use encoding::Linear; +use rgb::{Primaries, Rgb, RgbSpace}; +use white_point::WhitePoint; +use {FloatComponent, Xyz}; ///A 9 element array representing a 3x3 matrix pub type Mat3 = [T; 9]; ///Multiply the 3x3 matrix with the XYZ color -pub fn multiply_xyz( +pub fn multiply_xyz( c: &Mat3, f: &Xyz, ) -> Xyz { @@ -27,7 +27,7 @@ pub fn multiply_xyz( } } ///Multiply the 3x3 matrix with the XYZ color into RGB color -pub fn multiply_xyz_to_rgb( +pub fn multiply_xyz_to_rgb( c: &Mat3, f: &Xyz, ) -> Rgb, T> { @@ -39,7 +39,7 @@ pub fn multiply_xyz_to_rgb( } } ///Multiply the 3x3 matrix with the RGB into XYZ color -pub fn multiply_rgb_to_xyz( +pub fn multiply_rgb_to_xyz( c: &Mat3, f: &Rgb, T>, ) -> Xyz { @@ -99,7 +99,7 @@ pub fn matrix_inverse(a: &Mat3) -> Mat3 { } ///Geneartes to Srgb to Xyz transformation matrix for the given white point -pub fn rgb_to_xyz_matrix() -> Mat3 { +pub fn rgb_to_xyz_matrix() -> Mat3 { let r: Xyz = S::Primaries::red().into_xyz(); let g: Xyz = S::Primaries::green().into_xyz(); let b: Xyz = S::Primaries::blue().into_xyz(); @@ -124,7 +124,7 @@ pub fn rgb_to_xyz_matrix() -> Mat3 { } #[cfg_attr(rustfmt, rustfmt_skip)] -fn mat3_from_primaries(r: Xyz, g: Xyz, b: Xyz) -> Mat3 { +fn mat3_from_primaries(r: Xyz, g: Xyz, b: Xyz) -> Mat3 { [ r.x, g.x, b.x, r.y, g.y, b.y, @@ -134,12 +134,12 @@ fn mat3_from_primaries(r: Xyz, g: X #[cfg(test)] mod test { - use Xyz; - use rgb::Rgb; - use encoding::{Linear, Srgb}; + use super::{matrix_inverse, multiply_3x3, multiply_xyz, rgb_to_xyz_matrix}; use chromatic_adaptation::AdaptInto; + use encoding::{Linear, Srgb}; + use rgb::Rgb; use white_point::D50; - use super::{matrix_inverse, multiply_xyz, rgb_to_xyz_matrix, multiply_3x3}; + use Xyz; #[test] fn matrix_multiply_3x3() { diff --git a/palette/src/rgb/mod.rs b/palette/src/rgb/mod.rs index 9deb3d683..c09691b9b 100644 --- a/palette/src/rgb/mod.rs +++ b/palette/src/rgb/mod.rs @@ -1,10 +1,9 @@ //!RGB types, spaces and standards. -use float::Float; use core::any::Any; -use {Component, Yxy}; use white_point::WhitePoint; +use {Component, FloatComponent, FromComponent, Yxy}; use encoding::{Linear, TransferFn}; @@ -64,17 +63,17 @@ impl RgbSpace for (P, W) { ///Represents the red, green and blue primaries of an RGB space. pub trait Primaries: Any { ///Primary red. - fn red() -> Yxy; + fn red() -> Yxy; ///Primary green. - fn green() -> Yxy; + fn green() -> Yxy; ///Primary blue. - fn blue() -> Yxy; + fn blue() -> Yxy; } impl From> for Srgb where - T: Component + Float, - U: Component, + T: FloatComponent, + U: Component + FromComponent, { fn from(lin_srgb: LinSrgb) -> Self { let non_lin = Srgb::::from_linear(lin_srgb); @@ -84,19 +83,18 @@ where impl From> for LinSrgb where - T: Component + Float, - U: Component, + T: FloatComponent, + U: Component + FromComponent, { fn from(srgb: Srgb) -> Self { - srgb.into_linear() - .into_format() + srgb.into_linear().into_format() } } impl From> for Srgba where - T: Component + Float, - U: Component, + T: FloatComponent, + U: Component + FromComponent, { fn from(lin_srgb: LinSrgb) -> Self { let non_lin = Srgb::::from_linear(lin_srgb); @@ -107,8 +105,8 @@ where impl From> for Srgba where - T: Component + Float, - U: Component, + T: FloatComponent, + U: Component + FromComponent, { fn from(lin_srgba: LinSrgba) -> Self { let non_lin = Srgba::::from_linear(lin_srgba); @@ -118,23 +116,20 @@ where impl From> for LinSrgba where - T: Component + Float, - U: Component, + T: FloatComponent, + U: Component + FromComponent, { fn from(srgb: Srgb) -> Self { - srgb.into_linear() - .into_format() - .into() + srgb.into_linear().into_format().into() } } impl From> for LinSrgba where - T: Component + Float, - U: Component, + T: FloatComponent, + U: Component + FromComponent, { fn from(srgba: Srgba) -> Self { - srgba.into_linear() - .into_format() + srgba.into_linear().into_format() } } diff --git a/palette/src/rgb/rgb.rs b/palette/src/rgb/rgb.rs index ba2273b3f..4f79323a4 100644 --- a/palette/src/rgb/rgb.rs +++ b/palette/src/rgb/rgb.rs @@ -1,12 +1,11 @@ use core::any::TypeId; use core::fmt; use core::marker::PhantomData; +use core::num::ParseIntError; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; use core::str::FromStr; -use core::num::ParseIntError; use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -use float::Float; use alpha::Alpha; use blend::PreAlpha; @@ -18,8 +17,11 @@ use luma::LumaStandard; use matrix::{matrix_inverse, multiply_xyz_to_rgb, rgb_to_xyz_matrix}; use rgb::{RgbSpace, RgbStandard, TransferFn}; use white_point::WhitePoint; -use {cast, clamp}; -use {Blend, Component, ComponentWise, GetHue, Limited, Mix, Pixel, Shade}; +use {clamp, from_f64}; +use { + Blend, Component, ComponentWise, FloatComponent, FromComponent, GetHue, Limited, Mix, Pixel, + Shade, +}; use {Hsl, Hsv, Hwb, Lab, Lch, Luma, RgbHue, Xyz, Yxy}; /// Generic RGB with an alpha component. See the [`Rgba` implementation in @@ -84,17 +86,24 @@ impl Rgb { } /// Convert into another component type. - pub fn into_format(self) -> Rgb { + pub fn into_format(self) -> Rgb + where + U: Component + FromComponent, + { Rgb { - red: self.red.convert(), - green: self.green.convert(), - blue: self.blue.convert(), + red: U::from_component(self.red), + green: U::from_component(self.green), + blue: U::from_component(self.blue), standard: PhantomData, } } /// Convert from another component type. - pub fn from_format(color: Rgb) -> Self { + pub fn from_format(color: Rgb) -> Self + where + T: FromComponent, + U: Component, + { color.into_format() } @@ -109,7 +118,7 @@ impl Rgb { } } -impl Rgb { +impl Rgb { /// Convert the color to linear RGB. pub fn into_linear(self) -> Rgb, T> { Rgb::new( @@ -184,17 +193,27 @@ impl Alpha, A> { } /// Convert into another component type. - pub fn into_format(self) -> Alpha, B> { + pub fn into_format(self) -> Alpha, B> + where + U: Component + FromComponent, + B: Component + FromComponent, + { Alpha::, B>::new( - self.red.convert(), - self.green.convert(), - self.blue.convert(), - self.alpha.convert(), + U::from_component(self.red), + U::from_component(self.green), + U::from_component(self.blue), + B::from_component(self.alpha), ) } /// Convert from another component type. - pub fn from_format(color: Alpha, B>) -> Self { + pub fn from_format(color: Alpha, B>) -> Self + where + T: FromComponent, + U: Component, + A: FromComponent, + B: Component, + { color.into_format() } @@ -210,7 +229,7 @@ impl Alpha, A> { } /// [`Rgba`](rgb/type.Rgba.html) implementations. -impl Alpha, A> { +impl Alpha, A> { /// Convert the color to linear RGB with transparency. pub fn into_linear(self) -> Alpha, T>, A> { Alpha::, T>, A>::new( @@ -280,7 +299,7 @@ where impl Mix for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, { type Scalar = T; @@ -299,7 +318,7 @@ where impl Shade for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, { type Scalar = T; @@ -316,19 +335,19 @@ where impl GetHue for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, { type Hue = RgbHue; fn get_hue(&self) -> Option> { - let sqrt_3: T = cast(1.73205081); + let sqrt_3: T = from_f64(1.73205081); if self.red == self.green && self.red == self.blue { None } else { Some(RgbHue::from_radians( (sqrt_3 * (self.green - self.blue)) - .atan2(self.red * cast(2.0) - self.green - self.blue), + .atan2(self.red * from_f64(2.0) - self.green - self.blue), )) } } @@ -337,7 +356,7 @@ where impl Blend for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, { type Color = Rgb; @@ -629,7 +648,7 @@ where impl From> for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, S::Space: RgbSpace, { @@ -642,7 +661,7 @@ where impl From> for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, S::Space: RgbSpace, Sp: RgbSpace, @@ -650,20 +669,20 @@ where fn from(color: Hsl) -> Self { let hsl = Hsl::::from_hsl(color); - let c = (T::one() - (hsl.lightness * cast(2.0) - T::one()).abs()) * hsl.saturation; - let h = hsl.hue.to_positive_degrees() / cast(60.0); - let x = c * (T::one() - (h % cast(2.0) - T::one()).abs()); - let m = hsl.lightness - c * cast(0.5); + let c = (T::one() - (hsl.lightness * from_f64(2.0) - T::one()).abs()) * hsl.saturation; + let h = hsl.hue.to_positive_degrees() / from_f64(60.0); + let x = c * (T::one() - (h % from_f64(2.0) - T::one()).abs()); + let m = hsl.lightness - c * from_f64(0.5); let (red, green, blue) = if h >= T::zero() && h < T::one() { (c, x, T::zero()) - } else if h >= T::one() && h < cast(2.0) { + } else if h >= T::one() && h < from_f64(2.0) { (x, c, T::zero()) - } else if h >= cast(2.0) && h < cast(3.0) { + } else if h >= from_f64(2.0) && h < from_f64(3.0) { (T::zero(), c, x) - } else if h >= cast(3.0) && h < cast(4.0) { + } else if h >= from_f64(3.0) && h < from_f64(4.0) { (T::zero(), x, c) - } else if h >= cast(4.0) && h < cast(5.0) { + } else if h >= from_f64(4.0) && h < from_f64(5.0) { (x, T::zero(), c) } else { (c, T::zero(), x) @@ -681,7 +700,7 @@ where impl From> for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, S::Space: RgbSpace, Sp: RgbSpace, @@ -690,19 +709,19 @@ where let hsv = Hsv::::from_hsv(color); let c = hsv.value * hsv.saturation; - let h = hsv.hue.to_positive_degrees() / cast(60.0); - let x = c * (T::one() - (h % cast(2.0) - T::one()).abs()); + let h = hsv.hue.to_positive_degrees() / from_f64(60.0); + let x = c * (T::one() - (h % from_f64(2.0) - T::one()).abs()); let m = hsv.value - c; let (red, green, blue) = if h >= T::zero() && h < T::one() { (c, x, T::zero()) - } else if h >= T::one() && h < cast(2.0) { + } else if h >= T::one() && h < from_f64(2.0) { (x, c, T::zero()) - } else if h >= cast(2.0) && h < cast(3.0) { + } else if h >= from_f64(2.0) && h < from_f64(3.0) { (T::zero(), c, x) - } else if h >= cast(3.0) && h < cast(4.0) { + } else if h >= from_f64(3.0) && h < from_f64(4.0) { (T::zero(), x, c) - } else if h >= cast(4.0) && h < cast(5.0) { + } else if h >= from_f64(4.0) && h < from_f64(5.0) { (x, T::zero(), c) } else { (c, T::zero(), x) @@ -720,7 +739,7 @@ where impl From> for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, S::Space: RgbSpace, St: LumaStandard, @@ -764,7 +783,7 @@ impl Into<(T, T, T, A)> for Alpha IntoColor for Rgb where S: RgbStandard, - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, S::Space: RgbSpace, { @@ -827,9 +846,9 @@ where } fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { - self.red.abs_diff_eq(&other.red, epsilon) && - self.green.abs_diff_eq(&other.green, epsilon) && - self.blue.abs_diff_eq(&other.blue, epsilon) + self.red.abs_diff_eq(&other.red, epsilon) + && self.green.abs_diff_eq(&other.green, epsilon) + && self.blue.abs_diff_eq(&other.blue, epsilon) } } @@ -958,7 +977,7 @@ where #[derive(Debug)] pub enum FromHexError { ParseIntError(ParseIntError), - HexFormatError(&'static str) + HexFormatError(&'static str), } impl From for FromHexError { @@ -975,18 +994,17 @@ impl From<&'static str> for FromHexError { impl core::fmt::Display for FromHexError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &*self { - FromHexError::ParseIntError(e) => { - write!(f, "{}", e) - } - FromHexError::HexFormatError(s) => { - write!(f, "{}, please use format '#fff', 'fff', '#ffffff' or\ - 'ffffff'.", s) - } + FromHexError::ParseIntError(e) => write!(f, "{}", e), + FromHexError::HexFormatError(s) => write!( + f, + "{}, please use format '#fff', 'fff', '#ffffff' or 'ffffff'.", + s + ), } } } -#[cfg(feature="std")] +#[cfg(feature = "std")] impl std::error::Error for FromHexError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match &*self { @@ -996,28 +1014,19 @@ impl std::error::Error for FromHexError { } } - impl FromStr for Rgb { type Err = FromHexError; // Parses a color hex code of format '#ff00bb' or '#abc' into a // Rgb instance. fn from_str(hex: &str) -> Result { - let hex_code = if hex.starts_with('#') { - &hex[1..] - } else { - hex - }; + let hex_code = if hex.starts_with('#') { &hex[1..] } else { hex }; match hex_code.len() { 3 => { let red = u8::from_str_radix(&hex_code[..1], 16)?; let green = u8::from_str_radix(&hex_code[1..2], 16)?; let blue = u8::from_str_radix(&hex_code[2..3], 16)?; - let col: Rgb = Rgb::new( - red * 17, - green * 17, - blue * 17, - ); + let col: Rgb = Rgb::new(red * 17, green * 17, blue * 17); Ok(col) } 6 => { @@ -1035,8 +1044,8 @@ impl FromStr for Rgb { #[cfg(test)] mod test { use super::Rgb; - use encoding::Srgb; use core::str::FromStr; + use encoding::Srgb; #[test] fn ranges() { @@ -1166,44 +1175,44 @@ mod test { fn from_str() { let c = Rgb::::from_str("#ffffff"); assert!(c.is_ok()); - assert_eq!(c.unwrap(), Rgb::::new(255,255,255)); + assert_eq!(c.unwrap(), Rgb::::new(255, 255, 255)); let c = Rgb::::from_str("#gggggg"); assert!(c.is_err()); - let c = Rgb::::from_str("#fff"); + let c = Rgb::::from_str("#fff"); assert!(c.is_ok()); - assert_eq!(c.unwrap(),Rgb::::new(255,255,255)); - let c = Rgb::::from_str("#000000"); + assert_eq!(c.unwrap(), Rgb::::new(255, 255, 255)); + let c = Rgb::::from_str("#000000"); assert!(c.is_ok()); - assert_eq!(c.unwrap(), Rgb::::new(0,0,0)); - let c = Rgb::::from_str(""); + assert_eq!(c.unwrap(), Rgb::::new(0, 0, 0)); + let c = Rgb::::from_str(""); assert!(c.is_err()); - let c = Rgb::::from_str("#123456"); + let c = Rgb::::from_str("#123456"); assert!(c.is_ok()); - assert_eq!(c.unwrap(), Rgb::::new(18, 52, 86)); - let c = Rgb::::from_str("#iii"); + assert_eq!(c.unwrap(), Rgb::::new(18, 52, 86)); + let c = Rgb::::from_str("#iii"); assert!(c.is_err()); assert_eq!( format!("{}", c.err().unwrap()), "invalid digit found in string" ); - let c = Rgb::::from_str("#08f"); - assert_eq!(c.unwrap(), Rgb::::new(0, 136, 255)); - let c = Rgb::::from_str("08f"); - assert_eq!(c.unwrap(), Rgb::::new(0, 136,255)); - let c = Rgb::::from_str("ffffff"); - assert_eq!(c.unwrap(), Rgb::::new(255,255,255)); - let c = Rgb::::from_str("#12"); + let c = Rgb::::from_str("#08f"); + assert_eq!(c.unwrap(), Rgb::::new(0, 136, 255)); + let c = Rgb::::from_str("08f"); + assert_eq!(c.unwrap(), Rgb::::new(0, 136, 255)); + let c = Rgb::::from_str("ffffff"); + assert_eq!(c.unwrap(), Rgb::::new(255, 255, 255)); + let c = Rgb::::from_str("#12"); assert!(c.is_err()); assert_eq!( - format!("{}", c.err().unwrap()), + format!("{}", c.err().unwrap()), "invalid hex code format, \ - please use format \'#fff\', \'fff\', \'#ffffff\' or\'ffffff\'." + please use format \'#fff\', \'fff\', \'#ffffff\' or \'ffffff\'." ); - let c = Rgb::::from_str("da0bce"); - assert_eq!(c.unwrap(), Rgb::::new(218,11,206)); - let c = Rgb::::from_str("f034e6"); - assert_eq!(c.unwrap(), Rgb::::new(240,52,230)); - let c = Rgb::::from_str("abc"); - assert_eq!(c.unwrap(), Rgb::::new(170,187,204)); + let c = Rgb::::from_str("da0bce"); + assert_eq!(c.unwrap(), Rgb::::new(218, 11, 206)); + let c = Rgb::::from_str("f034e6"); + assert_eq!(c.unwrap(), Rgb::::new(240, 52, 230)); + let c = Rgb::::from_str("abc"); + assert_eq!(c.unwrap(), Rgb::::new(170, 187, 204)); } } diff --git a/palette/src/white_point.rs b/palette/src/white_point.rs index ff0c412c7..91408fd9d 100644 --- a/palette/src/white_point.rs +++ b/palette/src/white_point.rs @@ -6,9 +6,7 @@ //! unacceptable results when attempting to color-correct a photograph taken with incandescent //! lighting. -use float::Float; - -use {cast, Component, Xyz}; +use {from_f64, FloatComponent, Xyz}; ///WhitePoint defines the Xyz color co-ordinates for a given white point. /// @@ -20,7 +18,7 @@ use {cast, Component, Xyz}; ///and can be used in place of the ones defined in this library. pub trait WhitePoint { ///Get the Xyz chromacity co-ordinates for the white point. - fn get_xyz() -> Xyz; + fn get_xyz() -> Xyz; } /// CIE standard illuminant A @@ -31,8 +29,8 @@ pub trait WhitePoint { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct A; impl WhitePoint for A { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(1.09850), T::one(), cast(0.35585)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(1.09850), T::one(), from_f64(0.35585)) } } /// CIE standard illuminant B @@ -42,8 +40,8 @@ impl WhitePoint for A { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct B; impl WhitePoint for B { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.99072), T::one(), cast(0.85223)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.99072), T::one(), from_f64(0.85223)) } } ///CIE standard illuminant C @@ -53,8 +51,8 @@ impl WhitePoint for B { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct C; impl WhitePoint for C { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.98074), T::one(), cast(1.18232)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.98074), T::one(), from_f64(1.18232)) } } ///CIE D series standard illuminant - D50 @@ -64,8 +62,8 @@ impl WhitePoint for C { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct D50; impl WhitePoint for D50 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.96422), T::one(), cast(0.82521)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.96422), T::one(), from_f64(0.82521)) } } ///CIE D series standard illuminant - D55 @@ -75,8 +73,8 @@ impl WhitePoint for D50 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct D55; impl WhitePoint for D55 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.95682), T::one(), cast(0.92149)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.95682), T::one(), from_f64(0.92149)) } } ///CIE D series standard illuminant - D65 @@ -86,8 +84,8 @@ impl WhitePoint for D55 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct D65; impl WhitePoint for D65 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.95047), T::one(), cast(1.08883)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.95047), T::one(), from_f64(1.08883)) } } ///CIE D series standard illuminant - D75 @@ -97,8 +95,8 @@ impl WhitePoint for D65 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct D75; impl WhitePoint for D75 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.94972), T::one(), cast(1.22638)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.94972), T::one(), from_f64(1.22638)) } } ///CIE standard illuminant E @@ -108,7 +106,7 @@ impl WhitePoint for D75 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct E; impl WhitePoint for E { - fn get_xyz() -> Xyz { + fn get_xyz() -> Xyz { Xyz::with_wp(T::one(), T::one(), T::one()) } } @@ -118,8 +116,8 @@ impl WhitePoint for E { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct F2; impl WhitePoint for F2 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.99186), T::one(), cast(0.67393)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.99186), T::one(), from_f64(0.67393)) } } ///CIE fluorescent illuminant series - F7 @@ -128,8 +126,8 @@ impl WhitePoint for F2 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct F7; impl WhitePoint for F7 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.95041), T::one(), cast(1.08747)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.95041), T::one(), from_f64(1.08747)) } } ///CIE fluorescent illuminant series - F11 @@ -138,8 +136,8 @@ impl WhitePoint for F7 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct F11; impl WhitePoint for F11 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(1.00962), T::one(), cast(0.64350)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(1.00962), T::one(), from_f64(0.64350)) } } ///CIE D series standard illuminant - D50 @@ -149,8 +147,8 @@ impl WhitePoint for F11 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct D50Degree10; impl WhitePoint for D50Degree10 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.9672), T::one(), cast(0.8143)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.9672), T::one(), from_f64(0.8143)) } } ///CIE D series standard illuminant - D55 @@ -160,8 +158,8 @@ impl WhitePoint for D50Degree10 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct D55Degree10; impl WhitePoint for D55Degree10 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.958), T::one(), cast(0.9093)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.958), T::one(), from_f64(0.9093)) } } ///CIE D series standard illuminant - D65 @@ -171,8 +169,8 @@ impl WhitePoint for D55Degree10 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct D65Degree10; impl WhitePoint for D65Degree10 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.9481), T::one(), cast(1.073)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.9481), T::one(), from_f64(1.073)) } } ///CIE D series standard illuminant - D75 @@ -182,7 +180,7 @@ impl WhitePoint for D65Degree10 { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct D75Degree10; impl WhitePoint for D75Degree10 { - fn get_xyz() -> Xyz { - Xyz::with_wp(cast(0.94416), T::one(), cast(1.2064)) + fn get_xyz() -> Xyz { + Xyz::with_wp(from_f64(0.94416), T::one(), from_f64(1.2064)) } } diff --git a/palette/src/xyz.rs b/palette/src/xyz.rs index 46da956fa..670d8bc0c 100644 --- a/palette/src/xyz.rs +++ b/palette/src/xyz.rs @@ -1,5 +1,3 @@ -use float::Float; - use core::marker::PhantomData; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; @@ -7,10 +5,10 @@ use encoding::pixel::RawPixel; use luma::LumaStandard; use matrix::{multiply_rgb_to_xyz, rgb_to_xyz_matrix}; use rgb::{Rgb, RgbSpace, RgbStandard}; -use white_point::{D65, WhitePoint}; -use {cast, clamp}; +use white_point::{WhitePoint, D65}; +use {clamp, from_f64}; use {Alpha, Lab, Luma, Yxy}; -use {Component, ComponentWise, Limited, Mix, Pixel, Shade}; +use {Component, ComponentWise, FloatComponent, Limited, Mix, Pixel, Shade}; /// CIE 1931 XYZ with an alpha component. See the [`Xyza` implementation in /// `Alpha`](struct.Alpha.html#Xyza). @@ -34,7 +32,7 @@ pub type Xyza = Alpha, T>; #[repr(C)] pub struct Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///X is the scale of what can be seen as a response curve for the cone @@ -59,14 +57,14 @@ where impl Copy for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { } impl Clone for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn clone(&self) -> Xyz { @@ -76,7 +74,7 @@ where impl Xyz where - T: Component + Float, + T: FloatComponent, { ///CIE XYZ with whtie point D65. pub fn new(x: T, y: T, z: T) -> Xyz { @@ -91,7 +89,7 @@ where impl Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///CIE XYZ. @@ -118,7 +116,7 @@ where ///[`Xyza`](type.Xyza.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, { ///CIE Yxy and transparency with white point D65. @@ -133,7 +131,7 @@ where ///[`Xyza`](type.Xyza.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, Wp: WhitePoint, { @@ -158,7 +156,7 @@ where impl From> for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, S: RgbStandard, S::Space: RgbSpace, @@ -171,7 +169,7 @@ where impl From> for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn from(color: Yxy) -> Self { @@ -190,18 +188,18 @@ where impl From> for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn from(color: Lab) -> Self { - let y = (color.l + cast(16.0)) / cast(116.0); - let x = y + (color.a / cast(500.0)); - let z = y - (color.b / cast(200.0)); + let y = (color.l + from_f64(16.0)) / from_f64(116.0); + let x = y + (color.a / from_f64(500.0)); + let z = y - (color.b / from_f64(200.0)); - fn convert(c: T) -> T { - let epsilon: T = cast(6.0 / 29.0); - let kappa: T = cast(108.0 / 841.0); - let delta: T = cast(4.0 / 29.0); + fn convert(c: T) -> T { + let epsilon: T = from_f64(6.0 / 29.0); + let kappa: T = from_f64(108.0 / 841.0); + let delta: T = from_f64(4.0 / 29.0); if c > epsilon { c.powi(3) @@ -216,7 +214,7 @@ where impl From> for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, S: LumaStandard, { @@ -225,29 +223,25 @@ where } } -impl From<(T, T, T)> for Xyz { +impl From<(T, T, T)> for Xyz { fn from(components: (T, T, T)) -> Self { Self::from_components(components) } } -impl Into<(T, T, T)> for Xyz { +impl Into<(T, T, T)> for Xyz { fn into(self) -> (T, T, T) { self.into_components() } } -impl From<(T, T, T, A)> - for Alpha, A> -{ +impl From<(T, T, T, A)> for Alpha, A> { fn from(components: (T, T, T, A)) -> Self { Self::from_components(components) } } -impl Into<(T, T, T, A)> - for Alpha, A> -{ +impl Into<(T, T, T, A)> for Alpha, A> { fn into(self) -> (T, T, T, A) { self.into_components() } @@ -255,7 +249,7 @@ impl Into<(T, T, T, A)> impl Limited for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { #[cfg_attr(rustfmt, rustfmt_skip)] @@ -282,7 +276,7 @@ where impl Mix for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -301,7 +295,7 @@ where impl Shade for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -318,7 +312,7 @@ where impl ComponentWise for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -344,7 +338,7 @@ where impl Default for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn default() -> Xyz { @@ -354,7 +348,7 @@ where impl Add> for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Xyz; @@ -371,7 +365,7 @@ where impl Add for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Xyz; @@ -388,7 +382,7 @@ where impl AddAssign> for Xyz where - T: Component + Float + AddAssign, + T: FloatComponent + AddAssign, Wp: WhitePoint, { fn add_assign(&mut self, other: Xyz) { @@ -400,7 +394,7 @@ where impl AddAssign for Xyz where - T: Component + Float + AddAssign, + T: FloatComponent + AddAssign, Wp: WhitePoint, { fn add_assign(&mut self, c: T) { @@ -412,7 +406,7 @@ where impl Sub> for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Xyz; @@ -429,7 +423,7 @@ where impl Sub for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Xyz; @@ -446,7 +440,7 @@ where impl SubAssign> for Xyz where - T: Component + Float + SubAssign, + T: FloatComponent + SubAssign, Wp: WhitePoint, { fn sub_assign(&mut self, other: Xyz) { @@ -458,7 +452,7 @@ where impl SubAssign for Xyz where - T: Component + Float + SubAssign, + T: FloatComponent + SubAssign, Wp: WhitePoint, { fn sub_assign(&mut self, c: T) { @@ -470,7 +464,7 @@ where impl Mul> for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Xyz; @@ -487,7 +481,7 @@ where impl Mul for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Xyz; @@ -504,7 +498,7 @@ where impl MulAssign> for Xyz where - T: Component + Float + MulAssign, + T: FloatComponent + MulAssign, Wp: WhitePoint, { fn mul_assign(&mut self, other: Xyz) { @@ -516,7 +510,7 @@ where impl MulAssign for Xyz where - T: Component + Float + MulAssign, + T: FloatComponent + MulAssign, Wp: WhitePoint, { fn mul_assign(&mut self, c: T) { @@ -528,7 +522,7 @@ where impl Div> for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Xyz; @@ -545,7 +539,7 @@ where impl Div for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Xyz; @@ -562,7 +556,7 @@ where impl DivAssign> for Xyz where - T: Component + Float + DivAssign, + T: FloatComponent + DivAssign, Wp: WhitePoint, { fn div_assign(&mut self, other: Xyz) { @@ -574,7 +568,7 @@ where impl DivAssign for Xyz where - T: Component + Float + DivAssign, + T: FloatComponent + DivAssign, Wp: WhitePoint, { fn div_assign(&mut self, c: T) { @@ -586,7 +580,7 @@ where impl AsRef

for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, P: RawPixel + ?Sized, { @@ -597,7 +591,7 @@ where impl AsMut

for Xyz where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, P: RawPixel + ?Sized, { @@ -646,7 +640,7 @@ mod test { #[test] fn ranges() { - assert_ranges!{ + assert_ranges! { Xyz; limited { x: 0.0 => X_N, diff --git a/palette/src/yxy.rs b/palette/src/yxy.rs index 005920e90..b414660d8 100644 --- a/palette/src/yxy.rs +++ b/palette/src/yxy.rs @@ -1,14 +1,12 @@ -use float::Float; - use core::marker::PhantomData; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; use clamp; use encoding::pixel::RawPixel; use luma::LumaStandard; -use white_point::{D65, WhitePoint}; +use white_point::{WhitePoint, D65}; use {Alpha, Luma, Xyz}; -use {Component, ComponentWise, IntoColor, Limited, Mix, Pixel, Shade}; +use {Component, ComponentWise, FloatComponent, IntoColor, Limited, Mix, Pixel, Shade}; /// CIE 1931 Yxy (xyY) with an alpha component. See the [`Yxya` implementation /// in `Alpha`](struct.Alpha.html#Yxya). @@ -30,7 +28,7 @@ pub type Yxya = Alpha, T>; #[repr(C)] pub struct Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///x chromacity co-ordinate derived from XYZ color space as X/(X+Y+Z). @@ -55,14 +53,14 @@ where impl Copy for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { } impl Clone for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn clone(&self) -> Yxy { @@ -72,7 +70,7 @@ where impl Yxy where - T: Component + Float, + T: FloatComponent, { ///CIE Yxy with white point D65. pub fn new(x: T, y: T, luma: T) -> Yxy { @@ -87,7 +85,7 @@ where impl Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { ///CIE Yxy. @@ -114,7 +112,7 @@ where ///[`Yxya`](type.Yxya.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, { ///CIE Yxy and transparency with white point D65. @@ -128,7 +126,7 @@ where ///[`Yxya`](type.Yxya.html) implementations. impl Alpha, A> where - T: Component + Float, + T: FloatComponent, A: Component, Wp: WhitePoint, { @@ -153,7 +151,7 @@ where impl From> for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn from(xyz: Xyz) -> Self { @@ -175,7 +173,7 @@ where impl From> for Yxy where - T: Component + Float, + T: FloatComponent, S: LumaStandard, { fn from(luma: Luma) -> Self { @@ -186,29 +184,25 @@ where } } -impl From<(T, T, T)> for Yxy { +impl From<(T, T, T)> for Yxy { fn from(components: (T, T, T)) -> Self { Self::from_components(components) } } -impl Into<(T, T, T)> for Yxy { +impl Into<(T, T, T)> for Yxy { fn into(self) -> (T, T, T) { self.into_components() } } -impl From<(T, T, T, A)> - for Alpha, A> -{ +impl From<(T, T, T, A)> for Alpha, A> { fn from(components: (T, T, T, A)) -> Self { Self::from_components(components) } } -impl Into<(T, T, T, A)> - for Alpha, A> -{ +impl Into<(T, T, T, A)> for Alpha, A> { fn into(self) -> (T, T, T, A) { self.into_components() } @@ -216,7 +210,7 @@ impl Into<(T, T, T, A)> impl Limited for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { #[cfg_attr(rustfmt, rustfmt_skip)] @@ -241,7 +235,7 @@ where impl Mix for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -260,7 +254,7 @@ where impl Shade for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -277,7 +271,7 @@ where impl ComponentWise for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Scalar = T; @@ -303,7 +297,7 @@ where impl Default for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { fn default() -> Yxy { @@ -320,7 +314,7 @@ where impl Add> for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Yxy; @@ -337,7 +331,7 @@ where impl Add for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Yxy; @@ -354,7 +348,7 @@ where impl AddAssign> for Yxy where - T: Component + Float + AddAssign, + T: FloatComponent + AddAssign, Wp: WhitePoint, { fn add_assign(&mut self, other: Yxy) { @@ -366,7 +360,7 @@ where impl AddAssign for Yxy where - T: Component + Float + AddAssign, + T: FloatComponent + AddAssign, Wp: WhitePoint, { fn add_assign(&mut self, c: T) { @@ -378,7 +372,7 @@ where impl Sub> for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Yxy; @@ -395,7 +389,7 @@ where impl Sub for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Yxy; @@ -411,9 +405,9 @@ where } impl SubAssign> for Yxy - where - T: Component + Float + SubAssign, - Wp: WhitePoint, +where + T: FloatComponent + SubAssign, + Wp: WhitePoint, { fn sub_assign(&mut self, other: Yxy) { self.x -= other.x; @@ -423,9 +417,9 @@ impl SubAssign> for Yxy } impl SubAssign for Yxy - where - T: Component + Float + SubAssign, - Wp: WhitePoint, +where + T: FloatComponent + SubAssign, + Wp: WhitePoint, { fn sub_assign(&mut self, c: T) { self.x -= c; @@ -436,7 +430,7 @@ impl SubAssign for Yxy impl Mul> for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Yxy; @@ -453,7 +447,7 @@ where impl Mul for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Yxy; @@ -469,9 +463,9 @@ where } impl MulAssign> for Yxy - where - T: Component + Float + MulAssign, - Wp: WhitePoint, +where + T: FloatComponent + MulAssign, + Wp: WhitePoint, { fn mul_assign(&mut self, other: Yxy) { self.x *= other.x; @@ -481,9 +475,9 @@ impl MulAssign> for Yxy } impl MulAssign for Yxy - where - T: Component + Float + MulAssign, - Wp: WhitePoint, +where + T: FloatComponent + MulAssign, + Wp: WhitePoint, { fn mul_assign(&mut self, c: T) { self.x *= c; @@ -494,7 +488,7 @@ impl MulAssign for Yxy impl Div> for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Yxy; @@ -511,7 +505,7 @@ where impl Div for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, { type Output = Yxy; @@ -527,9 +521,9 @@ where } impl DivAssign> for Yxy - where - T: Component + Float + DivAssign, - Wp: WhitePoint, +where + T: FloatComponent + DivAssign, + Wp: WhitePoint, { fn div_assign(&mut self, other: Yxy) { self.x /= other.x; @@ -539,9 +533,9 @@ impl DivAssign> for Yxy } impl DivAssign for Yxy - where - T: Component + Float + DivAssign, - Wp: WhitePoint, +where + T: FloatComponent + DivAssign, + Wp: WhitePoint, { fn div_assign(&mut self, c: T) { self.x /= c; @@ -552,7 +546,7 @@ impl DivAssign for Yxy impl AsRef

for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, P: RawPixel + ?Sized, { @@ -563,7 +557,7 @@ where impl AsMut

for Yxy where - T: Component + Float, + T: FloatComponent, Wp: WhitePoint, P: RawPixel + ?Sized, { @@ -609,7 +603,7 @@ mod test { #[test] fn ranges() { - assert_ranges!{ + assert_ranges! { Yxy; limited { x: 0.0 => 1.0, diff --git a/palette/tests/pointer_dataset/pointer_data.rs b/palette/tests/pointer_dataset/pointer_data.rs index 1ed1c47ba..aeabb963a 100644 --- a/palette/tests/pointer_dataset/pointer_data.rs +++ b/palette/tests/pointer_dataset/pointer_data.rs @@ -11,16 +11,16 @@ u', v' 0.2008907213 0.4608888395 Note: The xyz and yxy conversions do not use the updated conversion formula. So they are not used. */ +use csv; use num_traits::{NumCast, ToPrimitive}; use palette::float::Float; -use csv; -use palette::{Component, IntoColor, Lab, Lch, Xyz}; use palette::white_point::WhitePoint; +use palette::{FloatComponent, IntoColor, Lab, Lch, Xyz}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct PointerWP; impl WhitePoint for PointerWP { - fn get_xyz() -> Xyz { + fn get_xyz() -> Xyz { Xyz::with_wp(flt(0.980722647624), T::one(), flt(1.182254189827)) } } @@ -68,8 +68,7 @@ macro_rules! impl_from_color_pointer { } } } - - } + }; } impl_from_color_pointer!(Lch); diff --git a/palette_derive/src/convert/shared.rs b/palette_derive/src/convert/shared.rs index 79448eed4..826cfdb9b 100644 --- a/palette_derive/src/convert/shared.rs +++ b/palette_derive/src/convert/shared.rs @@ -77,7 +77,7 @@ pub fn rgb_space_type(rgb_space: Option, white_point: &Type, internal: boo } pub fn add_component_where_clause(component: &Type, generics: &mut Generics, internal: bool) { - let component_trait_path = util::path(&["Component"], internal); + let component_trait_path = util::path(&["FloatComponent"], internal); generics .make_where_clause()