Skip to content

Commit

Permalink
Auto merge of #53 - sidred:hwb, r=Ogeon
Browse files Browse the repository at this point in the history
Add hwb color

Added support for HWB color model.

Added tests, implemented Alpha, ApproxEq, FromColor and IntoColor traits and added to color enum.

closes #32
  • Loading branch information
homu committed Feb 15, 2016
2 parents 209402e + 5cee7ab commit 2ee6064
Show file tree
Hide file tree
Showing 9 changed files with 519 additions and 167 deletions.
31 changes: 22 additions & 9 deletions src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use num::Float;

use {Alpha, Rgb, Luma, Xyz, Yxy, Lab, Lch, Hsv, Hsl, Color};
use {Alpha, Rgb, Luma, Xyz, Yxy, Lab, Lch, Hsv, Hwb, Hsl, Color};

///FromColor provides conversion between the colors.
///
Expand Down Expand Up @@ -46,6 +46,11 @@ pub trait FromColor<T>: Sized
Self::from_rgb(inp.into_rgb())
}

///Convert from HWB color space
fn from_hwb(inp: Hwb<T>) -> Self {
Self::from_hsv(inp.into_hsv())
}

///Convert from Luma
fn from_luma(inp: Luma<T>) -> Self {
Self::from_xyz(inp.into_xyz())
Expand Down Expand Up @@ -95,6 +100,11 @@ pub trait IntoColor<T>: Sized
Hsv::from_rgb(self.into_rgb())
}

///Convert into HWB color space
fn into_hwb(self) -> Hwb<T> {
Hwb::from_hsv(self.into_hsv())
}

///Convert into Luma
fn into_luma(self) -> Luma<T> {
Luma::from_xyz(self.into_xyz())
Expand Down Expand Up @@ -163,6 +173,7 @@ macro_rules! impl_from_trait {
Color::Lch(c) => c.$into_fn(),
Color::Hsv(c) => c.$into_fn(),
Color::Hsl(c) => c.$into_fn(),
Color::Hwb(c) => c.$into_fn(),
}
}
}
Expand Down Expand Up @@ -218,14 +229,16 @@ impl_into_color!(Lch,from_lch);
impl_into_color!(Rgb,from_rgb);
impl_into_color!(Hsl,from_hsl);
impl_into_color!(Hsv,from_hsv);
impl_into_color!(Hwb,from_hwb);
impl_into_color!(Luma,from_luma);


impl_from_trait!((Xyz,into_xyz) => {Yxy, Lab, Lch, Rgb, Hsl, Hsv, Luma});
impl_from_trait!((Yxy,into_yxy) => {Xyz, Lab, Lch, Rgb, Hsl, Hsv, Luma});
impl_from_trait!((Lab,into_lab) => {Xyz, Yxy, Lch, Rgb, Hsl, Hsv, Luma});
impl_from_trait!((Lch,into_lch) => {Xyz, Yxy, Lab, Rgb, Hsl, Hsv, Luma});
impl_from_trait!((Rgb,into_rgb) => {Xyz, Yxy, Lab, Lch, Hsl, Hsv, Luma});
impl_from_trait!((Hsl,into_hsl) => {Xyz, Yxy, Lab, Lch, Rgb, Hsv, Luma});
impl_from_trait!((Hsv,into_hsv) => {Xyz, Yxy, Lab, Lch, Rgb, Hsl, Luma});
impl_from_trait!((Luma,into_luma) => {Xyz, Yxy, Lab, Lch, Rgb, Hsl, Hsv});
impl_from_trait!((Xyz,into_xyz) => {Yxy, Lab, Lch, Rgb, Hsl, Hsv, Hwb, Luma});
impl_from_trait!((Yxy,into_yxy) => {Xyz, Lab, Lch, Rgb, Hsl, Hsv, Hwb, Luma});
impl_from_trait!((Lab,into_lab) => {Xyz, Yxy, Lch, Rgb, Hsl, Hsv, Hwb, Luma});
impl_from_trait!((Lch,into_lch) => {Xyz, Yxy, Lab, Rgb, Hsl, Hsv, Hwb, Luma});
impl_from_trait!((Rgb,into_rgb) => {Xyz, Yxy, Lab, Lch, Hsl, Hsv, Hwb, Luma});
impl_from_trait!((Hsl,into_hsl) => {Xyz, Yxy, Lab, Lch, Rgb, Hsv, Hwb, Luma});
impl_from_trait!((Hsv,into_hsv) => {Xyz, Yxy, Lab, Lch, Rgb, Hsl, Hwb, Luma});
impl_from_trait!((Hwb,into_hwb) => {Xyz, Yxy, Lab, Lch, Rgb, Hsl, Hsv, Luma});
impl_from_trait!((Luma,into_luma) => {Xyz, Yxy, Lab, Lch, Rgb, Hsl, Hsv, Hwb});
3 changes: 2 additions & 1 deletion src/equality.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use num::Float;
use approx::ApproxEq;

use {Xyz, Yxy, Lab, Lch, Rgb, Hsl, Hsv , Luma, LabHue, RgbHue, flt};
use {Xyz, Yxy, Lab, Lch, Rgb, Hsl, Hsv, Hwb, Luma, LabHue, RgbHue, flt};

macro_rules! impl_eq {
( $self_ty: ident , [$($element: ident),+]) => {
Expand Down Expand Up @@ -44,6 +44,7 @@ impl_eq!( Luma, [luma] );
impl_eq!( Lch, [l, chroma] );
impl_eq!( Hsl, [hue, saturation, lightness] );
impl_eq!( Hsv, [hue, saturation, value] );
impl_eq!( Hwb, [hue, whiteness, blackness] );

// For hues diffence is calculated and compared to zero. However due to the way floating point's
// work this is not so simple
Expand Down
17 changes: 16 additions & 1 deletion src/hsv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use num::Float;

use std::ops::{Add, Sub};

use {Alpha, Rgb, Xyz, Hsl, Limited, Mix, Shade, GetHue, Hue, Saturate, RgbHue, FromColor, clamp, flt};
use {Alpha, Rgb, Xyz, Hsl, Hwb, Limited, Mix, Shade, GetHue, Hue, Saturate, RgbHue, FromColor, clamp, flt};

///Linear HSV with an alpha component. See the [`Hsva` implementation in `Alpha`](struct.Alpha.html#Hsva).
pub type Hsva<T = f32> = Alpha<Hsv<T>, T>;
Expand Down Expand Up @@ -125,6 +125,21 @@ impl<T: Float> FromColor<T> for Hsv<T> {
hsv
}

fn from_hwb(hwb: Hwb<T>) -> Self {
let inv = T::one() - hwb.blackness;
// avoid divide by zero
let s = if inv.is_normal() {
T::one() - ( hwb.whiteness / inv )
} else {
T::zero()
};
Hsv {
hue: hwb.hue,
saturation: s,
value: inv,
}
}

}

impl<T: Float> Limited for Hsv<T> {
Expand Down
Loading

0 comments on commit 2ee6064

Please sign in to comment.