1use crate::media::{Color, ColorMatrix, ColorMatrixAlphaMode, Colors};
12
13#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
20pub struct CompositionEffectSourceParameter {
21 name: String,
22}
23
24impl CompositionEffectSourceParameter {
25 pub fn new(name: impl Into<String>) -> Self {
27 Self { name: name.into() }
28 }
29
30 pub fn name(&self) -> &str {
32 &self.name
33 }
34}
35
36#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
41#[repr(i32)]
42pub enum EffectBorderMode {
43 #[default]
45 Soft = 0,
46 Hard = 1,
48}
49
50#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
57#[repr(i32)]
58pub enum EffectOptimization {
59 Speed = 0,
61 #[default]
63 Balanced = 1,
64 Quality = 2,
66}
67
68#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
75#[repr(i32)]
76pub enum CanvasComposite {
77 #[default]
79 SourceOver = 0,
80 DestinationOver = 1,
81 SourceIn = 2,
82 DestinationIn = 3,
83 SourceOut = 4,
84 DestinationOut = 5,
85 SourceAtop = 6,
86 DestinationAtop = 7,
87 Xor = 8,
88 Add = 9,
89 Copy = 10,
90 BoundedCopy = 11,
91 MaskInvert = 12,
92}
93
94#[derive(Clone, Debug, PartialEq)]
97pub enum GraphicsEffectSource {
98 Parameter(CompositionEffectSourceParameter),
100 Effect(Box<GraphicsEffect>),
102}
103
104impl From<CompositionEffectSourceParameter> for GraphicsEffectSource {
105 fn from(parameter: CompositionEffectSourceParameter) -> Self {
106 GraphicsEffectSource::Parameter(parameter)
107 }
108}
109
110impl From<GraphicsEffect> for GraphicsEffectSource {
111 fn from(effect: GraphicsEffect) -> Self {
112 GraphicsEffectSource::Effect(Box::new(effect))
113 }
114}
115
116#[derive(Clone, Debug, PartialEq)]
119pub enum GraphicsEffect {
120 GaussianBlur(GaussianBlurEffect),
121 Opacity(OpacityEffect),
122 CrossFade(CrossFadeEffect),
123 Composite(CompositeEffect),
124 ColorSource(ColorSourceEffect),
125 Saturation(SaturationEffect),
126 Blend(BlendEffect),
127 ColorMatrix(ColorMatrixEffect),
128 Tint(TintEffect),
129 Invert(InvertEffect),
130 Grayscale(GrayscaleEffect),
131 LuminanceToAlpha(LuminanceToAlphaEffect),
132 ArithmeticComposite(ArithmeticCompositeEffect),
133 AlphaMask(AlphaMaskEffect),
134 Border(BorderEffect),
135 SceneLighting(SceneLightingEffect),
136 Shadow(ShadowEffect),
137}
138
139impl GraphicsEffect {
140 pub fn name(&self) -> &str {
143 match self {
144 GraphicsEffect::GaussianBlur(effect) => &effect.name,
145 GraphicsEffect::Opacity(effect) => &effect.name,
146 GraphicsEffect::CrossFade(effect) => &effect.name,
147 GraphicsEffect::Composite(effect) => &effect.name,
148 GraphicsEffect::ColorSource(effect) => &effect.name,
149 GraphicsEffect::Saturation(effect) => &effect.name,
150 GraphicsEffect::Blend(effect) => &effect.name,
151 GraphicsEffect::ColorMatrix(effect) => &effect.name,
152 GraphicsEffect::Tint(effect) => &effect.name,
153 GraphicsEffect::Invert(effect) => &effect.name,
154 GraphicsEffect::Grayscale(effect) => &effect.name,
155 GraphicsEffect::LuminanceToAlpha(effect) => &effect.name,
156 GraphicsEffect::ArithmeticComposite(effect) => &effect.name,
157 GraphicsEffect::AlphaMask(effect) => &effect.name,
158 GraphicsEffect::Border(effect) => &effect.name,
159 GraphicsEffect::SceneLighting(effect) => &effect.name,
160 GraphicsEffect::Shadow(effect) => &effect.name,
161 }
162 }
163
164 pub fn type_name(&self) -> &'static str {
166 match self {
167 GraphicsEffect::GaussianBlur(_) => "GaussianBlurEffect",
168 GraphicsEffect::Opacity(_) => "OpacityEffect",
169 GraphicsEffect::CrossFade(_) => "CrossFadeEffect",
170 GraphicsEffect::Composite(_) => "CompositeEffect",
171 GraphicsEffect::ColorSource(_) => "ColorSourceEffect",
172 GraphicsEffect::Saturation(_) => "SaturationEffect",
173 GraphicsEffect::Blend(_) => "BlendEffect",
174 GraphicsEffect::ColorMatrix(_) => "ColorMatrixEffect",
175 GraphicsEffect::Tint(_) => "TintEffect",
176 GraphicsEffect::Invert(_) => "InvertEffect",
177 GraphicsEffect::Grayscale(_) => "GrayscaleEffect",
178 GraphicsEffect::LuminanceToAlpha(_) => "LuminanceToAlphaEffect",
179 GraphicsEffect::ArithmeticComposite(_) => "ArithmeticCompositeEffect",
180 GraphicsEffect::AlphaMask(_) => "AlphaMaskEffect",
181 GraphicsEffect::Border(_) => "BorderEffect",
182 GraphicsEffect::SceneLighting(_) => "SceneLightingEffect",
183 GraphicsEffect::Shadow(_) => "ShadowEffect",
184 }
185 }
186}
187
188macro_rules! graphics_effect_conversions {
189 ($($ty:ident => $variant:ident),* $(,)?) => {$(
190 impl From<$ty> for GraphicsEffect {
191 fn from(effect: $ty) -> Self {
192 GraphicsEffect::$variant(effect)
193 }
194 }
195
196 impl From<$ty> for GraphicsEffectSource {
197 fn from(effect: $ty) -> Self {
198 GraphicsEffectSource::Effect(Box::new(GraphicsEffect::$variant(effect)))
199 }
200 }
201 )*};
202}
203
204graphics_effect_conversions! {
205 GaussianBlurEffect => GaussianBlur,
206 OpacityEffect => Opacity,
207 CrossFadeEffect => CrossFade,
208 CompositeEffect => Composite,
209 ColorSourceEffect => ColorSource,
210 SaturationEffect => Saturation,
211 BlendEffect => Blend,
212 ColorMatrixEffect => ColorMatrix,
213 TintEffect => Tint,
214 InvertEffect => Invert,
215 GrayscaleEffect => Grayscale,
216 LuminanceToAlphaEffect => LuminanceToAlpha,
217 ArithmeticCompositeEffect => ArithmeticComposite,
218 AlphaMaskEffect => AlphaMask,
219 BorderEffect => Border,
220 ShadowEffect => Shadow,
221 SceneLightingEffect => SceneLighting,
222}
223
224#[derive(Clone, Debug, PartialEq)]
227pub struct GaussianBlurEffect {
228 pub name: String,
230 pub blur_amount: f32,
233 pub border_mode: EffectBorderMode,
235 pub optimization: EffectOptimization,
237 pub source: Option<GraphicsEffectSource>,
239}
240
241impl Default for GaussianBlurEffect {
242 fn default() -> Self {
243 Self {
244 name: String::new(),
245 blur_amount: 3.0,
246 border_mode: EffectBorderMode::Soft,
247 optimization: EffectOptimization::Balanced,
248 source: None,
249 }
250 }
251}
252
253#[derive(Clone, Debug, PartialEq)]
256pub struct OpacityEffect {
257 pub name: String,
259 pub opacity: f32,
261 pub source: Option<GraphicsEffectSource>,
263}
264
265impl Default for OpacityEffect {
266 fn default() -> Self {
267 Self { name: String::new(), opacity: 1.0, source: None }
268 }
269}
270
271#[derive(Clone, Debug, PartialEq)]
275pub struct CrossFadeEffect {
276 pub name: String,
278 pub weight: f32,
280 pub source1: Option<GraphicsEffectSource>,
282 pub source2: Option<GraphicsEffectSource>,
284}
285
286impl Default for CrossFadeEffect {
287 fn default() -> Self {
288 Self { name: String::new(), weight: 0.5, source1: None, source2: None }
289 }
290}
291
292#[derive(Clone, Debug, Default, PartialEq)]
294pub struct CompositeEffect {
295 pub name: String,
297 pub mode: CanvasComposite,
299 pub sources: Vec<GraphicsEffectSource>,
301}
302
303#[derive(Clone, Debug, PartialEq)]
306pub struct ColorSourceEffect {
307 pub name: String,
309 pub color: Color,
311}
312
313impl Default for ColorSourceEffect {
314 fn default() -> Self {
315 Self { name: String::new(), color: Colors::BLACK }
316 }
317}
318
319#[derive(Clone, Debug, PartialEq)]
322pub struct SaturationEffect {
323 pub name: String,
325 pub saturation: f32,
328 pub source: Option<GraphicsEffectSource>,
330}
331
332impl Default for SaturationEffect {
333 fn default() -> Self {
334 Self { name: String::new(), saturation: 0.5, source: None }
335 }
336}
337
338#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
352#[repr(i32)]
353pub enum BlendEffectMode {
354 #[default]
356 Multiply = 0,
357 Screen = 1,
358 Darken = 2,
359 Lighten = 3,
360 Dissolve = 4,
361 ColorBurn = 5,
362 LinearBurn = 6,
363 DarkerColor = 7,
364 LighterColor = 8,
365 ColorDodge = 9,
366 LinearDodge = 10,
367 Overlay = 11,
368 SoftLight = 12,
369 HardLight = 13,
370 VividLight = 14,
371 LinearLight = 15,
372 PinLight = 16,
373 HardMix = 17,
374 Difference = 18,
375 Exclusion = 19,
376 Hue = 20,
377 Saturation = 21,
378 Color = 22,
379 Luminosity = 23,
380 Subtract = 24,
381 Division = 25,
382}
383
384#[derive(Clone, Debug, Default, PartialEq)]
386pub struct BlendEffect {
387 pub name: String,
389 pub mode: BlendEffectMode,
391 pub background: Option<GraphicsEffectSource>,
393 pub foreground: Option<GraphicsEffectSource>,
395}
396
397#[derive(Clone, Debug, PartialEq)]
400pub struct ColorMatrixEffect {
401 pub name: String,
403 pub color_matrix: ColorMatrix,
405 pub alpha_mode: ColorMatrixAlphaMode,
408 pub clamp_output: bool,
411 pub source: Option<GraphicsEffectSource>,
413}
414
415impl Default for ColorMatrixEffect {
416 fn default() -> Self {
417 Self {
418 name: String::new(),
419 color_matrix: ColorMatrix::IDENTITY,
420 alpha_mode: ColorMatrixAlphaMode::Premultiplied,
421 clamp_output: false,
422 source: None,
423 }
424 }
425}
426
427#[derive(Clone, Debug, PartialEq)]
430pub struct TintEffect {
431 pub name: String,
433 pub color: Color,
435 pub clamp_output: bool,
437 pub source: Option<GraphicsEffectSource>,
439}
440
441impl Default for TintEffect {
442 fn default() -> Self {
443 Self { name: String::new(), color: Colors::WHITE, clamp_output: false, source: None }
444 }
445}
446
447#[derive(Clone, Debug, Default, PartialEq)]
449pub struct InvertEffect {
450 pub name: String,
452 pub source: Option<GraphicsEffectSource>,
454}
455
456#[derive(Clone, Debug, Default, PartialEq)]
458pub struct GrayscaleEffect {
459 pub name: String,
461 pub source: Option<GraphicsEffectSource>,
463}
464
465#[derive(Clone, Debug, Default, PartialEq)]
468pub struct LuminanceToAlphaEffect {
469 pub name: String,
471 pub source: Option<GraphicsEffectSource>,
473}
474
475#[derive(Clone, Debug, PartialEq)]
485pub struct ArithmeticCompositeEffect {
486 pub name: String,
488 pub multiply_amount: f32,
490 pub source1_amount: f32,
492 pub source2_amount: f32,
494 pub offset: f32,
496 pub clamp_output: bool,
498 pub source1: Option<GraphicsEffectSource>,
500 pub source2: Option<GraphicsEffectSource>,
502}
503
504impl Default for ArithmeticCompositeEffect {
505 fn default() -> Self {
506 Self {
507 name: String::new(),
508 multiply_amount: 1.0,
509 source1_amount: 0.0,
510 source2_amount: 0.0,
511 offset: 0.0,
512 clamp_output: false,
513 source1: None,
514 source2: None,
515 }
516 }
517}
518
519#[derive(Clone, Debug, Default, PartialEq)]
522pub struct AlphaMaskEffect {
523 pub name: String,
525 pub source: Option<GraphicsEffectSource>,
527 pub alpha_mask: Option<GraphicsEffectSource>,
529}
530
531#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
534#[repr(i32)]
535pub enum CanvasEdgeBehavior {
536 #[default]
538 Clamp = 0,
539 Wrap = 1,
541 Mirror = 2,
543}
544
545#[derive(Clone, Debug, Default, PartialEq)]
550pub struct BorderEffect {
551 pub name: String,
553 pub extend_x: CanvasEdgeBehavior,
555 pub extend_y: CanvasEdgeBehavior,
557 pub source: Option<GraphicsEffectSource>,
559}
560
561#[derive(Clone, Debug, PartialEq)]
572pub struct SceneLightingEffect {
573 pub name: String,
575 pub ambient_amount: f32,
577 pub diffuse_amount: f32,
579 pub specular_amount: f32,
582 pub specular_shine: f32,
584 pub normal_map_source: Option<GraphicsEffectSource>,
586}
587
588impl Default for SceneLightingEffect {
589 fn default() -> Self {
590 Self {
591 name: String::new(),
592 ambient_amount: 1.0,
593 diffuse_amount: 1.0,
594 specular_amount: 0.0,
595 specular_shine: 16.0,
596 normal_map_source: None,
597 }
598 }
599}
600
601#[derive(Clone, Debug, PartialEq)]
604pub struct ShadowEffect {
605 pub name: String,
607 pub blur_amount: f32,
610 pub shadow_color: Color,
613 pub optimization: EffectOptimization,
615 pub source: Option<GraphicsEffectSource>,
617}
618
619impl Default for ShadowEffect {
620 fn default() -> Self {
621 Self {
622 name: String::new(),
623 blur_amount: 1.0,
624 shadow_color: Color::from_argb(255, 0, 0, 0),
625 optimization: EffectOptimization::Balanced,
626 source: None,
627 }
628 }
629}