Impl Color trait
This commit is contained in:
parent
a3f997e763
commit
58c3233fe3
4 changed files with 169 additions and 31 deletions
|
@ -13,13 +13,15 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
pub trait Channel: Num {
|
pub trait Channel: Primitive + Orderable {
|
||||||
priv fn from<T:Channel>(chan: T) -> Self;
|
priv fn from<T:Channel>(chan: T) -> Self;
|
||||||
pub fn to_channel<T:Channel>(&self) -> T;
|
pub fn to_channel<T:Channel>(&self) -> T;
|
||||||
pub fn to_channel_u8(&self) -> u8;
|
pub fn to_channel_u8(&self) -> u8;
|
||||||
pub fn to_channel_u16(&self) -> u16;
|
pub fn to_channel_u16(&self) -> u16;
|
||||||
pub fn to_channel_f32(&self) -> f32;
|
pub fn to_channel_f32(&self) -> f32;
|
||||||
pub fn to_channel_f64(&self) -> f64;
|
pub fn to_channel_f64(&self) -> f64;
|
||||||
|
|
||||||
|
pub fn invert_channel(&self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Channel for u8 {
|
impl Channel for u8 {
|
||||||
|
@ -29,6 +31,8 @@ impl Channel for u8 {
|
||||||
#[inline] pub fn to_channel_u16(&self) -> u16 { (*self as u16 << 8) | (*self) as u16 }
|
#[inline] pub fn to_channel_u16(&self) -> u16 { (*self as u16 << 8) | (*self) as u16 }
|
||||||
#[inline] pub fn to_channel_f32(&self) -> f32 { (*self as f32) / (0xFF as f32) }
|
#[inline] pub fn to_channel_f32(&self) -> f32 { (*self as f32) / (0xFF as f32) }
|
||||||
#[inline] pub fn to_channel_f64(&self) -> f64 { (*self as f64) / (0xFF as f64) }
|
#[inline] pub fn to_channel_f64(&self) -> f64 { (*self as f64) / (0xFF as f64) }
|
||||||
|
|
||||||
|
#[inline] pub fn invert_channel(&self) -> u8 { !(*self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Channel for u16 {
|
impl Channel for u16 {
|
||||||
|
@ -38,24 +42,42 @@ impl Channel for u16 {
|
||||||
#[inline] pub fn to_channel_u16(&self) -> u16 { (*self) }
|
#[inline] pub fn to_channel_u16(&self) -> u16 { (*self) }
|
||||||
#[inline] pub fn to_channel_f32(&self) -> f32 { (*self) / 0xFFFF as f32 }
|
#[inline] pub fn to_channel_f32(&self) -> f32 { (*self) / 0xFFFF as f32 }
|
||||||
#[inline] pub fn to_channel_f64(&self) -> f64 { (*self) / 0xFFFF as f64 }
|
#[inline] pub fn to_channel_f64(&self) -> f64 { (*self) / 0xFFFF as f64 }
|
||||||
|
|
||||||
|
#[inline] pub fn invert_channel(&self) -> u16 { !(*self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Channel for f32 {
|
impl Channel for f32 {
|
||||||
#[inline] priv fn from<T:Channel>(chan: T) -> f32 { chan.to_channel_f32() }
|
#[inline] priv fn from<T:Channel>(chan: T) -> f32 { chan.to_channel_f32() }
|
||||||
#[inlune] pub fn to_channel<T:Channel>(&self) -> T { Channel::from(*self) }
|
#[inlune] pub fn to_channel<T:Channel>(&self) -> T { Channel::from(*self) }
|
||||||
#[inline] pub fn to_channel_u8(&self) -> u8 { (*self) * (0xFF_u8 as f32) as u8 }
|
#[inline] pub fn to_channel_u8(&self) -> u8 { (*self) * (0xFF as f32) as u8 }
|
||||||
#[inline] pub fn to_channel_u16(&self) -> u16 { (*self) * (0xFFFF_u16 as f32) as u16 }
|
#[inline] pub fn to_channel_u16(&self) -> u16 { (*self) * (0xFFFF as f32) as u16 }
|
||||||
#[inline] pub fn to_channel_f32(&self) -> f32 { (*self) }
|
#[inline] pub fn to_channel_f32(&self) -> f32 { (*self) }
|
||||||
#[inline] pub fn to_channel_f64(&self) -> f64 { (*self) as f64 }
|
#[inline] pub fn to_channel_f64(&self) -> f64 { (*self) as f64 }
|
||||||
|
|
||||||
|
#[inline] pub fn invert_channel(&self) -> f32 { 1.0 - (*self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Channel for f64 {
|
impl Channel for f64 {
|
||||||
#[inline] priv fn from<T:Channel>(chan: T) -> f64 { chan.to_channel_f64() }
|
#[inline] priv fn from<T:Channel>(chan: T) -> f64 { chan.to_channel_f64() }
|
||||||
#[inlune] pub fn to_channel<T:Channel>(&self) -> T { Channel::from(*self) }
|
#[inlune] pub fn to_channel<T:Channel>(&self) -> T { Channel::from(*self) }
|
||||||
#[inline] pub fn to_channel_u8(&self) -> u8 { (*self) * (0xFF_u8 as f64) as u8 }
|
#[inline] pub fn to_channel_u8(&self) -> u8 { (*self) * (0xFF as f64) as u8 }
|
||||||
#[inline] pub fn to_channel_u16(&self) -> u16 { (*self) * (0xFFFF_u16 as f64) as u16 }
|
#[inline] pub fn to_channel_u16(&self) -> u16 { (*self) * (0xFFFF as f64) as u16 }
|
||||||
#[inline] pub fn to_channel_f32(&self) -> f32 { (*self) as f32 }
|
#[inline] pub fn to_channel_f32(&self) -> f32 { (*self) as f32 }
|
||||||
#[inline] pub fn to_channel_f64(&self) -> f64 { (*self) }
|
#[inline] pub fn to_channel_f64(&self) -> f64 { (*self) }
|
||||||
|
|
||||||
|
#[inline] pub fn invert_channel(&self) -> f64 { 1.0 - (*self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait FloatChannel: Float + Channel {
|
||||||
|
pub fn invert_degrees(&self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FloatChannel for f32 {
|
||||||
|
#[inline] pub fn invert_degrees(&self) -> f32 { ((*self) + 180.0) % 360.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FloatChannel for f64 {
|
||||||
|
#[inline] pub fn invert_degrees(&self) -> f64 { ((*self) + 180.0) % 360.0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -63,7 +85,7 @@ mod tests {
|
||||||
use color::Channel;
|
use color::Channel;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_channel_u8() {
|
fn test_to_channel_u8() {
|
||||||
assert_eq!(0x00_u8.to_channel_u8(), 0x00_u8);
|
assert_eq!(0x00_u8.to_channel_u8(), 0x00_u8);
|
||||||
assert_eq!(0x30_u8.to_channel_u8(), 0x30_u8);
|
assert_eq!(0x30_u8.to_channel_u8(), 0x30_u8);
|
||||||
assert_eq!(0x66_u8.to_channel_u8(), 0x66_u8);
|
assert_eq!(0x66_u8.to_channel_u8(), 0x66_u8);
|
||||||
|
@ -84,7 +106,14 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_channel_u16() {
|
fn test_invert_channel_u8() {
|
||||||
|
assert_eq!(0x00_u8.invert_channel(), 0xFF_u8);
|
||||||
|
assert_eq!(0x66_u8.invert_channel(), 0x99_u8);
|
||||||
|
assert_eq!(0xFF_u8.invert_channel(), 0x00_u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_to_channel_u16() {
|
||||||
assert_eq!(0x0000_u16.to_channel_u8(), 0x00_u8);
|
assert_eq!(0x0000_u16.to_channel_u8(), 0x00_u8);
|
||||||
assert_eq!(0x3300_u16.to_channel_u8(), 0x33_u8);
|
assert_eq!(0x3300_u16.to_channel_u8(), 0x33_u8);
|
||||||
assert_eq!(0x6666_u16.to_channel_u8(), 0x66_u8);
|
assert_eq!(0x6666_u16.to_channel_u8(), 0x66_u8);
|
||||||
|
@ -105,7 +134,14 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_channel_f32() {
|
fn test_invert_channel_u16() {
|
||||||
|
assert_eq!(0x0000_u16.invert_channel(), 0xFFFF_u16);
|
||||||
|
assert_eq!(0x6666_u16.invert_channel(), 0x9999_u16);
|
||||||
|
assert_eq!(0xFFFF_u16.invert_channel(), 0x0000_u16);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_to_channel_f32() {
|
||||||
assert_eq!(0.00f32.to_channel_u8(), 0x00);
|
assert_eq!(0.00f32.to_channel_u8(), 0x00);
|
||||||
assert_eq!(0.25f32.to_channel_u8(), 0x3F);
|
assert_eq!(0.25f32.to_channel_u8(), 0x3F);
|
||||||
assert_eq!(0.50f32.to_channel_u8(), 0x7F);
|
assert_eq!(0.50f32.to_channel_u8(), 0x7F);
|
||||||
|
@ -126,7 +162,23 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_channel_f64() {
|
fn test_invert_channel_f32() {
|
||||||
|
assert_eq!(0.00f32.invert_channel(), 1.00f32);
|
||||||
|
assert_eq!(0.50f32.invert_channel(), 0.50f32);
|
||||||
|
assert_eq!(1.00f32.invert_channel(), 0.00f32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invert_degrees_f32() {
|
||||||
|
assert_eq!( 0.00f32.invert_degrees(), 180.00f32);
|
||||||
|
assert_eq!( 45.00f32.invert_degrees(), 225.00f32);
|
||||||
|
assert_eq!( 90.00f32.invert_degrees(), 270.00f32);
|
||||||
|
assert_eq!(360.00f32.invert_degrees(), 180.00f32);
|
||||||
|
assert_eq!(720.00f32.invert_degrees(), 180.00f32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_to_channel_f64() {
|
||||||
assert_eq!(0.00f64.to_channel_u8(), 0x00);
|
assert_eq!(0.00f64.to_channel_u8(), 0x00);
|
||||||
assert_eq!(0.25f64.to_channel_u8(), 0x3F);
|
assert_eq!(0.25f64.to_channel_u8(), 0x3F);
|
||||||
assert_eq!(0.50f64.to_channel_u8(), 0x7F);
|
assert_eq!(0.50f64.to_channel_u8(), 0x7F);
|
||||||
|
@ -145,4 +197,20 @@ mod tests {
|
||||||
assert_eq!(0.00f64.to_channel_f64(), 0.00f64);
|
assert_eq!(0.00f64.to_channel_f64(), 0.00f64);
|
||||||
assert_eq!(1.00f64.to_channel_f64(), 1.00f64);
|
assert_eq!(1.00f64.to_channel_f64(), 1.00f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invert_channel_f64() {
|
||||||
|
assert_eq!(0.00f64.invert_channel(), 1.00f64);
|
||||||
|
assert_eq!(0.50f64.invert_channel(), 0.50f64);
|
||||||
|
assert_eq!(1.00f64.invert_channel(), 0.00f64);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invert_degrees_f64() {
|
||||||
|
assert_eq!( 0.00f64.invert_degrees(), 180.00f64);
|
||||||
|
assert_eq!( 45.00f64.invert_degrees(), 225.00f64);
|
||||||
|
assert_eq!( 90.00f64.invert_degrees(), 270.00f64);
|
||||||
|
assert_eq!(360.00f64.invert_degrees(), 180.00f64);
|
||||||
|
assert_eq!(720.00f64.invert_degrees(), 180.00f64);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
pub use self::channel::Channel;
|
pub use self::channel::{Channel, FloatChannel};
|
||||||
pub use self::hsv::{HSV, ToHSV, HSVA, ToHSVA};
|
pub use self::hsv::{HSV, ToHSV, HSVA, ToHSVA};
|
||||||
pub use self::rgb::{RGB, ToRGB, RGBA, ToRGBA};
|
pub use self::rgb::{RGB, ToRGB, RGBA, ToRGBA};
|
||||||
pub use self::srgb::{SRGB, SRGBA};
|
pub use self::srgb::{SRGB, SRGBA};
|
||||||
|
@ -24,6 +24,6 @@ pub mod rgb;
|
||||||
pub mod srgb;
|
pub mod srgb;
|
||||||
|
|
||||||
pub trait Color<T> {
|
pub trait Color<T> {
|
||||||
|
pub fn clamp(&self, lo: T, hi: T) -> Self;
|
||||||
pub fn inverse(&self) -> Self;
|
pub fn inverse(&self) -> Self;
|
||||||
pub fn invert_self(&mut self);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
use std::num;
|
use std::num;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
|
|
||||||
use color::Channel;
|
use color::Color;
|
||||||
|
use color::{Channel, FloatChannel};
|
||||||
use color::{RGB, ToRGB, RGBA, ToRGBA};
|
use color::{RGB, ToRGB, RGBA, ToRGBA};
|
||||||
|
|
||||||
#[path = "../num_macros.rs"]
|
#[path = "../num_macros.rs"]
|
||||||
|
@ -25,40 +26,56 @@ mod num_macros;
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct HSV<T> { h: T, s: T, v: T }
|
pub struct HSV<T> { h: T, s: T, v: T }
|
||||||
|
|
||||||
impl<T:Channel + Float> HSV<T> {
|
impl<T:FloatChannel> HSV<T> {
|
||||||
pub fn new(h: T, s: T, v: T) -> HSV<T> {
|
pub fn new(h: T, s: T, v: T) -> HSV<T> {
|
||||||
HSV { h: h, s: s, v: v }
|
HSV { h: h, s: s, v: v }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T:FloatChannel> Color<T> for HSV<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn clamp(&self, lo: T, hi: T) -> HSV<T> {
|
||||||
|
HSV::new((*self).h.clamp(&lo, &hi),
|
||||||
|
(*self).s.clamp(&lo, &hi),
|
||||||
|
(*self).v.clamp(&lo, &hi))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn inverse(&self) -> HSV<T> {
|
||||||
|
HSV::new((*self).h.invert_degrees(),
|
||||||
|
(*self).s.invert_channel(),
|
||||||
|
(*self).v.invert_channel())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ToHSV {
|
pub trait ToHSV {
|
||||||
pub fn to_hsv<U:Channel + Float>(&self) -> HSV<U>;
|
pub fn to_hsv<U:FloatChannel>(&self) -> HSV<U>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToHSV for u32 {
|
impl ToHSV for u32 {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsv<U:Channel + Float>(&self) -> HSV<U> {
|
pub fn to_hsv<U:FloatChannel>(&self) -> HSV<U> {
|
||||||
fail!("Not yet implemented")
|
fail!("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToHSV for u64 {
|
impl ToHSV for u64 {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsv<U:Channel + Float>(&self) -> HSV<U> {
|
pub fn to_hsv<U:FloatChannel>(&self) -> HSV<U> {
|
||||||
fail!("Not yet implemented")
|
fail!("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Channel + Float> ToHSV for HSV<T> {
|
impl<T:Clone + FloatChannel> ToHSV for HSV<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsv<U:Channel + Float>(&self) -> HSV<U> {
|
pub fn to_hsv<U:FloatChannel>(&self) -> HSV<U> {
|
||||||
HSV::new((*self).h.to_channel(),
|
HSV::new((*self).h.to_channel(),
|
||||||
(*self).s.to_channel(),
|
(*self).s.to_channel(),
|
||||||
(*self).v.to_channel())
|
(*self).v.to_channel())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Channel + Float> ToRGB for HSV<T> {
|
impl<T:Clone + FloatChannel> ToRGB for HSV<T> {
|
||||||
pub fn to_rgb<U:Channel>(&self) -> RGB<U> {
|
pub fn to_rgb<U:Channel>(&self) -> RGB<U> {
|
||||||
// Algorithm taken from the Wikipedia article on HSL and HSV:
|
// Algorithm taken from the Wikipedia article on HSL and HSV:
|
||||||
// http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
|
// http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
|
||||||
|
@ -93,7 +110,7 @@ impl<T:Clone + Channel + Float> ToRGB for HSV<T> {
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct HSVA<T> { h: T, s: T, v: T, a: T }
|
pub struct HSVA<T> { h: T, s: T, v: T, a: T }
|
||||||
|
|
||||||
impl<T:Channel + Float> HSVA<T> {
|
impl<T:FloatChannel> HSVA<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(h: T, s: T, v: T, a: T) -> HSVA<T> {
|
pub fn new(h: T, s: T, v: T, a: T) -> HSVA<T> {
|
||||||
HSVA { h: h, s: s, v: v, a: a }
|
HSVA { h: h, s: s, v: v, a: a }
|
||||||
|
@ -115,27 +132,45 @@ impl<T:Channel + Float> HSVA<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T:FloatChannel> Color<T> for HSVA<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn clamp(&self, lo: T, hi: T) -> HSVA<T> {
|
||||||
|
HSVA::new((*self).h.clamp(&lo, &hi),
|
||||||
|
(*self).s.clamp(&lo, &hi),
|
||||||
|
(*self).v.clamp(&lo, &hi),
|
||||||
|
(*self).a.clamp(&lo, &hi))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn inverse(&self) -> HSVA<T> {
|
||||||
|
HSVA::new((*self).h.invert_degrees(),
|
||||||
|
(*self).s.invert_channel(),
|
||||||
|
(*self).v.invert_channel(),
|
||||||
|
(*self).a.invert_channel())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ToHSVA {
|
pub trait ToHSVA {
|
||||||
pub fn to_hsva<U:Channel + Float>(&self) -> HSVA<U>;
|
pub fn to_hsva<U:FloatChannel>(&self) -> HSVA<U>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToHSVA for u32 {
|
impl ToHSVA for u32 {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsva<U:Channel + Float>(&self) -> HSVA<U> {
|
pub fn to_hsva<U:FloatChannel>(&self) -> HSVA<U> {
|
||||||
fail!("Not yet implemented")
|
fail!("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToHSVA for u64 {
|
impl ToHSVA for u64 {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsva<U:Channel + Float>(&self) -> HSVA<U> {
|
pub fn to_hsva<U:FloatChannel>(&self) -> HSVA<U> {
|
||||||
fail!("Not yet implemented")
|
fail!("Not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: ToHSV, T:Clone + Channel + Float> ToHSVA for (C, T) {
|
impl<C: ToHSV, T:Clone + FloatChannel> ToHSVA for (C, T) {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsva<U:Channel + Float>(&self) -> HSVA<U> {
|
pub fn to_hsva<U:FloatChannel>(&self) -> HSVA<U> {
|
||||||
match *self {
|
match *self {
|
||||||
(ref hsv, ref a) => {
|
(ref hsv, ref a) => {
|
||||||
HSVA::from_hsv_a(hsv.to_hsv(), a.to_channel())
|
HSVA::from_hsv_a(hsv.to_hsv(), a.to_channel())
|
||||||
|
@ -144,9 +179,9 @@ impl<C: ToHSV, T:Clone + Channel + Float> ToHSVA for (C, T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Channel + Float> ToHSVA for HSVA<T> {
|
impl<T:Clone + FloatChannel> ToHSVA for HSVA<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsva<U:Channel + Float>(&self) -> HSVA<U> {
|
pub fn to_hsva<U:FloatChannel>(&self) -> HSVA<U> {
|
||||||
HSVA::new((*self).h.to_channel(),
|
HSVA::new((*self).h.to_channel(),
|
||||||
(*self).s.to_channel(),
|
(*self).s.to_channel(),
|
||||||
(*self).v.to_channel(),
|
(*self).v.to_channel(),
|
||||||
|
@ -154,7 +189,7 @@ impl<T:Clone + Channel + Float> ToHSVA for HSVA<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Channel + Float> ToRGBA for HSVA<T> {
|
impl<T:Clone + FloatChannel> ToRGBA for HSVA<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_rgba<U:Channel>(&self) -> RGBA<U> {
|
pub fn to_rgba<U:Channel>(&self) -> RGBA<U> {
|
||||||
RGBA::from_rgb_a(self.hsv().to_rgb(), (*self).a.to_channel())
|
RGBA::from_rgb_a(self.hsv().to_rgb(), (*self).a.to_channel())
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
use std::num;
|
use std::num;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
|
|
||||||
use color::Channel;
|
use color::Color;
|
||||||
|
use color::{Channel, FloatChannel};
|
||||||
use color::{HSV, ToHSV, HSVA, ToHSVA};
|
use color::{HSV, ToHSV, HSVA, ToHSVA};
|
||||||
|
|
||||||
#[path = "../num_macros.rs"]
|
#[path = "../num_macros.rs"]
|
||||||
|
@ -32,6 +33,22 @@ impl<T:Channel> RGB<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T:Channel> Color<T> for RGB<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn clamp(&self, lo: T, hi: T) -> RGB<T> {
|
||||||
|
RGB::new((*self).r.clamp(&lo, &hi),
|
||||||
|
(*self).g.clamp(&lo, &hi),
|
||||||
|
(*self).b.clamp(&lo, &hi))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn inverse(&self) -> RGB<T> {
|
||||||
|
RGB::new((*self).r.invert_channel(),
|
||||||
|
(*self).g.invert_channel(),
|
||||||
|
(*self).b.invert_channel())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ToRGB {
|
pub trait ToRGB {
|
||||||
pub fn to_rgb<U:Channel>(&self) -> RGB<U>;
|
pub fn to_rgb<U:Channel>(&self) -> RGB<U>;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +78,7 @@ impl<T:Clone + Channel> ToRGB for RGB<T> {
|
||||||
|
|
||||||
impl<T:Clone + Channel> ToHSV for RGB<T> {
|
impl<T:Clone + Channel> ToHSV for RGB<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsv<U:Channel + Float>(&self) -> HSV<U> {
|
pub fn to_hsv<U:FloatChannel>(&self) -> HSV<U> {
|
||||||
// Algorithm taken from the Wikipedia article on HSL and HSV:
|
// Algorithm taken from the Wikipedia article on HSL and HSV:
|
||||||
// http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
|
// http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
|
||||||
|
|
||||||
|
@ -113,6 +130,24 @@ impl<T:Channel> RGBA<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T:Channel> Color<T> for RGBA<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn clamp(&self, lo: T, hi: T) -> RGBA<T> {
|
||||||
|
RGBA::new((*self).r.clamp(&lo, &hi),
|
||||||
|
(*self).g.clamp(&lo, &hi),
|
||||||
|
(*self).b.clamp(&lo, &hi),
|
||||||
|
(*self).a.clamp(&lo, &hi))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn inverse(&self) -> RGBA<T> {
|
||||||
|
RGBA::new((*self).r.invert_channel(),
|
||||||
|
(*self).g.invert_channel(),
|
||||||
|
(*self).b.invert_channel(),
|
||||||
|
(*self).a.invert_channel())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ToRGBA {
|
pub trait ToRGBA {
|
||||||
pub fn to_rgba<U:Channel>(&self) -> RGBA<U>;
|
pub fn to_rgba<U:Channel>(&self) -> RGBA<U>;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +189,7 @@ impl<T:Clone + Channel> ToRGBA for RGBA<T> {
|
||||||
|
|
||||||
impl<T:Clone + Channel> ToHSVA for RGBA<T> {
|
impl<T:Clone + Channel> ToHSVA for RGBA<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_hsva<U:Channel + Float>(&self) -> HSVA<U> {
|
pub fn to_hsva<U:FloatChannel>(&self) -> HSVA<U> {
|
||||||
HSVA::from_hsv_a(self.rgb().to_hsv(), (*self).a.to_channel())
|
HSVA::from_hsv_a(self.rgb().to_hsv(), (*self).a.to_channel())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue