Move color module to new git repository

This commit is contained in:
Brendan Zabarauskas 2012-12-13 16:57:09 +10:00
parent b429d91fcf
commit 7f14c6784b
6 changed files with 0 additions and 1327 deletions

View file

@ -1,146 +0,0 @@
use num::types::Number;
/**
* A color channel
*/
pub trait Channel: Number {
/**
* The maximum value used by the channel
*/
static pure fn max() -> self;
/**
* Convert a channel to the enclosing type
*
* # Example
*
* ~~~
* let chan: f32 = Channel::from(0xFFFFu16);
* assert chan == 1.0f32;
* ~~~
*/
static pure fn from<T:Channel>(val: T) -> self;
pure fn to_channel_u8(&self) -> u8;
pure fn to_channel_u16(&self) -> u16;
pure fn to_channel_u32(&self) -> u32;
pure fn to_channel_u64(&self) -> u64;
pure fn to_channel_f32(&self) -> f32;
pure fn to_channel_f64(&self) -> f64;
pure fn to_channel_float(&self) -> float;
pure fn inverse(&self) -> self;
}
pub impl u8: Channel {
#[inline(always)] static pure fn max() -> u8 { 0xFF } // 2^8
#[inline(always)] static pure fn from<T:Channel>(val: T) -> u8 { val.to_channel_u8() }
#[inline(always)] pure fn to_channel_u8(&self) -> u8 { (*self) }
#[inline(always)] pure fn to_channel_u16(&self) -> u16 { (*self as u16 << 8) | (*self) as u16 }
#[inline(always)] pure fn to_channel_u32(&self) -> u32 { (self.to_channel_u16() as u32 << 16) | self.to_channel_u16() as u32 }
#[inline(always)] pure fn to_channel_u64(&self) -> u64 { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
#[inline(always)] pure fn to_channel_f32(&self) -> f32 { (*self as f32) / (0xFF as f32) }
#[inline(always)] pure fn to_channel_f64(&self) -> f64 { (*self as f64) / (0xFF as f64) }
#[inline(always)] pure fn to_channel_float(&self) -> float { (*self as float) / (0xFF as float) }
#[inline(always)] pure fn inverse(&self) -> u8 { !(*self) }
}
pub impl u16: Channel {
#[inline(always)] static pure fn max() -> u16 { 0xFFFF } // 2^16
#[inline(always)] static pure fn from<T:Channel>(val: T) -> u16 { val.to_channel_u16() }
#[inline(always)] pure fn to_channel_u8(&self) -> u8 { (*self >> 8) as u8 } // this is the equivalent of `self/256`. Some folks prefer to do `self/257`
#[inline(always)] pure fn to_channel_u16(&self) -> u16 { (*self) }
#[inline(always)] pure fn to_channel_u32(&self) -> u32 { (*self as u32 << 16) | (*self) as u32 }
#[inline(always)] pure fn to_channel_u64(&self) -> u64 { (self.to_channel_u32() as u64 << 32) | self.to_channel_u32() as u64 }
#[inline(always)] pure fn to_channel_f32(&self) -> f32 { (*self) / 0xFFFF as f32 }
#[inline(always)] pure fn to_channel_f64(&self) -> f64 { (*self) / 0xFFFF as f64 }
#[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF as float }
#[inline(always)] pure fn inverse(&self) -> u16 { !(*self) }
}
pub impl u32: Channel {
#[inline(always)] static pure fn max() -> u32 { 0xFFFF_FFFF } // 2^32
#[inline(always)] static pure fn from<T:Channel>(val: T) -> u32 { val.to_channel_u32() }
#[inline(always)] pure fn to_channel_u8(&self) -> u8 { (*self >> 24) as u8 }
#[inline(always)] pure fn to_channel_u16(&self) -> u16 { (*self >> 16) as u16 }
#[inline(always)] pure fn to_channel_u32(&self) -> u32 { (*self) }
#[inline(always)] pure fn to_channel_u64(&self) -> u64 { (*self as u64 << 32) | (*self) as u64 }
#[inline(always)] pure fn to_channel_f32(&self) -> f32 { (*self) / 0xFFFF_FFFF as f32 }
#[inline(always)] pure fn to_channel_f64(&self) -> f64 { (*self) / 0xFFFF_FFFF as f64 }
#[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF_FFFF as float }
#[inline(always)] pure fn inverse(&self) -> u32 { !(*self) }
}
pub impl u64: Channel {
#[inline(always)] static pure fn max() -> u64 { 0xFFFF_FFFF_FFFF_FFFF_u64 } // 2^64
#[inline(always)] static pure fn from<T:Channel>(val: T) -> u64 { val.to_channel_u64() }
#[inline(always)] pure fn to_channel_u8(&self) -> u8 { (*self >> 56) as u8 }
#[inline(always)] pure fn to_channel_u16(&self) -> u16 { (*self >> 48) as u16 }
#[inline(always)] pure fn to_channel_u32(&self) -> u32 { (*self >> 32) as u32 }
#[inline(always)] pure fn to_channel_u64(&self) -> u64 { (*self) }
#[inline(always)] pure fn to_channel_f32(&self) -> f32 { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as f32 }
#[inline(always)] pure fn to_channel_f64(&self) -> f64 { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as f64 }
#[inline(always)] pure fn to_channel_float(&self) -> float { (*self) / 0xFFFF_FFFF_FFFF_FFFF_u64 as float }
#[inline(always)] pure fn inverse(&self) -> u64 { !(*self) }
}
pub impl f32: Channel {
#[inline(always)] static pure fn max() -> f32 { 1f32 }
#[inline(always)] static pure fn from<T:Channel>(val: T) -> f32 { val.to_channel_f32() }
#[inline(always)] pure fn to_channel_u8(&self) -> u8 { (*self) * (0xFF_u8 as f32) as u8 }
#[inline(always)] pure fn to_channel_u16(&self) -> u16 { (*self) * (0xFFFF_u16 as f32) as u16 }
#[inline(always)] pure fn to_channel_u32(&self) -> u32 { fail(~"to_channel_u32 not yet implemented for f32") }
#[inline(always)] pure fn to_channel_u64(&self) -> u64 { fail(~"to_channel_u64 not yet implemented for f32") }
#[inline(always)] pure fn to_channel_f32(&self) -> f32 { (*self) }
#[inline(always)] pure fn to_channel_f64(&self) -> f64 { (*self) as f64 }
#[inline(always)] pure fn to_channel_float(&self) -> float { (*self) as float }
#[inline(always)] pure fn inverse(&self) -> f32 { 1f32 - (*self) }
}
pub impl f64: Channel {
#[inline(always)] static pure fn max() -> f64 { 1f64 }
#[inline(always)] static pure fn from<T:Channel>(val: T) -> f64 { val.to_channel_f64() }
#[inline(always)] pure fn to_channel_u8(&self) -> u8 { (*self) * (0xFF_u8 as f64) as u8 }
#[inline(always)] pure fn to_channel_u16(&self) -> u16 { (*self) * (0xFFFF_u16 as f64) as u16 }
#[inline(always)] pure fn to_channel_u32(&self) -> u32 { fail(~"to_channel_u32 not yet implemented for f64") }
#[inline(always)] pure fn to_channel_u64(&self) -> u64 { fail(~"to_channel_u64 not yet implemented for f64") }
#[inline(always)] pure fn to_channel_f32(&self) -> f32 { (*self) as f32 }
#[inline(always)] pure fn to_channel_f64(&self) -> f64 { (*self) }
#[inline(always)] pure fn to_channel_float(&self) -> float { (*self) as float }
#[inline(always)] pure fn inverse(&self) -> f64 { 1f64 - (*self) }
}
pub impl float: Channel {
#[inline(always)] static pure fn max() -> float { 1f }
#[inline(always)] static pure fn from<T:Channel>(val: T) -> float { val.to_channel_float() }
#[inline(always)] pure fn to_channel_u8(&self) -> u8 { (*self) * (0xFF_u8 as float) as u8 }
#[inline(always)] pure fn to_channel_u16(&self) -> u16 { (*self) * (0xFFFF_u16 as float) as u16 }
#[inline(always)] pure fn to_channel_u32(&self) -> u32 { fail(~"to_channel_u32 not yet implemented for float") }
#[inline(always)] pure fn to_channel_u64(&self) -> u64 { fail(~"to_channel_u64 not yet implemented for float") }
#[inline(always)] pure fn to_channel_f32(&self) -> f32 { (*self) as f32 }
#[inline(always)] pure fn to_channel_f64(&self) -> f64 { (*self) as f64 }
#[inline(always)] pure fn to_channel_float(&self) -> float { (*self) }
#[inline(always)] pure fn inverse(&self) -> float { 1f - (*self) }
}

View file

@ -1,823 +0,0 @@
use core::cast::transmute;
use core::cmp::Eq;
use core::ptr::to_unsafe_ptr;
use core::sys::size_of;
use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use angle::Degrees;
use channel::Channel;
use funs::common::Sign;
use num::types::{Float, Number};
/**
* A generic color trait.
*/
pub trait Color<T>: Index<uint, T> Eq {
/**
* # Return value
*
* The color with each component inverted
*/
pure fn inverse(&self) -> self;
/**
* Convert the color to a `RGB<u8>`
*
* # Returns
*
* The color as a `RGB<u8>` color with components in the range of
* `0x00u8` to `0xFFu8`
*/
pure fn to_rgb_u8(&self) -> RGB<u8>;
/**
* Convert the color to a `RGB<u16>`
*
* # Returns
*
* The color as a `RGB<u16>` color with components in the range of
* `0x0000u16` to `0xFFFFu16`
*/
pure fn to_rgb_u16(&self) -> RGB<u16>;
/**
* Convert the color to a `RGB<u32>`
*
* # Returns
*
* The color as a `RGB<u32>` color with components in the range of
* `0x0000_0000_u32` to `0xFFFF_FFFF_u32`
*/
pure fn to_rgb_u32(&self) -> RGB<u32>;
/**
* Convert the color to a `RGB<u64>`
*
* # Returns
*
* The color as a `RGB<u32>` color with components in the range of
* `0x0000_0000_u32` to `0xFFFF_FFFF_u32`
*/
pure fn to_rgb_u64(&self) -> RGB<u64>;
/**
* Convert the color to a `RGB<f32>`
*
* # Returns
*
* The color as a `RGB<f32>` color with components in the range of
* `0f32` to `1f32`
*/
pure fn to_rgb_f32(&self) -> RGB<f32>;
/**
* Convert the color to a `RGB<f64>`
*
* # Returns
*
* The color as a `RGB<f64>` color with components in the range of
* `0f64` to `1f64`
*/
pure fn to_rgb_f64(&self) -> RGB<f64>;
/**
* Convert the color to a `HSV<f32>`
*
* # Returns
*
* The color as a `HSV<f32>` with the `h` component as a `Degrees<f32>`
* angle type, and saturation and value components in the range of `0f32`
* to `1f32`.
*/
pure fn to_hsv_f32(&self) -> HSV<f32>;
/**
* Convert the color to a `HSV<f64>`
*
* # Returns
*
* The color as a `HSV<f64>` with the `h` component as a `Degrees<f64>`
* angle type, and saturation and value components in the range of `0f64`
* to `1f64`.
*/
pure fn to_hsv_f64(&self) -> HSV<f64>;
/**
* # Return value
*
* A pointer to the first component of the color
*/
pure fn to_ptr(&self) -> *T;
}
pub trait MutableColor<T>: Color<T> {
/**
* Get a mutable reference to the component at `i`
*/
fn index_mut(&mut self, i: uint) -> &self/mut T;
/**
* Swap two components of the color in place
*/
fn swap(&mut self, a: uint, b: uint);
/**
* Invert each component of the color
*/
fn invert_self(&mut self);
}
/**
* A generic three-component color
*/
pub trait Color3<T>: Color<T> {
// TODO: documentation (bleh, so much writing)
pure fn to_rgba_u8(&self, a: u8) -> RGBA<u8>;
pure fn to_rgba_u16(&self, a: u16) -> RGBA<u16>;
pure fn to_rgba_u32(&self, a: u32) -> RGBA<u32>;
pure fn to_rgba_u64(&self, a: u64) -> RGBA<u64>;
pure fn to_rgba_f32(&self, a: f32) -> RGBA<f32>;
pure fn to_rgba_f64(&self, a: f64) -> RGBA<f64>;
pure fn to_hsva_f32(&self, a: f32) -> HSVA<f32>;
pure fn to_hsva_f64(&self, a: f64) -> HSVA<f64>;
}
/**
* A generic four-component color, the last component being an alpha channel
*/
pub trait Color4<T>: Color<T> {
// TODO: documentation (arrg...)
pure fn to_rgba_u8(&self) -> RGBA<u8>;
pure fn to_rgba_u16(&self) -> RGBA<u16>;
pure fn to_rgba_u32(&self) -> RGBA<u32>;
pure fn to_rgba_u64(&self) -> RGBA<u64>;
pure fn to_rgba_f32(&self) -> RGBA<f32>;
pure fn to_rgba_f64(&self) -> RGBA<f64>;
pure fn to_hsva_f32(&self) -> HSVA<f32>;
pure fn to_hsva_f64(&self) -> HSVA<f64>;
}
// TODO!!!
// pub trait ColorRGB<T> {
// static pure fn from_hex(hex: u8) -> self;
// }
/**
* RGB to HSV conversion
*/
#[inline(always)]
pub pure fn to_hsv<T:Copy Float>(color: &RGB<T>) -> HSV<T> {
// Algorithm taken from the Wikipedia article on HSL and HSV:
// http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
let _0 = Number::from(0f);
let mx = [color.r, color.g, color.b].max();
let mn = [color.r, color.g, color.b].min();
let chr = mx - mn;
if chr != Number::from(0f) {
let h = Degrees(
if color.r == mx { ((color.g - color.b) / chr) % Number::from(6f) }
else if color.g == mx { ((color.b - color.r) / chr) + Number::from(2f) }
else /* color.b == mx */{ ((color.r - color.g) / chr) + Number::from(4f) }
* Number::from(60f));
let s = chr / mx;
HSV::new(h, s, mx)
} else {
HSV::new(Degrees(_0), _0, mx)
}
}
/**
* HSV to RGB conversion
*/
#[inline(always)]
pub pure fn to_rgb<T:Copy Float Sign>(color: &HSV<T>) -> RGB<T> {
// Algorithm taken from the Wikipedia article on HSL and HSV:
// http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
let _0: T = Number::from(0f);
let _1: T = Number::from(1f);
let _2: T = Number::from(2f);
let chr = color.v * color.s;
let h_ = (* color.h) / Number::from(60f); // TODO: it'd be nice if Degrees / Degrees returned a scalar
// the 2nd largest component
let x = chr * (_1 - ((h_ % _2) - _1).abs());
let mut color_rgb =
if h_ < Number::from(1f) { RGB::new(chr, x, _0) }
else if h_ < Number::from(2f) { RGB::new( x, chr, _0) }
else if h_ < Number::from(3f) { RGB::new( _0, chr, x) }
else if h_ < Number::from(4f) { RGB::new( _0, x, chr) }
else if h_ < Number::from(5f) { RGB::new( x, _0, chr) }
else if h_ < Number::from(6f) { RGB::new(chr, _0, x) }
else { RGB::new( _0, _0, _0) };
// match the value by adding the same amount to each component
let mn = color.v - chr;
color_rgb.r += mn;
color_rgb.g += mn;
color_rgb.b += mn;
return color_rgb;
}
/**
* A RGB color type (red, green, blue)
*
* # Type parameters
*
* * `T` - A color component which should be one of the following primitive
* types: `u8`, `u16`, `u32`, `u64`, `f32` or `f64`.
*
* # Fields
*
* * `r` - the red component
* * `g` - the green component
* * `b` - the blue component
*/
pub struct RGB<T> { r: T, g: T, b: T }
pub impl<T:Copy> RGB<T> {
#[inline(always)]
static pure fn new(r: T, g: T, b: T) -> RGB<T> {
RGB { r: move r, g: move g, b: move b }
}
}
pub impl<T:Copy Number Channel> RGB<T>: Index<uint, T> {
#[inline(always)]
pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } }
}
}
pub impl<T:Copy Number Channel> RGB<T>: Color<T> {
#[inline(always)]
pure fn inverse(&self) -> RGB<T> {
RGB::new(self.r.inverse(),
self.g.inverse(),
self.b.inverse())
}
#[inline(always)]
pure fn to_rgb_u8(&self) -> RGB<u8> {
RGB::new(self.r.to_channel_u8(),
self.g.to_channel_u8(),
self.b.to_channel_u8())
}
#[inline(always)]
pure fn to_rgb_u16(&self) -> RGB<u16> {
RGB::new(self.r.to_channel_u16(),
self.g.to_channel_u16(),
self.b.to_channel_u16())
}
#[inline(always)]
pure fn to_rgb_u32(&self) -> RGB<u32> {
RGB::new(self.r.to_channel_u32(),
self.g.to_channel_u32(),
self.b.to_channel_u32())
}
#[inline(always)]
pure fn to_rgb_u64(&self) -> RGB<u64> {
RGB::new(self.r.to_channel_u64(),
self.g.to_channel_u64(),
self.b.to_channel_u64())
}
#[inline(always)]
pure fn to_rgb_f32(&self) -> RGB<f32> {
RGB::new(self.r.to_channel_f32(),
self.g.to_channel_f32(),
self.b.to_channel_f32())
}
#[inline(always)]
pure fn to_rgb_f64(&self) -> RGB<f64> {
RGB::new(self.r.to_channel_f64(),
self.g.to_channel_f64(),
self.b.to_channel_f64())
}
#[inline(always)] pure fn to_hsv_f32(&self) -> HSV<f32> { to_hsv(&self.to_rgb_f32()) }
#[inline(always)] pure fn to_hsv_f64(&self) -> HSV<f64> { to_hsv(&self.to_rgb_f64()) }
#[inline(always)]
pure fn to_ptr(&self) -> *T {
unsafe {
transmute::<*RGB<T>, *T>(
to_unsafe_ptr(self)
)
}
}
}
pub impl<T:Copy Channel> RGB<T>: MutableColor<T> {
#[inline(always)]
fn index_mut(&mut self, i: uint) -> &self/mut T {
match i {
0 => &mut self.r,
1 => &mut self.g,
2 => &mut self.b,
_ => fail(fmt!("index out of bounds: expected an index from 0 to 2, but found %u", i))
}
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
util::swap(self.index_mut(a),
self.index_mut(b));
}
#[inline(always)]
fn invert_self(&mut self) {
self.r = self.r.inverse();
self.g = self.g.inverse();
self.b = self.b.inverse();
}
}
pub impl<T:Copy Number Channel> RGB<T>: Color3<T> {
#[inline(always)] pure fn to_rgba_u8(&self, a: u8) -> RGBA<u8> { RGBA::from_rgb_a(&self.to_rgb_u8(), a) }
#[inline(always)] pure fn to_rgba_u16(&self, a: u16) -> RGBA<u16> { RGBA::from_rgb_a(&self.to_rgb_u16(), a) }
#[inline(always)] pure fn to_rgba_u32(&self, a: u32) -> RGBA<u32> { RGBA::from_rgb_a(&self.to_rgb_u32(), a) }
#[inline(always)] pure fn to_rgba_u64(&self, a: u64) -> RGBA<u64> { RGBA::from_rgb_a(&self.to_rgb_u64(), a) }
#[inline(always)] pure fn to_rgba_f32(&self, a: f32) -> RGBA<f32> { RGBA::from_rgb_a(&self.to_rgb_f32(), a) }
#[inline(always)] pure fn to_rgba_f64(&self, a: f64) -> RGBA<f64> { RGBA::from_rgb_a(&self.to_rgb_f64(), a) }
#[inline(always)] pure fn to_hsva_f32(&self, a: f32) -> HSVA<f32> { HSVA::from_hsv_a(&self.to_hsv_f32(), a) }
#[inline(always)] pure fn to_hsva_f64(&self, a: f64) -> HSVA<f64> { HSVA::from_hsv_a(&self.to_hsv_f64(), a) }
}
pub impl<T:Copy Eq> RGB<T>: Eq {
pure fn eq(&self, other: &RGB<T>) -> bool {
self.r == other.r &&
self.g == other.g &&
self.b == other.b
}
pure fn ne(&self, other: &RGB<T>) -> bool {
!(self == other)
}
}
pub impl<T:Copy Float> RGB<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &RGB<T>) -> bool {
self.r.fuzzy_eq(&other.r) &&
self.g.fuzzy_eq(&other.g) &&
self.b.fuzzy_eq(&other.b)
}
}
/**
* A RGBA color type (red, green, blue, alpha)
*
* # Type parameters
*
* * `T` - A color component which should be one of the following primitive
* types: `u8`, `u16`, `u32`, `u64`, `f32` or `f64`.
*
* # Fields
*
* * `r` - the red component
* * `g` - the green component
* * `b` - the blue component
* * `a` - the alpha component
*/
pub struct RGBA<T> { r: T, g: T, b: T, a: T }
pub impl<T:Copy> RGBA<T> {
#[inline(always)]
static pure fn new(r: T, g: T, b: T, a: T) -> RGBA<T> {
RGBA { r: move r, g: move g, b: move b, a: move a }
}
#[inline(always)]
static pure fn from_rgb_a(rgb: &RGB<T>, a: T) -> RGBA<T> {
RGBA::new(rgb.r, rgb.g, rgb.b, move a)
}
}
pub impl<T:Copy Number Channel> RGBA<T>: Index<uint, T> {
#[inline(always)]
pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } }
}
}
pub impl<T:Copy Number Channel> RGBA<T>: Color<T> {
#[inline(always)]
pure fn inverse(&self) -> RGBA<T> {
RGBA::new(self.r.inverse(),
self.g.inverse(),
self.b.inverse(),
self.a.inverse())
}
#[inline(always)]
pure fn to_rgb_u8(&self) -> RGB<u8> {
RGB::new(self.r.to_channel_u8(),
self.g.to_channel_u8(),
self.b.to_channel_u8())
}
#[inline(always)]
pure fn to_rgb_u16(&self) -> RGB<u16> {
RGB::new(self.r.to_channel_u16(),
self.g.to_channel_u16(),
self.b.to_channel_u16())
}
#[inline(always)]
pure fn to_rgb_u32(&self) -> RGB<u32> {
RGB::new(self.r.to_channel_u32(),
self.g.to_channel_u32(),
self.b.to_channel_u32())
}
#[inline(always)]
pure fn to_rgb_u64(&self) -> RGB<u64> {
RGB::new(self.r.to_channel_u64(),
self.g.to_channel_u64(),
self.b.to_channel_u64())
}
#[inline(always)]
pure fn to_rgb_f32(&self) -> RGB<f32> {
RGB::new(self.r.to_channel_f32(),
self.g.to_channel_f32(),
self.b.to_channel_f32())
}
#[inline(always)]
pure fn to_rgb_f64(&self) -> RGB<f64> {
RGB::new(self.r.to_channel_f64(),
self.g.to_channel_f64(),
self.b.to_channel_f64())
}
#[inline(always)] pure fn to_hsv_f32(&self) -> HSV<f32> { to_hsv(&self.to_rgb_f32()) }
#[inline(always)] pure fn to_hsv_f64(&self) -> HSV<f64> { to_hsv(&self.to_rgb_f64()) }
#[inline(always)]
pure fn to_ptr(&self) -> *T {
unsafe {
transmute::<*RGBA<T>, *T>(
to_unsafe_ptr(self)
)
}
}
}
pub impl<T:Copy Channel> RGBA<T>: MutableColor<T> {
#[inline(always)]
fn index_mut(&mut self, i: uint) -> &self/mut T {
match i {
0 => &mut self.r,
1 => &mut self.g,
2 => &mut self.b,
3 => &mut self.a,
_ => fail(fmt!("index out of bounds: expected an index from 0 to 2, but found %u", i))
}
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
util::swap(self.index_mut(a),
self.index_mut(b));
}
#[inline(always)]
fn invert_self(&mut self) {
self.r = self.r.inverse();
self.g = self.g.inverse();
self.b = self.b.inverse();
self.a = self.a.inverse();
}
}
pub impl<T:Copy Number Channel> RGBA<T>: Color4<T> {
#[inline(always)] pure fn to_rgba_u8(&self) -> RGBA<u8> { RGBA::from_rgb_a(&self.to_rgb_u8(), self.a.to_channel_u8()) }
#[inline(always)] pure fn to_rgba_u16(&self) -> RGBA<u16> { RGBA::from_rgb_a(&self.to_rgb_u16(), self.a.to_channel_u16()) }
#[inline(always)] pure fn to_rgba_u32(&self) -> RGBA<u32> { RGBA::from_rgb_a(&self.to_rgb_u32(), self.a.to_channel_u32()) }
#[inline(always)] pure fn to_rgba_u64(&self) -> RGBA<u64> { RGBA::from_rgb_a(&self.to_rgb_u64(), self.a.to_channel_u64()) }
#[inline(always)] pure fn to_rgba_f32(&self) -> RGBA<f32> { RGBA::from_rgb_a(&self.to_rgb_f32(), self.a.to_channel_f32()) }
#[inline(always)] pure fn to_rgba_f64(&self) -> RGBA<f64> { RGBA::from_rgb_a(&self.to_rgb_f64(), self.a.to_channel_f64()) }
#[inline(always)] pure fn to_hsva_f32(&self) -> HSVA<f32> { HSVA::from_hsv_a(&self.to_hsv_f32(), self.a.to_channel_f32()) }
#[inline(always)] pure fn to_hsva_f64(&self) -> HSVA<f64> { HSVA::from_hsv_a(&self.to_hsv_f64(), self.a.to_channel_f64()) }
}
pub impl<T:Copy Eq> RGBA<T>: Eq {
pure fn eq(&self, other: &RGBA<T>) -> bool {
self.r == other.r &&
self.g == other.g &&
self.b == other.b &&
self.a == other.a
}
pure fn ne(&self, other: &RGBA<T>) -> bool {
!(self == other)
}
}
pub impl<T:Copy Float> RGBA<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &RGBA<T>) -> bool {
self.r.fuzzy_eq(&other.r) &&
self.g.fuzzy_eq(&other.g) &&
self.b.fuzzy_eq(&other.b) &&
self.a.fuzzy_eq(&other.a)
}
}
/**
* A HSV color type (hue, saturation, value)
*
* # Type parameters
*
* * `T` - A color component which should be either an `f32` or `f64`.
*
* # Fields
*
* * `h` - the hue component in degrees (from 0.0 to 360.0)
* * `s` - the saturation component
* * `v` - the value (brightness) component
*/
pub struct HSV<T> { h: Degrees<T>, s: T, v: T }
pub impl<T:Copy> HSV<T> {
static pure fn new(h: Degrees<T>, s: T, v: T) -> HSV<T> {
HSV { h: move h, s: move s, v: move v }
}
}
pub impl<T:Copy Float Channel> HSV<T>: Index<uint, T> {
#[inline(always)]
pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 3) |slice| { slice[i] } }
}
}
pub impl<T:Copy Float Channel> HSV<T>: Color<T> {
#[inline(always)]
pure fn inverse(&self) -> HSV<T> {
HSV::new(self.h.opposite(),
self.s.inverse(),
self.v.inverse())
}
#[inline(always)] pure fn to_rgb_u8(&self) -> RGB<u8> { to_rgb(&self.to_hsv_f32()).to_rgb_u8() }
#[inline(always)] pure fn to_rgb_u16(&self) -> RGB<u16> { to_rgb(&self.to_hsv_f32()).to_rgb_u16() }
#[inline(always)] pure fn to_rgb_u32(&self) -> RGB<u32> { to_rgb(&self.to_hsv_f32()).to_rgb_u32() }
#[inline(always)] pure fn to_rgb_u64(&self) -> RGB<u64> { to_rgb(&self.to_hsv_f32()).to_rgb_u64() }
#[inline(always)] pure fn to_rgb_f32(&self) -> RGB<f32> { to_rgb(&self.to_hsv_f32()).to_rgb_f32() }
#[inline(always)] pure fn to_rgb_f64(&self) -> RGB<f64> { to_rgb(&self.to_hsv_f64()).to_rgb_f64() }
#[inline(always)]
pure fn to_hsv_f32(&self) -> HSV<f32> {
HSV::new(Degrees((*self.h).to_f32()),
self.s.to_channel_f32(),
self.v.to_channel_f32())
}
#[inline(always)]
pure fn to_hsv_f64(&self) -> HSV<f64> {
HSV::new(Degrees((*self.h).to_f64()),
self.s.to_channel_f64(),
self.v.to_channel_f64())
}
#[inline(always)]
pure fn to_ptr(&self) -> *T {
unsafe {
transmute::<*HSV<T>, *T>(
to_unsafe_ptr(self)
)
}
}
}
pub impl<T:Copy Channel Float> HSV<T>: MutableColor<T> {
#[inline(always)]
fn index_mut(&mut self, i: uint) -> &self/mut T {
match i {
0 => fail(~"can't swap the hue component at index 0 in a HSVA type"),
1 => &mut self.s,
2 => &mut self.v,
_ => fail(fmt!("index out of bounds: expected an index from 0 to 2, but found %u", i))
}
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
if a != 0 && b != 0 { fail(fmt!("can't swap the hue component (at index 0) in a HSV type: found a: %u, b: %u", a, b)); }
util::swap(self.index_mut(a),
self.index_mut(b));
}
#[inline(always)]
fn invert_self(&mut self) {
self.h = self.h.opposite();
self.s = self.s.inverse();
self.v = self.v.inverse();
}
}
pub impl<T:Copy Float Channel> HSV<T>: Color3<T> {
#[inline(always)] pure fn to_rgba_u8(&self, a: u8) -> RGBA<u8> { RGBA::from_rgb_a(&self.to_rgb_u8(), a) }
#[inline(always)] pure fn to_rgba_u16(&self, a: u16) -> RGBA<u16> { RGBA::from_rgb_a(&self.to_rgb_u16(), a) }
#[inline(always)] pure fn to_rgba_u32(&self, a: u32) -> RGBA<u32> { RGBA::from_rgb_a(&self.to_rgb_u32(), a) }
#[inline(always)] pure fn to_rgba_u64(&self, a: u64) -> RGBA<u64> { RGBA::from_rgb_a(&self.to_rgb_u64(), a) }
#[inline(always)] pure fn to_rgba_f32(&self, a: f32) -> RGBA<f32> { RGBA::from_rgb_a(&self.to_rgb_f32(), a) }
#[inline(always)] pure fn to_rgba_f64(&self, a: f64) -> RGBA<f64> { RGBA::from_rgb_a(&self.to_rgb_f64(), a) }
#[inline(always)] pure fn to_hsva_f32(&self, a: f32) -> HSVA<f32> { HSVA::from_hsv_a(&self.to_hsv_f32(), a) }
#[inline(always)] pure fn to_hsva_f64(&self, a: f64) -> HSVA<f64> { HSVA::from_hsv_a(&self.to_hsv_f64(), a) }
}
pub impl<T:Copy Float> HSV<T>: Eq {
pure fn eq(&self, other: &HSV<T>) -> bool {
self.h == other.h &&
self.s == other.s &&
self.v == other.v
}
pure fn ne(&self, other: &HSV<T>) -> bool {
!(self == other)
}
}
pub impl<T:Copy Float> HSV<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &HSV<T>) -> bool {
self.h.fuzzy_eq(&other.h) &&
self.s.fuzzy_eq(&other.s) &&
self.v.fuzzy_eq(&other.v)
}
}
/**
* A HSVA color type (hue, saturation, value, alpha)
*
* # Type parameters
*
* * `T` - A color component which should be either an `f32` or `f64`.
*
* # Fields
*
* * `h` - the hue component in degrees (from 0.0 to 360.0)
* * `s` - the saturation component
* * `v` - the value (brightness) component
* * `v` - the alpha component
*/
pub struct HSVA<T> { h: Degrees<T>, s: T, v: T, a: T }
pub impl<T:Copy> HSVA<T> {
#[inline(always)]
static pure fn new(h: Degrees<T>, s: T, v: T, a: T) -> HSVA<T> {
HSVA { h: move h, s: move s, v: move v, a: move a }
}
#[inline(always)]
static pure fn from_hsv_a(hsv: &HSV<T>, a: T) -> HSVA<T> {
HSVA::new(hsv.h, hsv.s, hsv.v, move a)
}
}
pub impl<T:Copy Float Channel> HSVA<T>: Index<uint, T> {
#[inline(always)]
pure fn index(&self, i: uint) -> T {
unsafe { do buf_as_slice(self.to_ptr(), 4) |slice| { slice[i] } }
}
}
pub impl<T:Copy Float Channel> HSVA<T>: Color<T> {
#[inline(always)]
pure fn inverse(&self) -> HSVA<T> {
HSVA::new(self.h.opposite(),
self.s.inverse(),
self.v.inverse(),
self.a.inverse())
}
#[inline(always)] pure fn to_rgb_u8(&self) -> RGB<u8> { to_rgb(&self.to_hsv_f32()).to_rgb_u8() }
#[inline(always)] pure fn to_rgb_u16(&self) -> RGB<u16> { to_rgb(&self.to_hsv_f32()).to_rgb_u16() }
#[inline(always)] pure fn to_rgb_u32(&self) -> RGB<u32> { to_rgb(&self.to_hsv_f32()).to_rgb_u32() }
#[inline(always)] pure fn to_rgb_u64(&self) -> RGB<u64> { to_rgb(&self.to_hsv_f32()).to_rgb_u64() }
#[inline(always)] pure fn to_rgb_f32(&self) -> RGB<f32> { to_rgb(&self.to_hsv_f32()).to_rgb_f32() }
#[inline(always)] pure fn to_rgb_f64(&self) -> RGB<f64> { to_rgb(&self.to_hsv_f64()).to_rgb_f64() }
#[inline(always)]
pure fn to_hsv_f32(&self) -> HSV<f32> {
HSV::new(Degrees((*self.h).to_f32()),
self.s.to_channel_f32(),
self.v.to_channel_f32())
}
#[inline(always)]
pure fn to_hsv_f64(&self) -> HSV<f64> {
HSV::new(Degrees((*self.h).to_f64()),
self.s.to_channel_f64(),
self.v.to_channel_f64())
}
#[inline(always)]
pure fn to_ptr(&self) -> *T {
unsafe {
transmute::<*HSVA<T>, *T>(
to_unsafe_ptr(self)
)
}
}
}
pub impl<T:Copy Channel Float> HSVA<T>: MutableColor<T> {
#[inline(always)]
fn index_mut(&mut self, i: uint) -> &self/mut T {
match i {
0 => fail(~"can't swap the hue component at index 0 in a HSVA type"),
1 => &mut self.s,
2 => &mut self.v,
3 => &mut self.a,
_ => fail(fmt!("index out of bounds: expected an index from 0 to 2, but found %u", i))
}
}
#[inline(always)]
fn swap(&mut self, a: uint, b: uint) {
util::swap(self.index_mut(a),
self.index_mut(b));
}
#[inline(always)]
fn invert_self(&mut self) {
self.h = self.h.opposite();
self.s = self.s.inverse();
self.v = self.v.inverse();
self.a = self.a.inverse();
}
}
pub impl<T:Copy Float Channel> HSVA<T>: Color4<T> {
#[inline(always)] pure fn to_rgba_u8(&self) -> RGBA<u8> { RGBA::from_rgb_a(&self.to_rgb_u8(), self.a.to_channel_u8()) }
#[inline(always)] pure fn to_rgba_u16(&self) -> RGBA<u16> { RGBA::from_rgb_a(&self.to_rgb_u16(), self.a.to_channel_u16()) }
#[inline(always)] pure fn to_rgba_u32(&self) -> RGBA<u32> { RGBA::from_rgb_a(&self.to_rgb_u32(), self.a.to_channel_u32()) }
#[inline(always)] pure fn to_rgba_u64(&self) -> RGBA<u64> { RGBA::from_rgb_a(&self.to_rgb_u64(), self.a.to_channel_u64()) }
#[inline(always)] pure fn to_rgba_f32(&self) -> RGBA<f32> { RGBA::from_rgb_a(&self.to_rgb_f32(), self.a.to_channel_f32()) }
#[inline(always)] pure fn to_rgba_f64(&self) -> RGBA<f64> { RGBA::from_rgb_a(&self.to_rgb_f64(), self.a.to_channel_f64()) }
#[inline(always)] pure fn to_hsva_f32(&self) -> HSVA<f32> { HSVA::from_hsv_a(&self.to_hsv_f32(), self.a.to_channel_f32()) }
#[inline(always)] pure fn to_hsva_f64(&self) -> HSVA<f64> { HSVA::from_hsv_a(&self.to_hsv_f64(), self.a.to_channel_f64()) }
}
pub impl<T:Copy Float> HSVA<T>: Eq {
pure fn eq(&self, other: &HSVA<T>) -> bool {
self.h == other.h &&
self.s == other.s &&
self.v == other.v &&
self.a == other.a
}
pure fn ne(&self, other: &HSVA<T>) -> bool {
!(self == other)
}
}
pub impl<T:Copy Float> HSVA<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &HSVA<T>) -> bool {
self.h.fuzzy_eq(&other.h) &&
self.s.fuzzy_eq(&other.s) &&
self.v.fuzzy_eq(&other.v) &&
self.a.fuzzy_eq(&other.a)
}
}

View file

@ -1,275 +0,0 @@
use channel::*;
#[test]
fn test_channel_u8() {
assert 0x00_u8.to_channel_u8() == 0x00_u8;
assert 0x30_u8.to_channel_u8() == 0x30_u8;
assert 0x66_u8.to_channel_u8() == 0x66_u8;
assert 0xA0_u8.to_channel_u8() == 0xA0_u8;
assert 0xFF_u8.to_channel_u8() == 0xFF_u8;
assert 0x00_u8.to_channel_u16() == 0x0000_u16;
assert 0x30_u8.to_channel_u16() == 0x3030_u16;
assert 0x66_u8.to_channel_u16() == 0x6666_u16;
assert 0xA0_u8.to_channel_u16() == 0xA0A0_u16;
assert 0xFF_u8.to_channel_u16() == 0xFFFF_u16;
assert 0x00_u8.to_channel_u32() == 0x0000_0000_u32;
assert 0x30_u8.to_channel_u32() == 0x3030_3030_u32;
assert 0x66_u8.to_channel_u32() == 0x6666_6666_u32;
assert 0xA0_u8.to_channel_u32() == 0xA0A0_A0A0_u32;
assert 0xFF_u8.to_channel_u32() == 0xFFFF_FFFF_u32;
assert 0x00_u8.to_channel_u64() == 0x0000_0000_0000_0000_u64;
assert 0x30_u8.to_channel_u64() == 0x3030_3030_3030_3030_u64;
assert 0x66_u8.to_channel_u64() == 0x6666_6666_6666_6666_u64;
assert 0xA0_u8.to_channel_u64() == 0xA0A0_A0A0_A0A0_A0A0_u64;
assert 0xFF_u8.to_channel_u64() == 0xFFFF_FFFF_FFFF_FFFF_u64;
assert 0x00_u8.to_channel_f32() == 0f32;
assert 0xFF_u8.to_channel_f32() == 1f32;
assert 0x00_u8.to_channel_f64() == 0f64;
assert 0xFF_u8.to_channel_f64() == 1f64;
assert 0x00_u8.to_channel_float() == 0f;
assert 0xFF_u8.to_channel_float() == 1f;
// Test inverse
assert 0x00_u8.inverse() == 0xFF_u8;
assert 0x66_u8.inverse() == 0x99_u8;
assert 0xFF_u8.inverse() == 0x00_u8;
}
#[test]
fn test_channel_u16() {
assert 0x0000_u16.to_channel_u8() == 0x00_u8;
assert 0x3300_u16.to_channel_u8() == 0x33_u8;
assert 0x6666_u16.to_channel_u8() == 0x66_u8;
assert 0xAA00_u16.to_channel_u8() == 0xAA_u8;
assert 0xFFFF_u16.to_channel_u8() == 0xFF_u8;
assert 0x0000_u16.to_channel_u16() == 0x0000_u16;
assert 0x3300_u16.to_channel_u16() == 0x3300_u16;
assert 0x6666_u16.to_channel_u16() == 0x6666_u16;
assert 0xAA00_u16.to_channel_u16() == 0xAA00_u16;
assert 0xFFFF_u16.to_channel_u16() == 0xFFFF_u16;
assert 0x0000_u16.to_channel_u32() == 0x0000_0000_u32;
assert 0x3300_u16.to_channel_u32() == 0x3300_3300_u32;
assert 0x6666_u16.to_channel_u32() == 0x6666_6666_u32;
assert 0xAA00_u16.to_channel_u32() == 0xAA00_AA00_u32;
assert 0xFFFF_u16.to_channel_u32() == 0xFFFF_FFFF_u32;
assert 0x0000_u16.to_channel_u64() == 0x0000_0000_0000_0000_u64;
assert 0x3300_u16.to_channel_u64() == 0x3300_3300_3300_3300_u64;
assert 0x6666_u16.to_channel_u64() == 0x6666_6666_6666_6666_u64;
assert 0xAA00_u16.to_channel_u64() == 0xAA00_AA00_AA00_AA00_u64;
assert 0xFFFF_u16.to_channel_u64() == 0xFFFF_FFFF_FFFF_FFFF_u64;
assert 0x0000_u16.to_channel_f32() == 0f32;
assert 0xFFFF_u16.to_channel_f32() == 1f32;
assert 0x0000_u16.to_channel_f64() == 0f64;
assert 0xFFFF_u16.to_channel_f64() == 1f64;
assert 0x0000_u16.to_channel_float() == 0f;
assert 0xFFFF_u16.to_channel_float() == 1f;
// Test inverse
assert 0x0000_u16.inverse() == 0xFFFF_u16;
assert 0x6666_u16.inverse() == 0x9999_u16;
assert 0xFFFF_u16.inverse() == 0x0000_u16;
}
#[test]
fn test_channel_u32() {
assert 0x0000_0000_u32.to_channel_u8() == 0x00_u8;
assert 0x3333_0000_u32.to_channel_u8() == 0x33_u8;
assert 0x6666_6666_u32.to_channel_u8() == 0x66_u8;
assert 0xAAAA_0000_u32.to_channel_u8() == 0xAA_u8;
assert 0xFFFF_FFFF_u32.to_channel_u8() == 0xFF_u8;
assert 0x0000_0000_u32.to_channel_u16() == 0x0000_u16;
assert 0x3333_0000_u32.to_channel_u16() == 0x3333_u16;
assert 0x6666_6666_u32.to_channel_u16() == 0x6666_u16;
assert 0xAAAA_0000_u32.to_channel_u16() == 0xAAAA_u16;
assert 0xFFFF_FFFF_u32.to_channel_u16() == 0xFFFF_u16;
assert 0x0000_0000_u32.to_channel_u32() == 0x0000_0000_u32;
assert 0x3333_0000_u32.to_channel_u32() == 0x3333_0000_u32;
assert 0x6666_6666_u32.to_channel_u32() == 0x6666_6666_u32;
assert 0xAAAA_0000_u32.to_channel_u32() == 0xAAAA_0000_u32;
assert 0xFFFF_FFFF_u32.to_channel_u32() == 0xFFFF_FFFF_u32;
assert 0x0000_0000_u32.to_channel_u64() == 0x0000_0000_0000_0000_u64;
assert 0x3333_0000_u32.to_channel_u64() == 0x3333_0000_3333_0000_u64;
assert 0x6666_6666_u32.to_channel_u64() == 0x6666_6666_6666_6666_u64;
assert 0xAAAA_0000_u32.to_channel_u64() == 0xAAAA_0000_AAAA_0000_u64;
assert 0xFFFF_FFFF_u32.to_channel_u64() == 0xFFFF_FFFF_FFFF_FFFF_u64;
assert 0x0000_0000_u32.to_channel_f32() == 0f32;
assert 0xFFFF_FFFF_u32.to_channel_f32() == 1f32;
assert 0x0000_0000_u32.to_channel_f64() == 0f64;
assert 0xFFFF_FFFF_u32.to_channel_f64() == 1f64;
assert 0x0000_0000_u32.to_channel_float() == 0f;
assert 0xFFFF_FFFF_u32.to_channel_float() == 1f;
// Test inverse
assert 0x0000_0000_u32.inverse() == 0xFFFF_FFFF_u32;
assert 0x6666_6666_u32.inverse() == 0x9999_9999_u32;
assert 0xFFFF_FFFF_u32.inverse() == 0x0000_0000_u32;
}
#[test]
fn test_channel_u64() {
assert 0x0000_0000_0000_0000_u64.to_channel_u8() == 0x00_u8;
assert 0x3333_3333_0000_0000_u64.to_channel_u8() == 0x33_u8; // FIXME: color shift?
assert 0x6666_6666_6666_6666_u64.to_channel_u8() == 0x66_u8;
assert 0xAAAA_AAAA_0000_0000_u64.to_channel_u8() == 0xAA_u8; // FIXME: color shift?
assert 0xFFFF_FFFF_FFFF_FFFF_u64.to_channel_u8() == 0xFF_u8;
assert 0x0000_0000_0000_0000_u64.to_channel_u16() == 0x0000_u16;
assert 0x3333_3333_0000_0000_u64.to_channel_u16() == 0x3333_u16; // FIXME: color shift?
assert 0x6666_6666_6666_6666_u64.to_channel_u16() == 0x6666_u16;
assert 0xAAAA_AAAA_0000_0000_u64.to_channel_u16() == 0xAAAA_u16; // FIXME: color shift?
assert 0xFFFF_FFFF_FFFF_FFFF_u64.to_channel_u16() == 0xFFFF_u16;
assert 0x0000_0000_0000_0000_u64.to_channel_u32() == 0x0000_0000_u32;
assert 0x3333_3333_0000_0000_u64.to_channel_u32() == 0x3333_3333_u32; // FIXME: color shift?
assert 0x6666_6666_6666_6666_u64.to_channel_u32() == 0x6666_6666_u32;
assert 0xAAAA_AAAA_0000_0000_u64.to_channel_u32() == 0xAAAA_AAAA_u32; // FIXME: color shift?
assert 0xFFFF_FFFF_FFFF_FFFF_u64.to_channel_u32() == 0xFFFF_FFFF_u32;
assert 0x0000_0000_0000_0000_u64.to_channel_u64() == 0x0000_0000_0000_0000_u64;
assert 0x3333_3333_0000_0000_u64.to_channel_u64() == 0x3333_3333_0000_0000_u64;
assert 0x6666_6666_6666_6666_u64.to_channel_u64() == 0x6666_6666_6666_6666_u64;
assert 0xAAAA_AAAA_0000_0000_u64.to_channel_u64() == 0xAAAA_AAAA_0000_0000_u64;
assert 0xFFFF_FFFF_FFFF_FFFF_u64.to_channel_u64() == 0xFFFF_FFFF_FFFF_FFFF_u64;
assert 0x0000_0000_0000_0000_u64.to_channel_f32() == 0f32;
assert 0xFFFF_FFFF_FFFF_FFFF_u64.to_channel_f32() == 1f32;
assert 0x0000_0000_0000_0000_u64.to_channel_f64() == 0f64;
assert 0xFFFF_FFFF_FFFF_FFFF_u64.to_channel_f64() == 1f64;
assert 0x0000_0000_0000_0000_u64.to_channel_float() == 0f;
assert 0xFFFF_FFFF_FFFF_FFFF_u64.to_channel_float() == 1f;
// Test inverse
assert 0x0000_0000_0000_0000_u64.inverse() == 0xFFFF_FFFF_FFFF_FFFF_u64;
assert 0x6666_6666_6666_6666_u64.inverse() == 0x9999_9999_9999_9999_u64;
assert 0xFFFF_FFFF_FFFF_FFFF_u64.inverse() == 0x0000_0000_0000_0000_u64;
}
#[test]
fn test_channel_f32() {
assert 0.00f32.to_channel_u8() == 0x00;
assert 0.25f32.to_channel_u8() == 0x3F;
assert 0.50f32.to_channel_u8() == 0x7F;
assert 0.75f32.to_channel_u8() == 0xBF;
assert 1.00f32.to_channel_u8() == 0xFF;
assert 0.00f32.to_channel_u16() == 0x0000;
assert 0.25f32.to_channel_u16() == 0x3FFF;
assert 0.50f32.to_channel_u16() == 0x7FFF;
assert 0.75f32.to_channel_u16() == 0xBFFF;
assert 1.00f32.to_channel_u16() == 0xFFFF;
// TODO: test to_channel_u32()
// TODO: test to_channel_u64()
// TODO: test to_channel_f32()
// TODO: test to_channel_f64()
// TODO: test to_channel_float()
// Test inverse
assert 0.00f32.inverse() == 1.00f32;
assert 0.25f32.inverse() == 0.75f32;
assert 0.50f32.inverse() == 0.50f32;
assert 0.75f32.inverse() == 0.25f32;
assert 1.00f32.inverse() == 0.00f32;
}
#[test]
fn test_channel_f64() {
assert 0.00f64.to_channel_u8() == 0x00;
assert 0.25f64.to_channel_u8() == 0x3F;
assert 0.50f64.to_channel_u8() == 0x7F;
assert 0.75f64.to_channel_u8() == 0xBF;
assert 1.00f64.to_channel_u8() == 0xFF;
assert 0.00f64.to_channel_u16() == 0x0000;
assert 0.25f64.to_channel_u16() == 0x3FFF;
assert 0.50f64.to_channel_u16() == 0x7FFF;
assert 0.75f64.to_channel_u16() == 0xBFFF;
assert 1.00f64.to_channel_u16() == 0xFFFF;
// TODO: test to_channel_u32()
// TODO: test to_channel_u64()
// TODO: test to_channel_f32()
// TODO: test to_channel_f64()
// TODO: test to_channel_float()
// Test inverse
assert 0.00f64.inverse() == 1.00f64;
assert 0.25f64.inverse() == 0.75f64;
assert 0.50f64.inverse() == 0.50f64;
assert 0.75f64.inverse() == 0.25f64;
assert 1.00f64.inverse() == 0.00f64;
}
#[test]
fn test_channel_float() {
assert 0.00f.to_channel_u8() == 0x00;
assert 0.25f.to_channel_u8() == 0x3F;
assert 0.50f.to_channel_u8() == 0x7F;
assert 0.75f.to_channel_u8() == 0xBF;
assert 1.00f.to_channel_u8() == 0xFF;
assert 0.00f.to_channel_u16() == 0x0000;
assert 0.25f.to_channel_u16() == 0x3FFF;
assert 0.50f.to_channel_u16() == 0x7FFF;
assert 0.75f.to_channel_u16() == 0xBFFF;
assert 1.00f.to_channel_u16() == 0xFFFF;
// TODO: test to_channel_u32()
// TODO: test to_channel_u64()
// TODO: test to_channel_f32()
// TODO: test to_channel_f64()
// TODO: test to_channel_float()
// Test inverse
assert 0.00f.inverse() == 1.00f;
assert 0.25f.inverse() == 0.75f;
assert 0.50f.inverse() == 0.50f;
assert 0.75f.inverse() == 0.25f;
assert 1.00f.inverse() == 0.00f;
}

View file

@ -1,29 +0,0 @@
use angle::*;
use color::*;
#[test]
fn test_color_rgb() {
// TODO
assert RGB::new::<u8>(0xA0, 0xA0, 0xA0).to_rgb_u8() == RGB::new(0xA0, 0xA0, 0xA0);
assert RGB::new::<u8>(0xA0, 0xA0, 0xA0).to_rgb_u16() == RGB::new(0xA0A0, 0xA0A0, 0xA0A0);
assert RGB::new::<u8>(0xA0, 0xA0, 0xA0).to_rgb_u32() == RGB::new(0xA0A0_A0A0, 0xA0A0_A0A0, 0xA0A0_A0A0);
assert RGB::new::<u8>(0xA0, 0xA0, 0xA0).to_rgb_u64() == RGB::new(0xA0A0_A0A0_A0A0_A0A0, 0xA0A0_A0A0_A0A0_A0A0, 0xA0A0_A0A0_A0A0_A0A0);
// assert RGB::new::<u8>(0xFF, 0xFF, 0xFF).to_hsv_f32() == HSV::new(Degrees(0.0), 0.0, 1.0); // FIXME: causes an ICE
// RGB::new::<u8>(0xFF, 0xFF, 0xFF).to_hsv_f32(); // FIXME: causes an ICE as well :(
}
#[test]
fn test_color_rgba() {
// TODO
}
#[test]
fn test_color_hsv() {
// TODO
}
#[test]
fn test_color_hsva() {
// TODO
}

View file

@ -23,7 +23,6 @@
use core::sys::size_of;
use angle::{Angle, Radians, Degrees};
use color::color::{RGB, RGBA, HSV, HSVA};
use mat::{Matrix, Mat2, Mat3, Mat4};
use vec::{Vector, NumericVector, Vec2, Vec3, Vec4};
use quat::{/*Quaternion, */Quat};
@ -404,46 +403,8 @@ pub impl ddegrees {
pub type quat4 = Quat<f32>; /// a single-precision floating-point quaternion
pub type dquat4 = Quat<f64>; /// a double-precision floating-point quaternion
// Color type aliases. Prefixing the colors with the type letter looked a little
// strange, so in this case I opted for a suffix. It actually loosely follows the
// nomanclature defined in [this article](http://www.opengl.org/wiki/Image_Formats#Color_formats)
// on the OpenGL wiki.
pub type rgb = rgbf; /// same as a `rgb32f`
pub type rgba = rgbaf; /// same as a `rgba32f`
pub type rgbf = rgb32f; /// same as a `rgb32f`
pub type rgb32f = RGB<f32>; /// a 32-bit floating-point RGB color with component values ranging from 0f32 to 1f32
pub type rgb64f = RGB<f64>; /// a 64-bit floating-point RGB color with component values ranging from 0f64 to 1f64
pub type rgbaf = rgba32f; /// same as a `rgba32f`
pub type rgba32f = RGBA<f32>; /// a 32-bit floating-point RGBA color with component values ranging from 0.0 to 1.0
pub type rgba64f = RGBA<f64>; /// a 64-bit floating-point RGBA color with component values ranging from 0.0 to 1.0
pub type rgbu = rgb8u; /// same as a `rgb8u`
pub type rgb8u = RGB<u8>; /// an 8-bit unsigned-integer RGB color with component values ranging from 0x00 to 0xFF
pub type rgb16u = RGB<u16>; /// a 16-bit unsigned-integer RGB color with component values ranging from 0x0000 to 0xFFFF
pub type rgb32u = RGB<u32>; /// a 32-bit unsigned-integer RGB color with component values ranging from 0x0000_0000 to 0xFFFF_FFFF
pub type rgb64u = RGB<u64>; /// a 64-bit unsigned-integer RGB color with component values ranging from 0x0000_0000 to 0xFFFF_FFFF
pub type rgbau = rgba8u; /// same as a `rgba8u`
pub type rgba8u = RGBA<u8>; /// an 8-bit unsigned-integer RGB color with component values ranging from 0x00 to 0xFF
pub type rgba16u = RGBA<u16>; /// a 16-bit unsigned-integer RGB color with component values ranging from 0x0000 to 0xFFFF
pub type rgba32u = RGBA<u32>; /// a 32-bit unsigned-integer RGB color with component values ranging from 0x0000_0000 to 0xFFFF_FFFF
pub type rgba64u = RGBA<u64>; /// a 364bit unsigned-integer RGB color with component values ranging from 0x0000_0000 to 0xFFFF_FFFF
pub type hsv = hsvaf; /// same as a `hsv32f`
pub type hsva = hsvaf; /// same as a `hsva32f`
pub type hsvf = hsv32f; /// same as a `hsv32f`
pub type hsv32f = HSV<f32>; /// TODO: documentation
pub type hsv64f = HSV<f64>; /// TODO: documentation
pub type hsvaf = hsva32f; /// same as a `hsva32f`
pub type hsva32f = HSVA<f32>; /// TODO: documentation
pub type hsva64f = HSVA<f64>; /// TODO: documentation
// TODO: Color method wrappers
// prevents "error: expected item"
priv fn hack() {}

View file

@ -30,21 +30,6 @@ mod test {
mod test_vec;
}
pub mod color {
#[path = "color/channel.rs"]
pub mod channel;
#[path = "color/color.rs"]
pub mod color;
#[test]
mod test {
#[path = "color/test/test_channel.rs"]
mod test_channel;
#[path = "color/test/test_color.rs"]
mod test_color;
}
}
pub mod funs {
#[path = "funs/common.rs"]
pub mod common;