Skip to content

Commit 09043a8

Browse files
committedJan 19, 2020
Split the Component trait into more specific traits
1 parent 0279591 commit 09043a8

25 files changed

+995
-882
lines changed
 

‎palette/src/blend/blend.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use float::Float;
22
use num_traits::{One, Zero};
33

44
use blend::{BlendFunction, PreAlpha};
5-
use {cast, clamp, ComponentWise};
5+
use {clamp, ComponentWise};
66

77
///A trait for colors that can be blended together.
88
///
@@ -353,6 +353,10 @@ where
353353
let one = <Self::Color as ComponentWise>::Scalar::one();
354354
let zero = <Self::Color as ComponentWise>::Scalar::zero();
355355
let two = one + one;
356+
let three = two + one;
357+
let four = two + two;
358+
let twelve = four + four + four;
359+
let sixteen = twelve + four;
356360

357361
let src = self.into_premultiplied();
358362
let dst = other.into_premultiplied();
@@ -369,14 +373,11 @@ where
369373
b * (src.alpha + (two * a - src.alpha) * (one - m))
370374
+ a * (one - dst.alpha)
371375
+ b * (one - src.alpha)
372-
} else if b * cast(4.0) <= dst.alpha {
376+
} else if b * four <= dst.alpha {
373377
let m2 = m * m;
374378
let m3 = m2 * m;
375379

376-
dst.alpha
377-
* (two * a - src.alpha)
378-
* (m3 * cast(16.0) - m2 * cast(12.0) - m * cast(3.0))
379-
+ a
380+
dst.alpha * (two * a - src.alpha) * (m3 * sixteen - m2 * twelve - m * three) + a
380381
- a * dst.alpha
381382
+ b
382383
} else {

‎palette/src/chromatic_adaptation.rs

+41-34
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
//!```
2525
use float::Float;
2626

27-
use {cast, Component, FromColor, IntoColor, Xyz};
27+
use from_f64;
28+
use matrix::{multiply_3x3, multiply_xyz, Mat3};
2829
use white_point::WhitePoint;
29-
use matrix::{multiply_xyz, Mat3, multiply_3x3};
30+
use {FloatComponent, FromColor, IntoColor, Xyz};
3031

3132
///Chromatic adaptation methods implemented in the library
3233
pub enum Method {
@@ -50,7 +51,7 @@ pub struct ConeResponseMatrices<T: Float> {
5051
///one illuminant to another (Swp -> Dwp)
5152
pub trait TransformMatrix<Swp, Dwp, T>
5253
where
53-
T: Component + Float,
54+
T: FloatComponent,
5455
Swp: WhitePoint,
5556
Dwp: WhitePoint,
5657
{
@@ -86,7 +87,7 @@ where
8687

8788
impl<Swp, Dwp, T> TransformMatrix<Swp, Dwp, T> for Method
8889
where
89-
T: Component + Float,
90+
T: FloatComponent,
9091
Swp: WhitePoint,
9192
Dwp: WhitePoint,
9293
{
@@ -95,38 +96,44 @@ where
9596
match *self {
9697
Method::Bradford => {
9798
ConeResponseMatrices::<T> {
98-
ma: [cast(0.8951000), cast(0.2664000), cast(-0.1614000),
99-
cast(-0.7502000), cast(1.7135000), cast(0.0367000),
100-
cast(0.0389000), cast(-0.0685000), cast(1.0296000)
101-
],
102-
inv_ma: [cast(0.9869929), cast(-0.1470543), cast(0.1599627),
103-
cast(0.4323053), cast(0.5183603), cast(0.0492912),
104-
cast(-0.0085287), cast(0.0400428), cast(0.9684867)
105-
],
99+
ma: [
100+
from_f64(0.8951000), from_f64(0.2664000), from_f64(-0.1614000),
101+
from_f64(-0.7502000), from_f64(1.7135000), from_f64(0.0367000),
102+
from_f64(0.0389000), from_f64(-0.0685000), from_f64(1.0296000)
103+
],
104+
inv_ma: [
105+
from_f64(0.9869929), from_f64(-0.1470543), from_f64(0.1599627),
106+
from_f64(0.4323053), from_f64(0.5183603), from_f64(0.0492912),
107+
from_f64(-0.0085287), from_f64(0.0400428), from_f64(0.9684867)
108+
],
106109
}
107110
}
108111
Method::VonKries => {
109112
ConeResponseMatrices::<T> {
110-
ma: [cast(0.4002400), cast(0.7076000), cast(-0.0808100),
111-
cast(-0.2263000), cast(1.1653200), cast(0.0457000),
112-
cast(0.0000000), cast(0.0000000), cast(0.9182200)
113-
],
114-
inv_ma: [cast(1.8599364), cast(-1.1293816), cast(0.2198974),
115-
cast(0.3611914), cast(0.6388125), cast(-0.0000064),
116-
cast(0.0000000), cast(0.0000000), cast(1.0890636)
117-
],
113+
ma: [
114+
from_f64(0.4002400), from_f64(0.7076000), from_f64(-0.0808100),
115+
from_f64(-0.2263000), from_f64(1.1653200), from_f64(0.0457000),
116+
from_f64(0.0000000), from_f64(0.0000000), from_f64(0.9182200)
117+
],
118+
inv_ma: [
119+
from_f64(1.8599364), from_f64(-1.1293816), from_f64(0.2198974),
120+
from_f64(0.3611914), from_f64(0.6388125), from_f64(-0.0000064),
121+
from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0890636)
122+
],
118123
}
119124
}
120125
Method::XyzScaling => {
121126
ConeResponseMatrices::<T> {
122-
ma: [cast(1.0000000), cast(0.0000000), cast(0.0000000),
123-
cast(0.0000000), cast(1.0000000), cast(0.0000000),
124-
cast(0.0000000), cast(0.0000000), cast(1.0000000)
125-
],
126-
inv_ma: [cast(1.0000000), cast(0.0000000), cast(0.0000000),
127-
cast(0.0000000), cast(1.0000000), cast(0.0000000),
128-
cast(0.0000000), cast(0.0000000), cast(1.0000000)
129-
],
127+
ma: [
128+
from_f64(1.0000000), from_f64(0.0000000), from_f64(0.0000000),
129+
from_f64(0.0000000), from_f64(1.0000000), from_f64(0.0000000),
130+
from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0000000)
131+
],
132+
inv_ma: [
133+
from_f64(1.0000000), from_f64(0.0000000), from_f64(0.0000000),
134+
from_f64(0.0000000), from_f64(1.0000000), from_f64(0.0000000),
135+
from_f64(0.0000000), from_f64(0.0000000), from_f64(1.0000000)
136+
],
130137
}
131138
}
132139
}
@@ -139,7 +146,7 @@ where
139146
///Uses the bradford method for conversion by default.
140147
pub trait AdaptFrom<S, Swp, Dwp, T>: Sized
141148
where
142-
T: Component + Float,
149+
T: FloatComponent,
143150
Swp: WhitePoint,
144151
Dwp: WhitePoint,
145152
{
@@ -155,7 +162,7 @@ where
155162

156163
impl<S, D, Swp, Dwp, T> AdaptFrom<S, Swp, Dwp, T> for D
157164
where
158-
T: Component + Float,
165+
T: FloatComponent,
159166
Swp: WhitePoint,
160167
Dwp: WhitePoint,
161168
S: IntoColor<Swp, T>,
@@ -175,7 +182,7 @@ where
175182
///Uses the bradford method for conversion by default.
176183
pub trait AdaptInto<D, Swp, Dwp, T>: Sized
177184
where
178-
T: Component + Float,
185+
T: FloatComponent,
179186
Swp: WhitePoint,
180187
Dwp: WhitePoint,
181188
{
@@ -191,7 +198,7 @@ where
191198

192199
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
193200
where
194-
T: Component + Float,
201+
T: FloatComponent,
195202
Swp: WhitePoint,
196203
Dwp: WhitePoint,
197204
D: AdaptFrom<S, Swp, Dwp, T>,
@@ -204,9 +211,9 @@ where
204211
#[cfg(test)]
205212
mod test {
206213

207-
use Xyz;
208-
use white_point::{D50, D65, A, C};
209214
use super::{AdaptFrom, AdaptInto, Method, TransformMatrix};
215+
use white_point::{A, C, D50, D65};
216+
use Xyz;
210217

211218
#[test]
212219
fn d65_to_d50_matrix_xyz_scaling() {

‎palette/src/component.rs

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
use num_traits::Zero;
2+
3+
use float::Float;
4+
use {clamp, FromF64};
5+
6+
/// Common trait for color components.
7+
pub trait Component: Copy + Zero + PartialOrd {
8+
/// The highest displayable value this component type can reach. Higher
9+
/// values are allowed, but they may be lowered to this before
10+
/// converting to another format.
11+
fn max_intensity() -> Self;
12+
}
13+
14+
/// Common trait for floating point color components.
15+
pub trait FloatComponent: Component + Float + FromF64 {}
16+
17+
impl<T: Component + Float + FromF64> FloatComponent for T {}
18+
19+
macro_rules! impl_float_components {
20+
($($ty: ident),+) => {
21+
$(
22+
impl Component for $ty {
23+
fn max_intensity() -> Self {
24+
1.0
25+
}
26+
}
27+
)*
28+
};
29+
}
30+
31+
impl_float_components!(f32, f64);
32+
33+
macro_rules! impl_uint_components {
34+
($($ty: ident),+) => {
35+
$(
36+
impl Component for $ty {
37+
fn max_intensity() -> Self {
38+
core::$ty::MAX
39+
}
40+
}
41+
)*
42+
};
43+
}
44+
45+
impl_uint_components!(u8, u16, u32, u64, u128);
46+
47+
/// Converts from a color component type, while performing the appropriate scaling, rounding and clamping.
48+
///
49+
/// ```
50+
/// use palette::FromComponent;
51+
///
52+
/// // Scales the value up to u8::MAX while converting.
53+
/// let u8_component = u8::from_component(1.0f32);
54+
/// assert_eq!(u8_component, 255);
55+
/// ```
56+
pub trait FromComponent<T: Component> {
57+
/// Converts `other` into `Self`, while performing the appropriate scaling, rounding and clamping.
58+
fn from_component(other: T) -> Self;
59+
}
60+
61+
impl<T: Component, U: IntoComponent<T> + Component> FromComponent<U> for T {
62+
#[inline]
63+
fn from_component(other: U) -> T {
64+
other.into_component()
65+
}
66+
}
67+
68+
/// Converts into a color component type, while performing the appropriate scaling, rounding and clamping.
69+
///
70+
/// ```
71+
/// use palette::IntoComponent;
72+
///
73+
/// // Scales the value up to u8::MAX while converting.
74+
/// let u8_component: u8 = 1.0f32.into_component();
75+
/// assert_eq!(u8_component, 255);
76+
/// ```
77+
pub trait IntoComponent<T: Component> {
78+
/// Converts `self` into `T`, while performing the appropriate scaling, rounding and clamping.
79+
fn into_component(self) -> T;
80+
}
81+
82+
impl<T: Component> IntoComponent<T> for T {
83+
#[inline]
84+
fn into_component(self) -> T {
85+
self
86+
}
87+
}
88+
89+
macro_rules! convert_float_to_uint {
90+
($float: ident; direct ($($direct_target: ident),+); $(via $temporary: ident ($($target: ident),+);)*) => {
91+
$(
92+
impl IntoComponent<$direct_target> for $float {
93+
#[inline]
94+
fn into_component(self) -> $direct_target {
95+
let max = $direct_target::max_intensity() as $float;
96+
let scaled = self * max;
97+
clamp(scaled.round(), 0.0, max) as $direct_target
98+
}
99+
}
100+
)+
101+
102+
$(
103+
$(
104+
impl IntoComponent<$target> for $float {
105+
#[inline]
106+
fn into_component(self) -> $target {
107+
let max = $target::max_intensity() as $temporary;
108+
let scaled = self as $temporary * max;
109+
clamp(scaled.round(), 0.0, max) as $target
110+
}
111+
}
112+
)+
113+
)*
114+
};
115+
}
116+
117+
macro_rules! convert_uint_to_float {
118+
($uint: ident; $(via $temporary: ident ($($target: ident),+);)*) => {
119+
$(
120+
$(
121+
impl IntoComponent<$target> for $uint {
122+
#[inline]
123+
fn into_component(self) -> $target {
124+
let max = $uint::max_intensity() as $temporary;
125+
let scaled = self as $temporary / max;
126+
scaled as $target
127+
}
128+
}
129+
)+
130+
)*
131+
};
132+
}
133+
134+
macro_rules! convert_uint_to_uint {
135+
($uint: ident; $(via $temporary: ident ($($target: ident),+);)*) => {
136+
$(
137+
$(
138+
impl IntoComponent<$target> for $uint {
139+
#[inline]
140+
fn into_component(self) -> $target {
141+
let target_max = $target::max_intensity() as $temporary;
142+
let own_max = $uint::max_intensity() as $temporary;
143+
let scaled = (self as $temporary / own_max) * target_max;
144+
clamp(scaled.round(), 0.0, target_max) as $target
145+
}
146+
}
147+
)+
148+
)*
149+
};
150+
}
151+
152+
impl IntoComponent<f64> for f32 {
153+
#[inline]
154+
fn into_component(self) -> f64 {
155+
self as f64
156+
}
157+
}
158+
convert_float_to_uint!(f32; direct (u8, u16); via f64 (u32, u64, u128););
159+
160+
impl IntoComponent<f32> for f64 {
161+
#[inline]
162+
fn into_component(self) -> f32 {
163+
self as f32
164+
}
165+
}
166+
convert_float_to_uint!(f64; direct (u8, u16, u32, u64, u128););
167+
168+
convert_uint_to_float!(u8; via f32 (f32); via f64 (f64););
169+
convert_uint_to_uint!(u8; via f32 (u16); via f64 (u32, u64, u128););
170+
171+
convert_uint_to_float!(u16; via f32 (f32); via f64 (f64););
172+
convert_uint_to_uint!(u16; via f32 (u8); via f64 (u32, u64, u128););
173+
174+
convert_uint_to_float!(u32; via f64 (f32, f64););
175+
convert_uint_to_uint!(u32; via f64 (u8, u16, u64, u128););
176+
177+
convert_uint_to_float!(u64; via f64 (f32, f64););
178+
convert_uint_to_uint!(u64; via f64 (u8, u16, u32, u128););
179+
180+
convert_uint_to_float!(u128; via f64 (f32, f64););
181+
convert_uint_to_uint!(u128; via f64 (u8, u16, u32, u64););

0 commit comments

Comments
 (0)
Please sign in to comment.