1#![allow(deprecated)]
2
3use crate::{
4 gradient, scalar, shaders, Color, Color4f, ColorSpace, Matrix, Point, Shader, TileMode,
5};
6
7pub use gradient::{interpolation, Colors as GradientColors, Gradient, Interpolation};
8
9impl From<Flags> for Interpolation {
10 fn from(flags: Flags) -> Self {
11 let in_premul = if flags.contains(Flags::INTERPOLATE_COLORS_IN_PREMUL) {
12 interpolation::InPremul::Yes
13 } else {
14 interpolation::InPremul::No
15 };
16 Self {
17 in_premul,
18 color_space: interpolation::ColorSpace::Destination,
19 hue_method: interpolation::HueMethod::Shorter,
20 }
21 }
22}
23
24impl Shader {
25 #[deprecated(
26 since = "0.93.0",
27 note = "Use gradient::shaders::linear_gradient() instead"
28 )]
29 pub fn linear_gradient<'a>(
30 points: (impl Into<Point>, impl Into<Point>),
31 colors: impl Into<GradientShaderColors<'a>>,
32 pos: impl Into<Option<&'a [scalar]>>,
33 mode: TileMode,
34 flags: impl Into<Option<Flags>>,
35 local_matrix: impl Into<Option<&'a Matrix>>,
36 ) -> Option<Self> {
37 linear(points, colors, pos, mode, flags, local_matrix)
38 }
39
40 #[deprecated(
41 since = "0.93.0",
42 note = "Use gradient::shaders::linear_gradient() instead"
43 )]
44 pub fn linear_gradient_with_interpolation<'a>(
45 points: (impl Into<Point>, impl Into<Point>),
46 colors: (&'a [Color4f], impl Into<Option<ColorSpace>>),
47 pos: impl Into<Option<&'a [scalar]>>,
48 mode: TileMode,
49 interpolation: impl Into<Interpolation>,
50 local_matrix: impl Into<Option<&'a Matrix>>,
51 ) -> Option<Self> {
52 linear_with_interpolation(points, colors, pos, mode, interpolation, local_matrix)
53 }
54
55 #[deprecated(
56 since = "0.93.0",
57 note = "Use gradient::shaders::radial_gradient() instead"
58 )]
59 pub fn radial_gradient<'a>(
60 center: impl Into<Point>,
61 radius: scalar,
62 colors: impl Into<GradientShaderColors<'a>>,
63 pos: impl Into<Option<&'a [scalar]>>,
64 mode: TileMode,
65 flags: impl Into<Option<self::Flags>>,
66 local_matrix: impl Into<Option<&'a Matrix>>,
67 ) -> Option<Self> {
68 radial(center, radius, colors, pos, mode, flags, local_matrix)
69 }
70
71 #[deprecated(
72 since = "0.93.0",
73 note = "Use gradient::shaders::radial_gradient() instead"
74 )]
75 #[allow(clippy::too_many_arguments)]
76 pub fn radial_gradient_with_interpolation<'a>(
77 center_and_radius: (impl Into<Point>, scalar),
78 colors: (&'a [Color4f], impl Into<Option<ColorSpace>>),
79 pos: impl Into<Option<&'a [scalar]>>,
80 mode: TileMode,
81 interpolation: impl Into<Interpolation>,
82 local_matrix: impl Into<Option<&'a Matrix>>,
83 ) -> Option<Shader> {
84 radial_with_interpolation(
85 center_and_radius,
86 colors,
87 pos,
88 mode,
89 interpolation,
90 local_matrix,
91 )
92 }
93
94 #[deprecated(
95 since = "0.93.0",
96 note = "Use gradient::shaders::two_point_conical_gradient() instead"
97 )]
98 #[allow(clippy::too_many_arguments)]
99 pub fn two_point_conical_gradient<'a>(
100 start: impl Into<Point>,
101 start_radius: scalar,
102 end: impl Into<Point>,
103 end_radius: scalar,
104 colors: impl Into<GradientShaderColors<'a>>,
105 pos: impl Into<Option<&'a [scalar]>>,
106 mode: TileMode,
107 flags: impl Into<Option<self::Flags>>,
108 local_matrix: impl Into<Option<&'a Matrix>>,
109 ) -> Option<Self> {
110 two_point_conical(
111 start,
112 start_radius,
113 end,
114 end_radius,
115 colors,
116 pos,
117 mode,
118 flags,
119 local_matrix,
120 )
121 }
122
123 #[deprecated(
124 since = "0.93.0",
125 note = "Use gradient::shaders::two_point_conical_gradient() instead"
126 )]
127 pub fn two_point_conical_gradient_with_interpolation<'a>(
128 start_and_radius: (impl Into<Point>, scalar),
129 end_and_radius: (impl Into<Point>, scalar),
130 colors: (&'a [Color4f], impl Into<Option<ColorSpace>>),
131 pos: impl Into<Option<&'a [scalar]>>,
132 mode: TileMode,
133 interpolation: impl Into<Interpolation>,
134 local_matrix: impl Into<Option<&'a Matrix>>,
135 ) -> Option<Shader> {
136 two_point_conical_with_interpolation(
137 start_and_radius,
138 end_and_radius,
139 colors,
140 pos,
141 mode,
142 interpolation,
143 local_matrix,
144 )
145 }
146
147 #[deprecated(
148 since = "0.93.0",
149 note = "Use gradient::shaders::sweep_gradient() instead"
150 )]
151 pub fn sweep_gradient<'a>(
152 center: impl Into<Point>,
153 colors: impl Into<GradientShaderColors<'a>>,
154 pos: impl Into<Option<&'a [scalar]>>,
155 mode: TileMode,
156 angles: impl Into<Option<(scalar, scalar)>>,
157 flags: impl Into<Option<self::Flags>>,
158 local_matrix: impl Into<Option<&'a Matrix>>,
159 ) -> Option<Self> {
160 sweep(center, colors, pos, mode, angles, flags, local_matrix)
161 }
162
163 #[deprecated(
164 since = "0.93.0",
165 note = "Use gradient::shaders::sweep_gradient() instead"
166 )]
167 pub fn sweep_gradient_with_interpolation<'a>(
168 center: impl Into<Point>,
169 colors: (&'a [Color4f], impl Into<Option<ColorSpace>>),
170 pos: impl Into<Option<&'a [scalar]>>,
171 mode: TileMode,
172 angles: impl Into<Option<(scalar, scalar)>>,
173 interpolation: impl Into<Interpolation>,
174 local_matrix: impl Into<Option<&'a Matrix>>,
175 ) -> Option<Shader> {
176 sweep_with_interpolation(
177 center,
178 colors,
179 pos,
180 mode,
181 angles,
182 interpolation,
183 local_matrix,
184 )
185 }
186}
187
188bitflags! {
189 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
190 pub struct Flags: u32 {
191 const INTERPOLATE_COLORS_IN_PREMUL = 1 << 0;
192 }
193}
194
195impl Default for self::Flags {
196 fn default() -> Self {
197 Self::empty()
198 }
199}
200
201pub fn linear<'a>(
202 points: (impl Into<Point>, impl Into<Point>),
203 colors: impl Into<GradientShaderColors<'a>>,
204 pos: impl Into<Option<&'a [scalar]>>,
205 mode: TileMode,
206 flags: impl Into<Option<Flags>>,
207 local_matrix: impl Into<Option<&'a Matrix>>,
208) -> Option<Shader> {
209 let colors = colors.into();
210 let pos = pos.into();
211 let flags = flags.into().unwrap_or_default();
212
213 match colors {
214 GradientShaderColors::Colors(colors) => {
215 let colors4f: Vec<Color4f> = colors.iter().map(|c| Color4f::from(*c)).collect();
217 let grad_colors = GradientColors::new(&colors4f, pos, mode, None);
218 let grad = Gradient::new(grad_colors, flags);
219 shaders::linear_gradient(points, &grad, local_matrix)
220 }
221 GradientShaderColors::ColorsInSpace(colors, color_space) => linear_with_interpolation(
222 points,
223 (colors, color_space),
224 pos,
225 mode,
226 flags,
227 local_matrix,
228 ),
229 }
230}
231
232pub fn linear_with_interpolation<'a>(
233 points: (impl Into<Point>, impl Into<Point>),
234 (colors, color_space): (&'a [Color4f], impl Into<Option<ColorSpace>>),
235 pos: impl Into<Option<&'a [scalar]>>,
236 mode: TileMode,
237 interpolation: impl Into<Interpolation>,
238 local_matrix: impl Into<Option<&'a Matrix>>,
239) -> Option<Shader> {
240 let pos = pos.into();
241 let color_space = color_space.into();
242 let grad_colors = GradientColors::new(colors, pos, mode, color_space);
243 let grad = Gradient::new(grad_colors, interpolation);
244 shaders::linear_gradient(points, &grad, local_matrix)
245}
246
247pub fn radial<'a>(
248 center: impl Into<Point>,
249 radius: scalar,
250 colors: impl Into<GradientShaderColors<'a>>,
251 pos: impl Into<Option<&'a [scalar]>>,
252 mode: TileMode,
253 flags: impl Into<Option<self::Flags>>,
254 local_matrix: impl Into<Option<&'a Matrix>>,
255) -> Option<Shader> {
256 let colors = colors.into();
257 let pos = pos.into();
258 let flags = flags.into().unwrap_or_default();
259
260 match colors {
261 GradientShaderColors::Colors(colors) => {
262 let colors4f: Vec<Color4f> = colors.iter().map(|c| Color4f::from(*c)).collect();
263 let grad_colors = GradientColors::new(&colors4f, pos, mode, None);
264 let grad = Gradient::new(grad_colors, flags);
265 shaders::radial_gradient((center, radius), &grad, local_matrix)
266 }
267 GradientShaderColors::ColorsInSpace(colors, color_space) => radial_with_interpolation(
268 (center, radius),
269 (colors, color_space),
270 pos,
271 mode,
272 flags,
273 local_matrix,
274 ),
275 }
276}
277
278pub fn radial_with_interpolation<'a>(
279 (center, radius): (impl Into<Point>, scalar),
280 (colors, color_space): (&'a [Color4f], impl Into<Option<ColorSpace>>),
281 pos: impl Into<Option<&'a [scalar]>>,
282 mode: TileMode,
283 interpolation: impl Into<Interpolation>,
284 local_matrix: impl Into<Option<&'a Matrix>>,
285) -> Option<Shader> {
286 let pos = pos.into();
287 let color_space = color_space.into();
288 let grad_colors = GradientColors::new(colors, pos, mode, color_space);
289 let grad = Gradient::new(grad_colors, interpolation);
290 shaders::radial_gradient((center, radius), &grad, local_matrix)
291}
292
293#[allow(clippy::too_many_arguments)]
294pub fn two_point_conical<'a>(
295 start: impl Into<Point>,
296 start_radius: scalar,
297 end: impl Into<Point>,
298 end_radius: scalar,
299 colors: impl Into<GradientShaderColors<'a>>,
300 pos: impl Into<Option<&'a [scalar]>>,
301 mode: TileMode,
302 flags: impl Into<Option<self::Flags>>,
303 local_matrix: impl Into<Option<&'a Matrix>>,
304) -> Option<Shader> {
305 let colors = colors.into();
306 let pos = pos.into();
307 let flags = flags.into().unwrap_or_default();
308
309 match colors {
310 GradientShaderColors::Colors(colors) => {
311 let colors4f: Vec<Color4f> = colors.iter().map(|c| Color4f::from(*c)).collect();
312 let grad_colors = GradientColors::new(&colors4f, pos, mode, None);
313 let grad = Gradient::new(grad_colors, flags);
314 shaders::two_point_conical_gradient(
315 (start, start_radius),
316 (end, end_radius),
317 &grad,
318 local_matrix,
319 )
320 }
321 GradientShaderColors::ColorsInSpace(colors, color_space) => {
322 two_point_conical_with_interpolation(
323 (start, start_radius),
324 (end, end_radius),
325 (colors, color_space),
326 pos,
327 mode,
328 flags,
329 local_matrix,
330 )
331 }
332 }
333}
334
335pub fn two_point_conical_with_interpolation<'a>(
336 (start, start_radius): (impl Into<Point>, scalar),
337 (end, end_radius): (impl Into<Point>, scalar),
338 (colors, color_space): (&'a [Color4f], impl Into<Option<ColorSpace>>),
339 pos: impl Into<Option<&'a [scalar]>>,
340 mode: TileMode,
341 interpolation: impl Into<Interpolation>,
342 local_matrix: impl Into<Option<&'a Matrix>>,
343) -> Option<Shader> {
344 let pos = pos.into();
345 let color_space = color_space.into();
346 let grad_colors = GradientColors::new(colors, pos, mode, color_space);
347 let grad = Gradient::new(grad_colors, interpolation);
348 shaders::two_point_conical_gradient(
349 (start, start_radius),
350 (end, end_radius),
351 &grad,
352 local_matrix,
353 )
354}
355
356pub fn sweep<'a>(
357 center: impl Into<Point>,
358 colors: impl Into<GradientShaderColors<'a>>,
359 pos: impl Into<Option<&'a [scalar]>>,
360 mode: TileMode,
361 angles: impl Into<Option<(scalar, scalar)>>,
362 flags: impl Into<Option<self::Flags>>,
363 local_matrix: impl Into<Option<&'a Matrix>>,
364) -> Option<Shader> {
365 let colors = colors.into();
366 let pos = pos.into();
367 let angles = angles.into();
368 let flags = flags.into().unwrap_or_default();
369
370 let (start_angle, end_angle) = (
371 angles.map(|a| a.0).unwrap_or(0.0),
372 angles.map(|a| a.1).unwrap_or(360.0),
373 );
374
375 match colors {
376 GradientShaderColors::Colors(colors) => {
377 let colors4f: Vec<Color4f> = colors.iter().map(|c| Color4f::from(*c)).collect();
378 let grad_colors = GradientColors::new(&colors4f, pos, mode, None);
379 let grad = Gradient::new(grad_colors, flags);
380 shaders::sweep_gradient(center, (start_angle, end_angle), &grad, local_matrix)
381 }
382 GradientShaderColors::ColorsInSpace(colors, color_space) => sweep_with_interpolation(
383 center,
384 (colors, color_space),
385 pos,
386 mode,
387 angles,
388 flags,
389 local_matrix,
390 ),
391 }
392}
393
394pub fn sweep_with_interpolation<'a>(
395 center: impl Into<Point>,
396 (colors, color_space): (&'a [Color4f], impl Into<Option<ColorSpace>>),
397 pos: impl Into<Option<&'a [scalar]>>,
398 mode: TileMode,
399 angles: impl Into<Option<(scalar, scalar)>>,
400 interpolation: impl Into<Interpolation>,
401 local_matrix: impl Into<Option<&'a Matrix>>,
402) -> Option<Shader> {
403 let pos = pos.into();
404 let angles = angles.into();
405 let color_space = color_space.into();
406
407 let (start_angle, end_angle) = (
408 angles.map(|a| a.0).unwrap_or(0.0),
409 angles.map(|a| a.1).unwrap_or(360.0),
410 );
411
412 let grad_colors = GradientColors::new(colors, pos, mode, color_space);
413 let grad = Gradient::new(grad_colors, interpolation);
414 shaders::sweep_gradient(center, (start_angle, end_angle), &grad, local_matrix)
415}
416
417#[derive(Debug)]
421pub enum GradientShaderColors<'a> {
422 Colors(&'a [Color]),
423 ColorsInSpace(&'a [Color4f], Option<ColorSpace>),
424}
425
426impl GradientShaderColors<'_> {
427 pub fn len(&self) -> usize {
428 match self {
429 GradientShaderColors::Colors(colors) => colors.len(),
430 GradientShaderColors::ColorsInSpace(colors, _) => colors.len(),
431 }
432 }
433
434 pub fn is_empty(&self) -> bool {
436 self.len() == 0
437 }
438}
439
440impl<'a> From<&'a [Color]> for GradientShaderColors<'a> {
441 fn from(colors: &'a [Color]) -> Self {
442 GradientShaderColors::<'a>::Colors(colors)
443 }
444}
445
446impl<'a> From<(&'a [Color4f], ColorSpace)> for GradientShaderColors<'a> {
447 fn from(c: (&'a [Color4f], ColorSpace)) -> Self {
448 GradientShaderColors::<'a>::ColorsInSpace(c.0, Some(c.1))
449 }
450}
451
452impl<'a> From<(&'a [Color4f], Option<ColorSpace>)> for GradientShaderColors<'a> {
453 fn from(c: (&'a [Color4f], Option<ColorSpace>)) -> Self {
454 GradientShaderColors::<'a>::ColorsInSpace(c.0, c.1)
455 }
456}
457
458impl<'a> From<&'a [Color4f]> for GradientShaderColors<'a> {
459 fn from(c: &'a [Color4f]) -> Self {
460 GradientShaderColors::<'a>::ColorsInSpace(c, None)
461 }
462}