1
1
//!Types for interpolation between multiple colors.
2
2
3
- use num:: traits :: Float ;
3
+ use num:: { Float , One , Zero , NumCast } ;
4
4
use std:: cmp:: max;
5
5
6
6
use Mix ;
@@ -14,18 +14,18 @@ use Mix;
14
14
///the domain of the gradient will have the same color as the closest control
15
15
///point.
16
16
#[ derive( Clone , Debug ) ]
17
- pub struct Gradient < T : Float , C : Mix < T > + Clone > ( Vec < ( T , C ) > ) ;
17
+ pub struct Gradient < C : Mix + Clone > ( Vec < ( C :: Scalar , C ) > ) ;
18
18
19
- impl < T : Float , C : Mix < T > + Clone > Gradient < T , C > {
19
+ impl < C : Mix + Clone > Gradient < C > {
20
20
///Create a gradient of evenly spaced colors with the domain [0.0, 1.0].
21
21
///There must be at least one color.
22
- pub fn new < I : IntoIterator < Item = C > > ( colors : I ) -> Gradient < T , C > {
23
- let mut points: Vec < _ > = colors. into_iter ( ) . map ( |c| ( T :: zero ( ) , c) ) . collect ( ) ;
22
+ pub fn new < I : IntoIterator < Item = C > > ( colors : I ) -> Gradient < C > {
23
+ let mut points: Vec < _ > = colors. into_iter ( ) . map ( |c| ( C :: Scalar :: zero ( ) , c) ) . collect ( ) ;
24
24
assert ! ( points. len( ) > 0 ) ;
25
- let step_size = T :: one ( ) / T :: from ( max ( points. len ( ) - 1 , 1 ) as f64 ) . unwrap ( ) ;
25
+ let step_size = C :: Scalar :: one ( ) / < C :: Scalar as NumCast > :: from ( max ( points. len ( ) - 1 , 1 ) as f64 ) . unwrap ( ) ;
26
26
27
27
for ( i, & mut ( ref mut p, _) ) in points. iter_mut ( ) . enumerate ( ) {
28
- * p = T :: from ( i) . unwrap ( ) * step_size;
28
+ * p = < C :: Scalar as NumCast > :: from ( i) . unwrap ( ) * step_size;
29
29
}
30
30
31
31
Gradient ( points)
@@ -34,7 +34,7 @@ impl<T: Float, C: Mix<T> + Clone> Gradient<T, C> {
34
34
///Create a gradient of colors with custom spacing and domain. There must be
35
35
///at least one color and they are expected to be ordered by their
36
36
///position value.
37
- pub fn with_domain ( colors : Vec < ( T , C ) > ) -> Gradient < T , C > {
37
+ pub fn with_domain ( colors : Vec < ( C :: Scalar , C ) > ) -> Gradient < C > {
38
38
assert ! ( colors. len( ) > 0 ) ;
39
39
40
40
//Maybe sort the colors?
@@ -43,7 +43,7 @@ impl<T: Float, C: Mix<T> + Clone> Gradient<T, C> {
43
43
44
44
///Get a color from the gradient. The color of the closest control point
45
45
///will be returned if `i` is outside the domain.
46
- pub fn get ( & self , i : T ) -> C {
46
+ pub fn get ( & self , i : C :: Scalar ) -> C {
47
47
let & ( mut min, ref min_color) = self . 0 . get ( 0 ) . expect ( "a Gradient must contain at least one color" ) ;
48
48
let mut min_color = min_color;
49
49
let mut min_index = 0 ;
@@ -82,7 +82,7 @@ impl<T: Float, C: Mix<T> + Clone> Gradient<T, C> {
82
82
}
83
83
84
84
///Take `n` evenly spaced colors from the gradient, as an iterator.
85
- pub fn take ( & self , n : usize ) -> Take < T , C > {
85
+ pub fn take ( & self , n : usize ) -> Take < C > {
86
86
let ( min, max) = self . domain ( ) ;
87
87
88
88
Take {
@@ -95,36 +95,36 @@ impl<T: Float, C: Mix<T> + Clone> Gradient<T, C> {
95
95
}
96
96
97
97
///Slice this gradient to limit its domain.
98
- pub fn slice < R : Into < Range < T > > > ( & self , range : R ) -> Slice < T , C > {
98
+ pub fn slice < R : Into < Range < C :: Scalar > > > ( & self , range : R ) -> Slice < C > {
99
99
Slice {
100
100
gradient : self ,
101
101
range : range. into ( ) ,
102
102
}
103
103
}
104
104
105
105
///Get the limits of this gradient's domain.
106
- pub fn domain ( & self ) -> ( T , T ) {
106
+ pub fn domain ( & self ) -> ( C :: Scalar , C :: Scalar ) {
107
107
let & ( min, _) = self . 0 . get ( 0 ) . expect ( "a Gradient must contain at least one color" ) ;
108
108
let & ( max, _) = self . 0 . last ( ) . expect ( "a Gradient must contain at least one color" ) ;
109
109
( min, max)
110
110
}
111
111
}
112
112
113
113
///An iterator over interpolated colors.
114
- pub struct Take < ' a , T : Float + ' a , C : Mix < T > + Clone + ' a > {
115
- gradient : MaybeSlice < ' a , T , C > ,
116
- from : T ,
117
- diff : T ,
114
+ pub struct Take < ' a , C : Mix + Clone + ' a > {
115
+ gradient : MaybeSlice < ' a , C > ,
116
+ from : C :: Scalar ,
117
+ diff : C :: Scalar ,
118
118
len : usize ,
119
119
current : usize ,
120
120
}
121
121
122
- impl < ' a , T : Float , C : Mix < T > + Clone > Iterator for Take < ' a , T , C > {
122
+ impl < ' a , C : Mix + Clone > Iterator for Take < ' a , C > {
123
123
type Item = C ;
124
124
125
125
fn next ( & mut self ) -> Option < C > {
126
126
if self . current < self . len {
127
- let i = self . from + T :: from ( self . current ) . unwrap ( ) * ( self . diff / T :: from ( self . len ) . unwrap ( ) ) ;
127
+ let i = self . from + < C :: Scalar as NumCast > :: from ( self . current ) . unwrap ( ) * ( self . diff / < C :: Scalar as NumCast > :: from ( self . len ) . unwrap ( ) ) ;
128
128
self . current += 1 ;
129
129
Some ( self . gradient . get ( i) )
130
130
} else {
@@ -137,25 +137,25 @@ impl<'a, T: Float, C: Mix<T> + Clone> Iterator for Take<'a, T, C> {
137
137
}
138
138
}
139
139
140
- impl < ' a , T : Float , C : Mix < T > + Clone > ExactSizeIterator for Take < ' a , T , C > { }
140
+ impl < ' a , C : Mix + Clone > ExactSizeIterator for Take < ' a , C > { }
141
141
142
142
143
143
///A slice of a Gradient that limits its domain.
144
144
#[ derive( Clone , Debug ) ]
145
- pub struct Slice < ' a , T : Float + ' a , C : Mix < T > + Clone + ' a > {
146
- gradient : & ' a Gradient < T , C > ,
147
- range : Range < T > ,
145
+ pub struct Slice < ' a , C : Mix + Clone + ' a > {
146
+ gradient : & ' a Gradient < C > ,
147
+ range : Range < C :: Scalar > ,
148
148
}
149
149
150
- impl < ' a , T : Float , C : Mix < T > + Clone > Slice < ' a , T , C > {
150
+ impl < ' a , C : Mix + Clone > Slice < ' a , C > {
151
151
///Get a color from the gradient slice. The color of the closest domain
152
152
///limit will be returned if `i` is outside the domain.
153
- pub fn get ( & self , i : T ) -> C {
153
+ pub fn get ( & self , i : C :: Scalar ) -> C {
154
154
self . gradient . get ( self . range . clamp ( i) )
155
155
}
156
156
157
157
///Take `n` evenly spaced colors from the gradient slice, as an iterator.
158
- pub fn take ( & self , n : usize ) -> Take < T , C > {
158
+ pub fn take ( & self , n : usize ) -> Take < C > {
159
159
let ( min, max) = self . domain ( ) ;
160
160
161
161
Take {
@@ -169,15 +169,15 @@ impl<'a, T: Float, C: Mix<T> + Clone> Slice<'a, T, C> {
169
169
170
170
///Slice this gradient slice to further limit its domain. Ranges outside
171
171
///the domain will be clamped to the nearest domain limit.
172
- pub fn slice < R : Into < Range < T > > > ( & self , range : R ) -> Slice < T , C > {
172
+ pub fn slice < R : Into < Range < C :: Scalar > > > ( & self , range : R ) -> Slice < C > {
173
173
Slice {
174
174
gradient : self . gradient ,
175
175
range : self . range . constrain ( & range. into ( ) )
176
176
}
177
177
}
178
178
179
179
///Get the limits of this gradient slice's domain.
180
- pub fn domain ( & self ) -> ( T , T ) {
180
+ pub fn domain ( & self ) -> ( C :: Scalar , C :: Scalar ) {
181
181
if let Range { from : Some ( from) , to : Some ( to) } = self . range {
182
182
( from, to)
183
183
} else {
@@ -273,13 +273,13 @@ impl<T: Float> From<::std::ops::RangeFull> for Range<T> {
273
273
}
274
274
}
275
275
276
- enum MaybeSlice < ' a , T : Float + ' a , C : Mix < T > + Clone + ' a > {
277
- NotSlice ( & ' a Gradient < T , C > ) ,
278
- Slice ( Slice < ' a , T , C > ) ,
276
+ enum MaybeSlice < ' a , C : Mix + Clone + ' a > {
277
+ NotSlice ( & ' a Gradient < C > ) ,
278
+ Slice ( Slice < ' a , C > ) ,
279
279
}
280
280
281
- impl < ' a , T : Float , C : Mix < T > + Clone > MaybeSlice < ' a , T , C > {
282
- fn get ( & self , i : T ) -> C {
281
+ impl < ' a , C : Mix + Clone > MaybeSlice < ' a , C > {
282
+ fn get ( & self , i : C :: Scalar ) -> C {
283
283
match * self {
284
284
MaybeSlice :: NotSlice ( g) => g. get ( i) ,
285
285
MaybeSlice :: Slice ( ref s) => s. get ( i) ,
0 commit comments