@@ -22,27 +22,45 @@ use std::convert;
22
22
use std:: hash:: { Hash , Hasher } ;
23
23
use std:: mem;
24
24
25
+ /// A gradient, either linear or radial.
25
26
#[ derive( Clone , PartialEq , Debug ) ]
26
27
pub struct Gradient {
28
+ /// Information specific to the type of gradient (linear or radial).
27
29
pub geometry : GradientGeometry ,
28
30
stops : Vec < ColorStop > ,
31
+ /// What should be rendered upon reaching the end of the color stops.
29
32
pub wrap : GradientWrap ,
30
33
}
31
34
35
+ /// A color in a gradient. Points in a gradient between two stops interpolate linearly between the
36
+ /// stops.
32
37
#[ derive( Clone , Copy , PartialEq , Debug ) ]
33
38
pub struct ColorStop {
39
+ /// The offset of the color stop, between 0.0 and 1.0 inclusive. The value 0.0 represents the
40
+ /// start of the gradient, and 1.0 represents the end.
34
41
pub offset : f32 ,
42
+ /// The color of the gradient stop.
35
43
pub color : ColorU ,
36
44
}
37
45
46
+ /// The type of gradient: linear or radial.
38
47
#[ derive( Clone , PartialEq , Debug ) ]
39
48
pub enum GradientGeometry {
49
+ /// A linear gradient that follows a line.
50
+ ///
51
+ /// The line is in scene coordinates, not relative to the bounding box of the path.
40
52
Linear ( LineSegment2F ) ,
53
+ /// A radial gradient that radiates outward from a line connecting two circles (or from one
54
+ /// circle).
41
55
Radial {
42
- /// The line that connects the two circles. It may have zero length for simple radial
43
- /// gradients.
56
+ /// The line that connects the centers of the two circles. For single-circle radial
57
+ /// gradients (the common case), this line has zero length, with start point and endpoint
58
+ /// both at the circle's center point.
59
+ ///
60
+ /// This is in scene coordinates, not relative to the bounding box of the path.
44
61
line : LineSegment2F ,
45
- /// The radii of the two circles. The first value may be zero.
62
+ /// The radii of the two circles. The first value may be zero to start the gradient at the
63
+ /// center of the circle.
46
64
radii : F32x2 ,
47
65
/// Transform from radial gradient space into screen space.
48
66
///
@@ -52,9 +70,13 @@ pub enum GradientGeometry {
52
70
}
53
71
}
54
72
73
+ /// What should be rendered outside the color stops.
55
74
#[ derive( Clone , Copy , PartialEq , Debug ) ]
56
75
pub enum GradientWrap {
76
+ /// The area before the gradient is filled with the color of the first stop, and the area after
77
+ /// the gradient is filled with the color of the last stop.
57
78
Clamp ,
79
+ /// The gradient repeats indefinitely.
58
80
Repeat ,
59
81
}
60
82
@@ -97,6 +119,9 @@ impl Hash for ColorStop {
97
119
}
98
120
99
121
impl Gradient {
122
+ /// Creates a new linear gradient with the given line.
123
+ ///
124
+ /// The line is in scene coordinates, not relative to the bounding box of the current path.
100
125
#[ inline]
101
126
pub fn linear ( line : LineSegment2F ) -> Gradient {
102
127
Gradient {
@@ -106,11 +131,19 @@ impl Gradient {
106
131
}
107
132
}
108
133
134
+ /// A convenience method equivalent to `Gradient::linear(LineSegment2F::new(from, to))`.
109
135
#[ inline]
110
136
pub fn linear_from_points ( from : Vector2F , to : Vector2F ) -> Gradient {
111
137
Gradient :: linear ( LineSegment2F :: new ( from, to) )
112
138
}
113
139
140
+ /// Creates a new radial gradient from a line connecting the centers of two circles with the
141
+ /// given radii, or a point at the center of one circle.
142
+ ///
143
+ /// To create a radial gradient with a single circle (the common case), pass a `Vector2F`
144
+ /// representing the center of the circle for `line`; otherwise, to create a radial gradient
145
+ /// with two circles, pass a `LineSegment2F`. To start the gradient at the center of the
146
+ /// circle, pass zero for the first radius.
114
147
#[ inline]
115
148
pub fn radial < L > ( line : L , radii : F32x2 ) -> Gradient where L : RadialGradientLine {
116
149
let transform = Transform2F :: default ( ) ;
@@ -121,6 +154,7 @@ impl Gradient {
121
154
}
122
155
}
123
156
157
+ /// Adds a new color stop to the radial gradient.
124
158
#[ inline]
125
159
pub fn add ( & mut self , stop : ColorStop ) {
126
160
let index = self . stops . binary_search_by ( |other| {
@@ -129,22 +163,28 @@ impl Gradient {
129
163
self . stops . insert ( index, stop) ;
130
164
}
131
165
132
- /// A convenience method to add a color stop.
166
+ /// A convenience method equivalent to
167
+ /// `gradient.add_color_stop(ColorStop::new(color, offset))`.
133
168
#[ inline]
134
169
pub fn add_color_stop ( & mut self , color : ColorU , offset : f32 ) {
135
170
self . add ( ColorStop :: new ( color, offset) )
136
171
}
137
172
173
+ /// Returns the list of color stops in this gradient.
138
174
#[ inline]
139
175
pub fn stops ( & self ) -> & [ ColorStop ] {
140
176
& self . stops
141
177
}
142
178
179
+ /// Returns a mutable version of the list of color stops in this gradient.
143
180
#[ inline]
144
181
pub fn stops_mut ( & mut self ) -> & mut [ ColorStop ] {
145
182
& mut self . stops
146
183
}
147
184
185
+ /// Returns the value of the gradient at offset `t`, which will be clamped between 0.0 and 1.0.
186
+ ///
187
+ /// FIXME(pcwalton): This should probably take `wrap` into account…
148
188
pub fn sample ( & self , mut t : f32 ) -> ColorU {
149
189
if self . stops . is_empty ( ) {
150
190
return ColorU :: transparent_black ( ) ;
@@ -170,16 +210,23 @@ impl Gradient {
170
210
lower_stop. color . to_f32 ( ) . lerp ( upper_stop. color . to_f32 ( ) , ratio) . to_u8 ( )
171
211
}
172
212
213
+ /// Returns true if all colors of all stops in this gradient are opaque (alpha is 1.0).
173
214
#[ inline]
174
215
pub fn is_opaque ( & self ) -> bool {
175
216
self . stops . iter ( ) . all ( |stop| stop. color . is_opaque ( ) )
176
217
}
177
218
219
+ /// Returns true if all colors of all stops in this gradient are fully transparent (alpha is
220
+ /// 0.0).
178
221
#[ inline]
179
222
pub fn is_fully_transparent ( & self ) -> bool {
180
223
self . stops . iter ( ) . all ( |stop| stop. color . is_fully_transparent ( ) )
181
224
}
182
225
226
+ /// Applies the given affine transform to this gradient.
227
+ ///
228
+ /// FIXME(pcwalton): This isn't correct for radial gradients, as transforms can transform the
229
+ /// circles into ellipses…
183
230
pub fn apply_transform ( & mut self , new_transform : Transform2F ) {
184
231
if new_transform. is_identity ( ) {
185
232
return ;
@@ -195,13 +242,16 @@ impl Gradient {
195
242
}
196
243
197
244
impl ColorStop {
245
+ /// Creates a new color stop from a color and offset between 0.0 and 1.0 inclusive.
198
246
#[ inline]
199
247
pub fn new ( color : ColorU , offset : f32 ) -> ColorStop {
200
248
ColorStop { color, offset }
201
249
}
202
250
}
203
251
252
+ /// Allows `Gradient::radial` to be called with either a `LineSegment2F` or a `Vector2F`.
204
253
pub trait RadialGradientLine {
254
+ /// Represents this value as a line.
205
255
fn to_line ( self ) -> LineSegment2F ;
206
256
}
207
257
0 commit comments