swf: Introduce `GradientFilterFlags`

This commit is contained in:
relrelb 2023-02-17 23:51:25 +02:00 committed by relrelb
parent 1fbfd2cbbc
commit 35ef402b95
5 changed files with 58 additions and 34 deletions

View File

@ -2122,23 +2122,14 @@ impl<'a> Reader<'a> {
ratio: self.read_u8()?, ratio: self.read_u8()?,
}); });
} }
let blur_x = self.read_fixed16()?;
let blur_y = self.read_fixed16()?;
let angle = self.read_fixed16()?;
let distance = self.read_fixed16()?;
let strength = self.read_fixed8()?;
let flags = self.read_u8()?;
Ok(GradientFilter { Ok(GradientFilter {
colors: gradient_records, colors: gradient_records,
blur_x, blur_x: self.read_fixed16()?,
blur_y, blur_y: self.read_fixed16()?,
angle, angle: self.read_fixed16()?,
distance, distance: self.read_fixed16()?,
strength, strength: self.read_fixed8()?,
is_inner: flags & 0b1000_0000 != 0, flags: GradientFilterFlags::from_bits_truncate(self.read_u8()?),
is_knockout: flags & 0b0100_0000 != 0,
is_on_top: flags & 0b0001_0000 != 0,
num_passes: flags & 0b0000_1111,
}) })
} }

View File

@ -2133,10 +2133,10 @@ pub fn tag_tests() -> Vec<TagTestData> {
angle: Fixed16::from_f64(0.7853851318359375), angle: Fixed16::from_f64(0.7853851318359375),
distance: Fixed16::from_f32(5.0), distance: Fixed16::from_f32(5.0),
strength: Fixed8::ONE, strength: Fixed8::ONE,
is_inner: true, flags: GradientFilterFlags::INNER_SHADOW
is_knockout: true, | GradientFilterFlags::KNOCKOUT
is_on_top: false, | GradientFilterFlags::COMPOSITE_SOURCE
num_passes: 3, | GradientFilterFlags::from_passes(3),
})), })),
Filter::GradientGlowFilter(Box::new(GradientFilter { Filter::GradientGlowFilter(Box::new(GradientFilter {
colors: vec![ colors: vec![
@ -2164,10 +2164,9 @@ pub fn tag_tests() -> Vec<TagTestData> {
angle: Fixed16::from_f64(0.174530029296875), angle: Fixed16::from_f64(0.174530029296875),
distance: Fixed16::from_f32(5.0), distance: Fixed16::from_f32(5.0),
strength: Fixed8::from_f64(0.19921875), strength: Fixed8::from_f64(0.19921875),
is_inner: false, flags: GradientFilterFlags::COMPOSITE_SOURCE
is_knockout: false, | GradientFilterFlags::ON_TOP
is_on_top: true, | GradientFilterFlags::from_passes(1),
num_passes: 1,
})), })),
Filter::BlurFilter(Box::new(BlurFilter { Filter::BlurFilter(Box::new(BlurFilter {
blur_x: Fixed16::from_f32(30.0), blur_x: Fixed16::from_f32(30.0),

View File

@ -32,7 +32,7 @@ pub use convolution_filter::ConvolutionFilter;
pub use drop_shadow_filter::{DropShadowFilter, DropShadowFilterFlags}; pub use drop_shadow_filter::{DropShadowFilter, DropShadowFilterFlags};
pub use fixed::{Fixed16, Fixed8}; pub use fixed::{Fixed16, Fixed8};
pub use glow_filter::{GlowFilter, GlowFilterFlags}; pub use glow_filter::{GlowFilter, GlowFilterFlags};
pub use gradient_filter::GradientFilter; pub use gradient_filter::{GradientFilter, GradientFilterFlags};
pub use matrix::Matrix; pub use matrix::Matrix;
pub use point::Point; pub use point::Point;
pub use rectangle::Rectangle; pub use rectangle::Rectangle;

View File

@ -1,4 +1,5 @@
use crate::{Fixed16, Fixed8, GradientRecord}; use crate::{Fixed16, Fixed8, GradientRecord};
use bitflags::bitflags;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct GradientFilter { pub struct GradientFilter {
@ -8,8 +9,46 @@ pub struct GradientFilter {
pub angle: Fixed16, pub angle: Fixed16,
pub distance: Fixed16, pub distance: Fixed16,
pub strength: Fixed8, pub strength: Fixed8,
pub is_inner: bool, pub flags: GradientFilterFlags,
pub is_knockout: bool, }
pub is_on_top: bool,
pub num_passes: u8, impl GradientFilter {
#[inline]
pub fn is_inner(&self) -> bool {
self.flags.contains(GradientFilterFlags::INNER_SHADOW)
}
#[inline]
pub fn is_knockout(&self) -> bool {
self.flags.contains(GradientFilterFlags::KNOCKOUT)
}
#[inline]
pub fn is_on_top(&self) -> bool {
self.flags.contains(GradientFilterFlags::ON_TOP)
}
#[inline]
pub fn num_passes(&self) -> u8 {
(self.flags & GradientFilterFlags::PASSES).bits()
}
}
bitflags! {
pub struct GradientFilterFlags: u8 {
const INNER_SHADOW = 1 << 7;
const KNOCKOUT = 1 << 6;
const COMPOSITE_SOURCE = 1 << 5;
const ON_TOP = 1 << 4;
const PASSES = 0b1111;
}
}
impl GradientFilterFlags {
#[inline]
pub fn from_passes(num_passes: u8) -> Self {
let flags = Self::from_bits_truncate(num_passes);
debug_assert_eq!(flags & Self::PASSES, flags);
flags
}
} }

View File

@ -1817,12 +1817,7 @@ impl<W: Write> Writer<W> {
self.write_fixed16(filter.angle)?; self.write_fixed16(filter.angle)?;
self.write_fixed16(filter.distance)?; self.write_fixed16(filter.distance)?;
self.write_fixed8(filter.strength)?; self.write_fixed8(filter.strength)?;
let mut bits = self.bits(); self.write_u8(filter.flags.bits())?;
bits.write_bit(filter.is_inner)?;
bits.write_bit(filter.is_knockout)?;
bits.write_bit(true)?;
bits.write_bit(filter.is_on_top)?;
bits.write_ubits(4, filter.num_passes.into())?;
Ok(()) Ok(())
} }