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 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}