ferroui_base/media/effects/
effect_extensions.rs1use crate::media::effects::{IEffect, IImmutableEffect};
2use crate::{Rect, Thickness, Vector};
3use std::rc::Rc;
4
5pub struct EffectExtensions;
7
8impl EffectExtensions {
9 fn adjust_padding_radius(radius: f64) -> f64 {
10 if radius <= 0.0 {
11 return 0.0;
12 }
13 radius.ceil() + 1.0
14 }
15
16 pub fn get_effect_output_padding(effect: Option<&dyn IEffect>) -> Thickness {
21 let Some(effect) = effect else { return Thickness::default() };
22 if let Some(blur) = effect.as_blur_effect() {
23 return Thickness::uniform(Self::adjust_padding_radius(blur.radius()));
24 }
25 if let Some(drop_shadow_effect) = effect.as_drop_shadow_effect() {
26 let radius = Self::adjust_padding_radius(drop_shadow_effect.blur_radius());
27 let rc = Rect::new(-radius, -radius, radius * 2.0, radius * 2.0);
28 let rc = rc.translate(Vector::new(drop_shadow_effect.offset_x(), drop_shadow_effect.offset_y()));
29 return Thickness::new(
30 f64::max(0.0, 0.0 - rc.x),
31 f64::max(0.0, 0.0 - rc.y),
32 f64::max(0.0, rc.right()),
33 f64::max(0.0, rc.bottom()),
34 );
35 }
36
37 panic!("Unknown effect type");
38 }
39
40 pub fn to_immutable(effect: &Rc<dyn IEffect>) -> std::sync::Arc<dyn IImmutableEffect> {
44 if let Some(mutable) = effect.as_mutable_effect() {
45 return mutable.to_immutable();
46 }
47 effect.clone().into_immutable_effect().expect("an effect is either mutable or immutable")
48 }
49
50 pub fn effect_equals(immutable: Option<&dyn IImmutableEffect>, right: Option<&dyn IEffect>) -> bool {
53 match (immutable, right) {
54 (None, None) => true,
55 (Some(immutable), Some(right)) => immutable.equals(Some(right)),
56 _ => false,
57 }
58 }
59}