swf/types/
glow_filter.rs

1use crate::{BlurFilter, BlurFilterFlags, Color, Fixed16, Fixed8, Rectangle, Twips};
2use bitflags::bitflags;
3
4#[derive(Clone, Debug, Eq, PartialEq)]
5pub struct GlowFilter {
6    pub color: Color,
7    pub blur_x: Fixed16,
8    pub blur_y: Fixed16,
9    pub strength: Fixed8,
10    pub flags: GlowFilterFlags,
11}
12
13impl GlowFilter {
14    #[inline]
15    pub fn is_inner(&self) -> bool {
16        self.flags.contains(GlowFilterFlags::INNER_GLOW)
17    }
18
19    #[inline]
20    pub fn is_knockout(&self) -> bool {
21        self.flags.contains(GlowFilterFlags::KNOCKOUT)
22    }
23
24    #[inline]
25    pub fn composite_source(&self) -> bool {
26        self.flags.contains(GlowFilterFlags::COMPOSITE_SOURCE)
27    }
28
29    #[inline]
30    pub fn num_passes(&self) -> u8 {
31        (self.flags & GlowFilterFlags::PASSES).bits()
32    }
33
34    pub fn scale(&mut self, x: f32, y: f32) {
35        self.blur_x = BlurFilter::scale_blur(self.blur_x, x);
36        self.blur_y = BlurFilter::scale_blur(self.blur_y, y);
37    }
38
39    pub fn calculate_dest_rect(&self, source_rect: Rectangle<Twips>) -> Rectangle<Twips> {
40        // TODO: Inner might not need this. Docs suggest it doesn't care about source rect, but rather source *size*?
41        self.inner_blur_filter().calculate_dest_rect(source_rect)
42    }
43
44    pub fn inner_blur_filter(&self) -> BlurFilter {
45        BlurFilter {
46            blur_x: self.blur_x,
47            blur_y: self.blur_y,
48            flags: BlurFilterFlags::from_passes(self.num_passes()),
49        }
50    }
51}
52
53bitflags! {
54    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
55    pub struct GlowFilterFlags: u8 {
56        const INNER_GLOW       = 1 << 7;
57        const KNOCKOUT         = 1 << 6;
58        const COMPOSITE_SOURCE = 1 << 5;
59        const PASSES           = 0b11111;
60    }
61}
62
63impl GlowFilterFlags {
64    #[inline]
65    pub fn from_passes(num_passes: u8) -> Self {
66        let flags = Self::from_bits_retain(num_passes);
67        debug_assert_eq!(flags & Self::PASSES, flags);
68        flags
69    }
70}