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()?,
});
}
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 {
colors: gradient_records,
blur_x,
blur_y,
angle,
distance,
strength,
is_inner: flags & 0b1000_0000 != 0,
is_knockout: flags & 0b0100_0000 != 0,
is_on_top: flags & 0b0001_0000 != 0,
num_passes: flags & 0b0000_1111,
blur_x: self.read_fixed16()?,
blur_y: self.read_fixed16()?,
angle: self.read_fixed16()?,
distance: self.read_fixed16()?,
strength: self.read_fixed8()?,
flags: GradientFilterFlags::from_bits_truncate(self.read_u8()?),
})
}

View File

@ -2133,10 +2133,10 @@ pub fn tag_tests() -> Vec<TagTestData> {
angle: Fixed16::from_f64(0.7853851318359375),
distance: Fixed16::from_f32(5.0),
strength: Fixed8::ONE,
is_inner: true,
is_knockout: true,
is_on_top: false,
num_passes: 3,
flags: GradientFilterFlags::INNER_SHADOW
| GradientFilterFlags::KNOCKOUT
| GradientFilterFlags::COMPOSITE_SOURCE
| GradientFilterFlags::from_passes(3),
})),
Filter::GradientGlowFilter(Box::new(GradientFilter {
colors: vec![
@ -2164,10 +2164,9 @@ pub fn tag_tests() -> Vec<TagTestData> {
angle: Fixed16::from_f64(0.174530029296875),
distance: Fixed16::from_f32(5.0),
strength: Fixed8::from_f64(0.19921875),
is_inner: false,
is_knockout: false,
is_on_top: true,
num_passes: 1,
flags: GradientFilterFlags::COMPOSITE_SOURCE
| GradientFilterFlags::ON_TOP
| GradientFilterFlags::from_passes(1),
})),
Filter::BlurFilter(Box::new(BlurFilter {
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 fixed::{Fixed16, Fixed8};
pub use glow_filter::{GlowFilter, GlowFilterFlags};
pub use gradient_filter::GradientFilter;
pub use gradient_filter::{GradientFilter, GradientFilterFlags};
pub use matrix::Matrix;
pub use point::Point;
pub use rectangle::Rectangle;

View File

@ -1,4 +1,5 @@
use crate::{Fixed16, Fixed8, GradientRecord};
use bitflags::bitflags;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct GradientFilter {
@ -8,8 +9,46 @@ pub struct GradientFilter {
pub angle: Fixed16,
pub distance: Fixed16,
pub strength: Fixed8,
pub is_inner: bool,
pub is_knockout: bool,
pub is_on_top: bool,
pub num_passes: u8,
pub flags: GradientFilterFlags,
}
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.distance)?;
self.write_fixed8(filter.strength)?;
let mut bits = self.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())?;
self.write_u8(filter.flags.bits())?;
Ok(())
}