Skip to content

Commit

Permalink
Merge #225
Browse files Browse the repository at this point in the history
225: `Hsluv` implementation r=Ogeon a=masonium

Round three!

This finally implements the HSLuv color space as `Hsluv`. A few notes.

- I didn't implement Uniform generation for `Hsluv` because I wasn't convinced that the naive version would be anything close to correct. I think you could do something like rejection sample in `Lchuv` (based on if, after converting that to Xyz, it were in-gamut) and then convert the result to `Hsluv`, but that's a very different approach than anything I see currently implemented. 
- I also added macros for implementing `core::ops::Add` and related traits, since they're pretty repetitive. I also added tests to confirm that all of the arithmetic operations are implemented (though there is no correctness checking).
- I kept `l` as the field name, rather than `lightness`, since it is the same as the `Lchuv` `l`. 

Closes #112

Co-authored-by: Mason Smith <masonium@gmail.com>
  • Loading branch information
bors[bot] and masonium committed May 23, 2021
2 parents c7b0365 + 11954d1 commit fad9c87
Show file tree
Hide file tree
Showing 11 changed files with 1,153 additions and 260 deletions.
22 changes: 21 additions & 1 deletion palette/src/convert.rs
Expand Up @@ -529,7 +529,7 @@ mod tests {
use crate::encoding::linear::Linear;
use crate::luma::{Luma, LumaStandard};
use crate::rgb::{Rgb, RgbSpace};
use crate::{Alpha, Hsl, Hsv, Hwb, Lab, Lch, Luv, Xyz, Yxy};
use crate::{Alpha, Hsl, Hsluv, Hsv, Hwb, Lab, Lch, Luv, Xyz, Yxy};
use crate::{Clamp, FloatComponent};

#[derive(FromColorUnclamped, WithAlpha)]
Expand Down Expand Up @@ -684,6 +684,9 @@ mod tests {
let hsl: Hsl<_, f64> = Default::default();
WithXyz::<crate::encoding::Srgb>::from_color(hsl);

let hsluv: Hsluv<_, f64> = Default::default();
WithXyz::<crate::encoding::Srgb>::from_color(hsluv);

let hsv: Hsv<_, f64> = Default::default();
WithXyz::<crate::encoding::Srgb>::from_color(hsv);

Expand Down Expand Up @@ -721,6 +724,9 @@ mod tests {
let hsl: Alpha<Hsl<_, f64>, u8> = Alpha::from(Hsl::default());
WithXyz::<crate::encoding::Srgb>::from_color(hsl);

let hsluv: Alpha<Hsluv<_, f64>, u8> = Alpha::from(Hsluv::default());
WithXyz::<crate::encoding::Srgb>::from_color(hsluv);

let hsv: Alpha<Hsv<_, f64>, u8> = Alpha::from(Hsv::default());
WithXyz::<crate::encoding::Srgb>::from_color(hsv);

Expand Down Expand Up @@ -758,6 +764,9 @@ mod tests {
let hsl: Hsl<_, f64> = Default::default();
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(hsl);

let hsluv: Hsluv<_, f64> = Default::default();
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(hsluv);

let hsv: Hsv<_, f64> = Default::default();
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(hsv);

Expand Down Expand Up @@ -795,6 +804,9 @@ mod tests {
let hsl: Hsl<_, f64> = Default::default();
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(hsl);

let hsluv: Hsluv<_, f64> = Default::default();
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(hsluv);

let hsv: Hsv<_, f64> = Default::default();
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(hsv);

Expand All @@ -817,6 +829,7 @@ mod tests {
let _luv: Luv<_, f64> = color.into_color();
let _rgb: Rgb<_, f64> = color.into_color();
let _hsl: Hsl<_, f64> = color.into_color();
let _hsluv: Hsluv<_, f64> = color.into_color();
let _hsv: Hsv<_, f64> = color.into_color();
let _hwb: Hwb<_, f64> = color.into_color();
let _luma: Luma<crate::encoding::Srgb, f64> = color.into_color();
Expand All @@ -835,6 +848,7 @@ mod tests {
let _luv: Luv<_, f64> = color.into_color();
let _rgb: Rgb<_, f64> = color.into_color();
let _hsl: Hsl<_, f64> = color.into_color();
let _hsluv: Hsluv<_, f64> = color.into_color();
let _hsv: Hsv<_, f64> = color.into_color();
let _hwb: Hwb<_, f64> = color.into_color();
let _luma: Luma<crate::encoding::Srgb, f64> = color.into_color();
Expand All @@ -852,6 +866,7 @@ mod tests {
let _luv: Alpha<Luv<_, f64>, u8> = color.into_color();
let _rgb: Alpha<Rgb<_, f64>, u8> = color.into_color();
let _hsl: Alpha<Hsl<_, f64>, u8> = color.into_color();
let _hsluv: Alpha<Hsluv<_, f64>, u8> = color.into_color();
let _hsv: Alpha<Hsv<_, f64>, u8> = color.into_color();
let _hwb: Alpha<Hwb<_, f64>, u8> = color.into_color();
let _luma: Alpha<Luma<crate::encoding::Srgb, f64>, u8> = color.into_color();
Expand All @@ -870,6 +885,7 @@ mod tests {
let _luv: Alpha<Luv<_, f64>, u8> = color.into_color();
let _rgb: Alpha<Rgb<_, f64>, u8> = color.into_color();
let _hsl: Alpha<Hsl<_, f64>, u8> = color.into_color();
let _hsluv: Alpha<Hsluv<_, f64>, u8> = color.into_color();
let _hsv: Alpha<Hsv<_, f64>, u8> = color.into_color();
let _hwb: Alpha<Hwb<_, f64>, u8> = color.into_color();
let _luma: Alpha<Luma<crate::encoding::Srgb, f64>, u8> = color.into_color();
Expand Down Expand Up @@ -901,6 +917,9 @@ mod tests {
let hsl: Hsl<_, f64> = Default::default();
WithoutXyz::<f64>::from_color(hsl);

let hsluv: Hsluv<_, f64> = Default::default();
WithoutXyz::<f64>::from_color(hsluv);

let hsv: Hsv<_, f64> = Default::default();
WithoutXyz::<f64>::from_color(hsv);

Expand All @@ -923,6 +942,7 @@ mod tests {
let _luv: Luv<crate::white_point::E, f64> = color.into_color();
let _rgb: Rgb<_, f64> = color.into_color();
let _hsl: Hsl<_, f64> = color.into_color();
let _hsluv: Hsluv<_, f64> = color.into_color();
let _hsv: Hsv<_, f64> = color.into_color();
let _hwb: Hwb<_, f64> = color.into_color();
let _luma: Luma<Linear<crate::white_point::E>, f64> = color.into_color();
Expand Down
4 changes: 3 additions & 1 deletion palette/src/equality.rs
Expand Up @@ -3,7 +3,8 @@ use approx::{AbsDiffEq, RelativeEq, UlpsEq};
use crate::float::Float;
use crate::white_point::WhitePoint;
use crate::{
from_f64, FloatComponent, FromF64, Lab, LabHue, Lch, Lchuv, Luv, LuvHue, RgbHue, Xyz, Yxy,
from_f64, FloatComponent, FromF64, Hsluv, Lab, LabHue, Lch, Lchuv, Luv, LuvHue, RgbHue, Xyz,
Yxy,
};

macro_rules! impl_eq {
Expand Down Expand Up @@ -69,6 +70,7 @@ impl_eq!(Lab, [l, a, b]);
impl_eq!(Luv, [l, u, v]);
impl_eq!(Lch, [l, chroma, hue]);
impl_eq!(Lchuv, [l, chroma, hue]);
impl_eq!(Hsluv, [hue, saturation, l]);

// For hues, the difference is calculated and compared to zero. However due to
// the way floating point's work this is not so simple.
Expand Down

0 comments on commit fad9c87

Please sign in to comment.