swf: Use Fixed in more places

This commit is contained in:
Mike Welsh 2021-05-30 13:30:06 -07:00
parent 34d54dbc05
commit 2b98c878f0
17 changed files with 103 additions and 100 deletions

View File

@ -20,8 +20,8 @@ use crate::vminterface::Instantiator;
use gc_arena::MutationContext; use gc_arena::MutationContext;
use std::borrow::Cow; use std::borrow::Cow;
use swf::{ use swf::{
FillStyle, Gradient, GradientInterpolation, GradientRecord, GradientSpread, LineCapStyle, FillStyle, Fixed8, Gradient, GradientInterpolation, GradientRecord, GradientSpread,
LineJoinStyle, LineStyle, Twips, LineCapStyle, LineJoinStyle, LineStyle, Twips,
}; };
macro_rules! mc_method { macro_rules! mc_method {
@ -277,9 +277,10 @@ fn line_style<'gc>(
{ {
Some("miter") => { Some("miter") => {
if let Some(limit) = args.get(7) { if let Some(limit) = args.get(7) {
LineJoinStyle::Miter(limit.coerce_to_f64(activation)?.max(0.0).min(255.0) as f32) let limit = limit.coerce_to_f64(activation)?.max(0.0).min(255.0);
LineJoinStyle::Miter(Fixed8::from_f64(limit))
} else { } else {
LineJoinStyle::Miter(3.0) LineJoinStyle::Miter(Fixed8::from_f32(3.0))
} }
} }
Some("bevel") => LineJoinStyle::Bevel, Some("bevel") => LineJoinStyle::Bevel,
@ -401,7 +402,7 @@ fn begin_gradient_fill<'gc>(
if let Some(focal_point) = args.get(7) { if let Some(focal_point) = args.get(7) {
FillStyle::FocalGradient { FillStyle::FocalGradient {
gradient, gradient,
focal_point: focal_point.coerce_to_f64(activation)? as f32, focal_point: Fixed8::from_f64(focal_point.coerce_to_f64(activation)?),
} }
} else { } else {
FillStyle::RadialGradient(gradient) FillStyle::RadialGradient(gradient)

View File

@ -10,7 +10,7 @@ use crate::avm2::Error;
use crate::display_object::TDisplayObject; use crate::display_object::TDisplayObject;
use crate::shape_utils::DrawCommand; use crate::shape_utils::DrawCommand;
use gc_arena::{GcCell, MutationContext}; use gc_arena::{GcCell, MutationContext};
use swf::{Color, FillStyle, LineCapStyle, LineJoinStyle, LineStyle, Twips}; use swf::{Color, FillStyle, Fixed8, LineCapStyle, LineJoinStyle, LineStyle, Twips};
/// Implements `flash.display.Graphics`'s instance constructor. /// Implements `flash.display.Graphics`'s instance constructor.
pub fn instance_init<'gc>( pub fn instance_init<'gc>(
@ -151,14 +151,14 @@ fn caps_to_cap_style<'gc>(
fn joints_to_join_style<'gc>( fn joints_to_join_style<'gc>(
activation: &mut Activation<'_, 'gc, '_>, activation: &mut Activation<'_, 'gc, '_>,
joints: Value<'gc>, joints: Value<'gc>,
miter_limit: f32, miter_limit: f64,
) -> Result<LineJoinStyle, Error> { ) -> Result<LineJoinStyle, Error> {
let joints_string = joints.coerce_to_string(activation); let joints_string = joints.coerce_to_string(activation);
let joints_str = joints_string.as_deref(); let joints_str = joints_string.as_deref();
match (joints, joints_str) { match (joints, joints_str) {
(Value::Null, _) | (_, Ok("round")) => Ok(LineJoinStyle::Round), (Value::Null, _) | (_, Ok("round")) => Ok(LineJoinStyle::Round),
(_, Ok("miter")) => Ok(LineJoinStyle::Miter(miter_limit)), (_, Ok("miter")) => Ok(LineJoinStyle::Miter(Fixed8::from_f64(miter_limit))),
(_, Ok("bevel")) => Ok(LineJoinStyle::Bevel), (_, Ok("bevel")) => Ok(LineJoinStyle::Bevel),
(_, Ok(_)) => Err("ArgumentError: joints is invalid".into()), (_, Ok(_)) => Err("ArgumentError: joints is invalid".into()),
(_, Err(_)) => Err(joints_string.unwrap_err()), (_, Err(_)) => Err(joints_string.unwrap_err()),
@ -223,7 +223,7 @@ pub fn line_style<'gc>(
let width = Twips::from_pixels(thickness.min(255.0).max(0.0)); let width = Twips::from_pixels(thickness.min(255.0).max(0.0));
let color = color_from_args(color, alpha); let color = color_from_args(color, alpha);
let join_style = joints_to_join_style(activation, joints, miter_limit as f32)?; let join_style = joints_to_join_style(activation, joints, miter_limit)?;
let (allow_scale_x, allow_scale_y) = scale_mode_to_allow_scale_bits(&scale_mode)?; let (allow_scale_x, allow_scale_y) = scale_mode_to_allow_scale_bits(&scale_mode)?;
let line_style = LineStyle { let line_style = LineStyle {

View File

@ -171,7 +171,7 @@ pub fn frame_rate<'gc>(
return Err("Error: The stage's loader info does not have a frame rate".into()) return Err("Error: The stage's loader info does not have a frame rate".into())
} }
LoaderStream::Swf(root, _) => { LoaderStream::Swf(root, _) => {
return Ok(root.frame_rate().into()); return Ok(root.frame_rate().to_f64().into());
} }
} }
} }

View File

@ -6,7 +6,7 @@ use crate::tag_utils::SwfMovie;
use crate::types::{Degrees, Percent}; use crate::types::{Degrees, Percent};
use gc_arena::{Collect, Gc, GcCell, MutationContext}; use gc_arena::{Collect, Gc, GcCell, MutationContext};
use std::sync::Arc; use std::sync::Arc;
use swf::Twips; use swf::{Fixed8, Twips};
#[derive(Clone, Debug, Collect, Copy)] #[derive(Clone, Debug, Collect, Copy)]
#[collect(no_drop)] #[collect(no_drop)]
@ -369,7 +369,7 @@ fn lerp_fill(start: &swf::FillStyle, end: &swf::FillStyle, a: f32, b: f32) -> sw
}, },
) => FillStyle::FocalGradient { ) => FillStyle::FocalGradient {
gradient: lerp_gradient(start, end, a, b), gradient: lerp_gradient(start, end, a, b),
focal_point: a * start_focal + b * end_focal, focal_point: *start_focal * Fixed8::from_f32(a) + *end_focal * Fixed8::from_f32(b),
}, },
// All other combinations should not occur, because SWF stores the start/end fill as the same type, always. // All other combinations should not occur, because SWF stores the start/end fill as the same type, always.

View File

@ -3,7 +3,7 @@ use crate::vminterface::AvmType;
use gc_arena::Collect; use gc_arena::Collect;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use swf::{HeaderExt, Rectangle, TagCode, Twips}; use swf::{Fixed8, HeaderExt, Rectangle, TagCode, Twips};
pub type Error = Box<dyn std::error::Error>; pub type Error = Box<dyn std::error::Error>;
pub type DecodeResult = Result<(), Error>; pub type DecodeResult = Result<(), Error>;
@ -173,7 +173,7 @@ impl SwfMovie {
self.header.num_frames() self.header.num_frames()
} }
pub fn frame_rate(&self) -> f32 { pub fn frame_rate(&self) -> Fixed8 {
self.header.frame_rate() self.header.frame_rate()
} }
} }

View File

@ -973,7 +973,7 @@ fn swf_shape_to_svg(
let mut svg_gradient = RadialGradient::new() let mut svg_gradient = RadialGradient::new()
.set("id", format!("f{}", num_defs)) .set("id", format!("f{}", num_defs))
.set("fx", focal_point / 2.0) .set("fx", focal_point.to_f32() / 2.0)
.set("gradientUnits", "userSpaceOnUse") .set("gradientUnits", "userSpaceOnUse")
.set("cx", "0") .set("cx", "0")
.set("cy", "0") .set("cy", "0")
@ -1155,7 +1155,7 @@ fn swf_shape_to_svg(
); );
if let LineJoinStyle::Miter(miter_limit) = style.join_style { if let LineJoinStyle::Miter(miter_limit) = style.join_style {
svg_path = svg_path.set("stroke-miterlimit", miter_limit); svg_path = svg_path.set("stroke-miterlimit", miter_limit.to_f32());
} }
let mut data = Data::new(); let mut data = Data::new();
@ -1411,7 +1411,7 @@ fn swf_shape_to_canvas_commands(
let (line_join, miter_limit) = match style.join_style { let (line_join, miter_limit) = match style.join_style {
LineJoinStyle::Round => ("round", 999_999.0), LineJoinStyle::Round => ("round", 999_999.0),
LineJoinStyle::Bevel => ("bevel", 999_999.0), LineJoinStyle::Bevel => ("bevel", 999_999.0),
LineJoinStyle::Miter(ml) => ("miter", ml), LineJoinStyle::Miter(ml) => ("miter", ml.to_f32()),
}; };
let path = Path2d::new().unwrap(); let path = Path2d::new().unwrap();

View File

@ -87,7 +87,7 @@ impl ShapeTessellator {
DrawType::Gradient(swf_gradient_to_uniforms( DrawType::Gradient(swf_gradient_to_uniforms(
GradientType::Linear, GradientType::Linear,
gradient, gradient,
0.0, swf::Fixed8::ZERO,
)), )),
&mut mesh, &mut mesh,
&mut lyon_mesh, &mut lyon_mesh,
@ -117,7 +117,7 @@ impl ShapeTessellator {
DrawType::Gradient(swf_gradient_to_uniforms( DrawType::Gradient(swf_gradient_to_uniforms(
GradientType::Radial, GradientType::Radial,
gradient, gradient,
0.0, swf::Fixed8::ZERO,
)), )),
&mut mesh, &mut mesh,
&mut lyon_mesh, &mut lyon_mesh,
@ -232,6 +232,7 @@ impl ShapeTessellator {
swf::LineJoinStyle::Bevel => tessellation::LineJoin::Bevel, swf::LineJoinStyle::Bevel => tessellation::LineJoin::Bevel,
swf::LineJoinStyle::Miter(limit) => { swf::LineJoinStyle::Miter(limit) => {
// Avoid lyon assert with small miter limits. // Avoid lyon assert with small miter limits.
let limit = limit.to_f32();
if limit >= StrokeOptions::MINIMUM_MITER_LIMIT { if limit >= StrokeOptions::MINIMUM_MITER_LIMIT {
options = options.with_miter_limit(limit); options = options.with_miter_limit(limit);
tessellation::LineJoin::MiterClip tessellation::LineJoin::MiterClip
@ -299,7 +300,7 @@ pub struct Gradient {
pub colors: Vec<[f32; 4]>, pub colors: Vec<[f32; 4]>,
pub num_colors: usize, pub num_colors: usize,
pub repeat_mode: swf::GradientSpread, pub repeat_mode: swf::GradientSpread,
pub focal_point: f32, pub focal_point: swf::Fixed8,
pub interpolation: swf::GradientInterpolation, pub interpolation: swf::GradientInterpolation,
} }
@ -415,7 +416,7 @@ const MAX_GRADIENT_COLORS: usize = 15;
fn swf_gradient_to_uniforms( fn swf_gradient_to_uniforms(
gradient_type: GradientType, gradient_type: GradientType,
gradient: &swf::Gradient, gradient: &swf::Gradient,
focal_point: f32, focal_point: swf::Fixed8,
) -> Gradient { ) -> Gradient {
let mut colors: Vec<[f32; 4]> = Vec::with_capacity(8); let mut colors: Vec<[f32; 4]> = Vec::with_capacity(8);
let mut ratios: Vec<f32> = Vec::with_capacity(8); let mut ratios: Vec<f32> = Vec::with_capacity(8);

View File

@ -1365,7 +1365,7 @@ impl From<TessGradient> for Gradient {
swf::GradientSpread::Repeat => 1, swf::GradientSpread::Repeat => 1,
swf::GradientSpread::Reflect => 2, swf::GradientSpread::Reflect => 2,
}, },
focal_point: gradient.focal_point, focal_point: gradient.focal_point.to_f32(),
interpolation: gradient.interpolation, interpolation: gradient.interpolation,
} }
} }

View File

@ -202,7 +202,7 @@ impl From<TessGradient> for GradientUniforms {
swf::GradientSpread::Reflect => 2, swf::GradientSpread::Reflect => 2,
}, },
interpolation: (gradient.interpolation == swf::GradientInterpolation::LinearRgb) as i32, interpolation: (gradient.interpolation == swf::GradientInterpolation::LinearRgb) as i32,
focal_point: gradient.focal_point, focal_point: gradient.focal_point.to_f32(),
} }
} }
} }

View File

@ -10,7 +10,7 @@ fn main() {
y_min: Twips::from_pixels(0.0), y_min: Twips::from_pixels(0.0),
y_max: Twips::from_pixels(400.0), y_max: Twips::from_pixels(400.0),
}, },
frame_rate: 60.0, frame_rate: Fixed8::from_f32(60.0),
num_frames: 1, num_frames: 1,
}; };
let tags = [ let tags = [

View File

@ -1,6 +1,7 @@
use crate::byteorder::{LittleEndian, ReadBytesExt}; use crate::byteorder::{LittleEndian, ReadBytesExt};
use crate::error::Result; use crate::error::Result;
use crate::string::SwfStr; use crate::string::SwfStr;
use crate::{Fixed16, Fixed8};
use std::io::{self, Read}; use std::io::{self, Read};
pub trait ReadSwfExt<'a> { pub trait ReadSwfExt<'a> {
@ -66,13 +67,13 @@ pub trait ReadSwfExt<'a> {
} }
#[inline] #[inline]
fn read_fixed8(&mut self) -> Result<f32> { fn read_fixed8(&mut self) -> Result<Fixed8> {
Ok((self.read_i16()? as f32) / 256.0) Ok(Fixed8::from_bits(self.read_i16()?))
} }
#[inline] #[inline]
fn read_fixed16(&mut self) -> Result<f64> { fn read_fixed16(&mut self) -> Result<Fixed16> {
Ok((self.read_i32()? as f64) / 65536.0) Ok(Fixed16::from_bits(self.read_i32()?))
} }
#[inline] #[inline]

View File

@ -2288,7 +2288,7 @@ impl<'a> Reader<'a> {
})) }))
} }
6 => { 6 => {
let mut matrix = [0f64; 20]; let mut matrix = [Fixed16::ZERO; 20];
for m in &mut matrix { for m in &mut matrix {
*m = self.read_fixed16()?; *m = self.read_fixed16()?;
} }
@ -2625,7 +2625,7 @@ impl<'a> Reader<'a> {
let deblocking = if version >= 4 { let deblocking = if version >= 4 {
self.read_fixed8()? self.read_fixed8()?
} else { } else {
0.0 Fixed8::ZERO
}; };
let data = self.read_slice(data_size)?; let data = self.read_slice(data_size)?;
let alpha_data = self.read_slice_to_end(); let alpha_data = self.read_slice_to_end();
@ -2890,10 +2890,10 @@ pub mod tests {
0b11101011, 0b11101011,
]; ];
let mut reader = Reader::new(&buf[..], 1); let mut reader = Reader::new(&buf[..], 1);
assert_eq!(reader.read_fixed8().unwrap(), 0f32); assert_eq!(reader.read_fixed8().unwrap(), Fixed8::from_f32(0.0));
assert_eq!(reader.read_fixed8().unwrap(), 1f32); assert_eq!(reader.read_fixed8().unwrap(), Fixed8::from_f32(1.0));
assert_eq!(reader.read_fixed8().unwrap(), 6.5f32); assert_eq!(reader.read_fixed8().unwrap(), Fixed8::from_f32(6.5));
assert_eq!(reader.read_fixed8().unwrap(), -20.75f32); assert_eq!(reader.read_fixed8().unwrap(), Fixed8::from_f32(-20.75));
} }
#[test] #[test]

View File

@ -112,7 +112,7 @@ pub fn tag_tests() -> Vec<TagTestData> {
Tag::DefineBitsJpeg3(DefineBitsJpeg3 { Tag::DefineBitsJpeg3(DefineBitsJpeg3 {
id: 1, id: 1,
version: 3, version: 3,
deblocking: 0.0, deblocking: Fixed8::ZERO,
data: &[ data: &[
255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255,
219, 0, 67, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 219, 0, 67, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -245,8 +245,8 @@ pub fn tag_tests() -> Vec<TagTestData> {
..Default::default() ..Default::default()
}, },
filters: vec![Filter::BlurFilter(Box::new(BlurFilter { filters: vec![Filter::BlurFilter(Box::new(BlurFilter {
blur_x: 5f64, blur_x: Fixed16::from_f32(5.0),
blur_y: 5f64, blur_y: Fixed16::from_f32(5.0),
num_passes: 1, num_passes: 1,
}))], }))],
blend_mode: BlendMode::Difference, blend_mode: BlendMode::Difference,
@ -986,7 +986,7 @@ pub fn tag_tests() -> Vec<TagTestData> {
}, },
], ],
}, },
focal_point: 0.97265625, focal_point: Fixed8::from_f64(0.97265625),
}], }],
line_styles: vec![LineStyle { line_styles: vec![LineStyle {
width: Twips::from_pixels(10.0), width: Twips::from_pixels(10.0),
@ -1109,7 +1109,7 @@ pub fn tag_tests() -> Vec<TagTestData> {
}, },
], ],
}, },
focal_point: -0.9921875, focal_point: Fixed8::from_f64(-0.9921875),
}], }],
line_styles: vec![LineStyle { line_styles: vec![LineStyle {
width: Twips::from_pixels(2.0), width: Twips::from_pixels(2.0),
@ -1656,7 +1656,7 @@ pub fn tag_tests() -> Vec<TagTestData> {
}, },
], ],
}, },
focal_point: 0.56640625f32, focal_point: Fixed8::from_f64(0.56640625),
}, },
], ],
line_styles: vec![ line_styles: vec![
@ -1735,7 +1735,7 @@ pub fn tag_tests() -> Vec<TagTestData> {
}, },
start_cap: LineCapStyle::Round, start_cap: LineCapStyle::Round,
end_cap: LineCapStyle::Round, end_cap: LineCapStyle::Round,
join_style: LineJoinStyle::Miter(56f32), join_style: LineJoinStyle::Miter(Fixed8::from_f32(56.0)),
fill_style: None, fill_style: None,
allow_scale_x: true, allow_scale_x: true,
allow_scale_y: false, allow_scale_y: false,
@ -2249,11 +2249,11 @@ pub fn tag_tests() -> Vec<TagTestData> {
}, },
}, },
], ],
blur_x: 5f64, blur_x: Fixed16::from_f32(5.0),
blur_y: 5f64, blur_y: Fixed16::from_f32(5.0),
angle: 0.7853851318359375f64, angle: Fixed16::from_f64(0.7853851318359375),
distance: 5f64, distance: Fixed16::from_f32(5.0),
strength: 1f32, strength: Fixed8::ONE,
is_inner: true, is_inner: true,
is_knockout: true, is_knockout: true,
is_on_top: false, is_on_top: false,
@ -2280,19 +2280,19 @@ pub fn tag_tests() -> Vec<TagTestData> {
}, },
}, },
], ],
blur_x: 30f64, blur_x: Fixed16::from_f32(30.0),
blur_y: 30f64, blur_y: Fixed16::from_f32(30.0),
angle: 0.174530029296875f64, angle: Fixed16::from_f64(0.174530029296875),
distance: 5f64, distance: Fixed16::from_f32(5.0),
strength: 0.19921875f32, strength: Fixed8::from_f64(0.19921875),
is_inner: false, is_inner: false,
is_knockout: false, is_knockout: false,
is_on_top: true, is_on_top: true,
num_passes: 1, num_passes: 1,
})), })),
Filter::BlurFilter(Box::new(BlurFilter { Filter::BlurFilter(Box::new(BlurFilter {
blur_x: 30f64, blur_x: Fixed16::from_f32(30.0),
blur_y: 20f64, blur_y: Fixed16::from_f32(20.0),
num_passes: 2, num_passes: 2,
})), })),
]), ]),

View File

@ -40,7 +40,7 @@ pub struct Header {
pub compression: Compression, pub compression: Compression,
pub version: u8, pub version: u8,
pub stage_size: Rectangle, pub stage_size: Rectangle,
pub frame_rate: f32, pub frame_rate: Fixed8,
pub num_frames: u16, pub num_frames: u16,
} }
@ -50,7 +50,7 @@ impl Header {
compression: Compression::None, compression: Compression::None,
version, version,
stage_size: Default::default(), stage_size: Default::default(),
frame_rate: 1.0, frame_rate: Fixed8::ONE,
num_frames: 0, num_frames: 0,
} }
} }
@ -100,7 +100,7 @@ impl HeaderExt {
/// The frame rate of the SWF, in frames per second. /// The frame rate of the SWF, in frames per second.
#[inline] #[inline]
pub fn frame_rate(&self) -> f32 { pub fn frame_rate(&self) -> Fixed8 {
self.header.frame_rate self.header.frame_rate
} }
@ -590,11 +590,11 @@ pub enum Filter {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct DropShadowFilter { pub struct DropShadowFilter {
pub color: Color, pub color: Color,
pub blur_x: f64, pub blur_x: Fixed16,
pub blur_y: f64, pub blur_y: Fixed16,
pub angle: f64, pub angle: Fixed16,
pub distance: f64, pub distance: Fixed16,
pub strength: f32, pub strength: Fixed8,
pub is_inner: bool, pub is_inner: bool,
pub is_knockout: bool, pub is_knockout: bool,
pub num_passes: u8, pub num_passes: u8,
@ -602,17 +602,17 @@ pub struct DropShadowFilter {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct BlurFilter { pub struct BlurFilter {
pub blur_x: f64, pub blur_x: Fixed16,
pub blur_y: f64, pub blur_y: Fixed16,
pub num_passes: u8, pub num_passes: u8,
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct GlowFilter { pub struct GlowFilter {
pub color: Color, pub color: Color,
pub blur_x: f64, pub blur_x: Fixed16,
pub blur_y: f64, pub blur_y: Fixed16,
pub strength: f32, pub strength: Fixed8,
pub is_inner: bool, pub is_inner: bool,
pub is_knockout: bool, pub is_knockout: bool,
pub num_passes: u8, pub num_passes: u8,
@ -622,11 +622,11 @@ pub struct GlowFilter {
pub struct BevelFilter { pub struct BevelFilter {
pub shadow_color: Color, pub shadow_color: Color,
pub highlight_color: Color, pub highlight_color: Color,
pub blur_x: f64, pub blur_x: Fixed16,
pub blur_y: f64, pub blur_y: Fixed16,
pub angle: f64, pub angle: Fixed16,
pub distance: f64, pub distance: Fixed16,
pub strength: f32, pub strength: Fixed8,
pub is_inner: bool, pub is_inner: bool,
pub is_knockout: bool, pub is_knockout: bool,
pub is_on_top: bool, pub is_on_top: bool,
@ -636,11 +636,11 @@ pub struct BevelFilter {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct GradientGlowFilter { pub struct GradientGlowFilter {
pub colors: Vec<GradientRecord>, pub colors: Vec<GradientRecord>,
pub blur_x: f64, pub blur_x: Fixed16,
pub blur_y: f64, pub blur_y: Fixed16,
pub angle: f64, pub angle: Fixed16,
pub distance: f64, pub distance: Fixed16,
pub strength: f32, pub strength: Fixed8,
pub is_inner: bool, pub is_inner: bool,
pub is_knockout: bool, pub is_knockout: bool,
pub is_on_top: bool, pub is_on_top: bool,
@ -651,9 +651,9 @@ pub struct GradientGlowFilter {
pub struct ConvolutionFilter { pub struct ConvolutionFilter {
pub num_matrix_rows: u8, pub num_matrix_rows: u8,
pub num_matrix_cols: u8, pub num_matrix_cols: u8,
pub matrix: Vec<f64>, pub matrix: Vec<Fixed16>,
pub divisor: f64, pub divisor: Fixed16,
pub bias: f64, pub bias: Fixed16,
pub default_color: Color, pub default_color: Color,
pub is_clamped: bool, pub is_clamped: bool,
pub is_preserve_alpha: bool, pub is_preserve_alpha: bool,
@ -661,17 +661,17 @@ pub struct ConvolutionFilter {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct ColorMatrixFilter { pub struct ColorMatrixFilter {
pub matrix: [f64; 20], pub matrix: [Fixed16; 20],
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct GradientBevelFilter { pub struct GradientBevelFilter {
pub colors: Vec<GradientRecord>, pub colors: Vec<GradientRecord>,
pub blur_x: f64, pub blur_x: Fixed16,
pub blur_y: f64, pub blur_y: Fixed16,
pub angle: f64, pub angle: Fixed16,
pub distance: f64, pub distance: Fixed16,
pub strength: f32, pub strength: Fixed8,
pub is_inner: bool, pub is_inner: bool,
pub is_knockout: bool, pub is_knockout: bool,
pub is_on_top: bool, pub is_on_top: bool,
@ -973,7 +973,7 @@ pub enum FillStyle {
RadialGradient(Gradient), RadialGradient(Gradient),
FocalGradient { FocalGradient {
gradient: Gradient, gradient: Gradient,
focal_point: f32, focal_point: Fixed8,
}, },
Bitmap { Bitmap {
id: CharacterId, id: CharacterId,
@ -1052,7 +1052,7 @@ pub enum LineCapStyle {
pub enum LineJoinStyle { pub enum LineJoinStyle {
Round, Round,
Bevel, Bevel,
Miter(f32), Miter(Fixed8),
} }
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Clone, Copy)]
@ -1394,7 +1394,7 @@ pub struct VideoFrame<'a> {
pub struct DefineBitsJpeg3<'a> { pub struct DefineBitsJpeg3<'a> {
pub id: CharacterId, pub id: CharacterId,
pub version: u8, pub version: u8,
pub deblocking: f32, pub deblocking: Fixed8,
pub data: &'a [u8], pub data: &'a [u8],
pub alpha_data: &'a [u8], pub alpha_data: &'a [u8],
} }

View File

@ -25,7 +25,7 @@ use std::io::{self, Write};
/// compression: Compression::Zlib, /// compression: Compression::Zlib,
/// version: 6, /// version: 6,
/// stage_size: Rectangle { x_min: Twips::from_pixels(0.0), x_max: Twips::from_pixels(400.0), y_min: Twips::from_pixels(0.0), y_max: Twips::from_pixels(400.0) }, /// stage_size: Rectangle { x_min: Twips::from_pixels(0.0), x_max: Twips::from_pixels(400.0), y_min: Twips::from_pixels(0.0), y_max: Twips::from_pixels(400.0) },
/// frame_rate: 60.0, /// frame_rate: Fixed8::from_f32(60.0),
/// num_frames: 1, /// num_frames: 1,
/// }; /// };
/// let tags = [ /// let tags = [
@ -281,12 +281,12 @@ impl<W: Write> Writer<W> {
} }
} }
fn write_fixed8(&mut self, n: f32) -> io::Result<()> { fn write_fixed8(&mut self, n: Fixed8) -> io::Result<()> {
self.write_i16((n * 256f32) as i16) self.write_i16(n.get())
} }
fn write_fixed16(&mut self, n: f64) -> io::Result<()> { fn write_fixed16(&mut self, n: Fixed16) -> io::Result<()> {
self.write_i32((n * 65536f64) as i32) self.write_i32(n.get())
} }
fn write_encoded_u32(&mut self, mut n: u32) -> Result<()> { fn write_encoded_u32(&mut self, mut n: u32) -> Result<()> {
@ -2660,7 +2660,7 @@ mod tests {
y_min: Twips::from_pixels(0.0), y_min: Twips::from_pixels(0.0),
y_max: Twips::from_pixels(480.0), y_max: Twips::from_pixels(480.0),
}, },
frame_rate: 60.0, frame_rate: Fixed8::from_f32(60.0),
num_frames: 1, num_frames: 1,
}; };
write_swf(&header, &[], &mut buf)?; write_swf(&header, &[], &mut buf)?;
@ -2687,10 +2687,10 @@ mod tests {
let mut buf = Vec::new(); let mut buf = Vec::new();
{ {
let mut writer = Writer::new(&mut buf, 1); let mut writer = Writer::new(&mut buf, 1);
writer.write_fixed8(0f32).unwrap(); writer.write_fixed8(Fixed8::ZERO).unwrap();
writer.write_fixed8(1f32).unwrap(); writer.write_fixed8(Fixed8::ONE).unwrap();
writer.write_fixed8(6.5f32).unwrap(); writer.write_fixed8(Fixed8::from_f32(6.5)).unwrap();
writer.write_fixed8(-20.75f32).unwrap(); writer.write_fixed8(Fixed8::from_f32(-20.75)).unwrap();
} }
assert_eq!( assert_eq!(
buf, buf,

View File

@ -881,7 +881,7 @@ fn run_swf(
let base_path = Path::new(swf_path).parent().unwrap(); let base_path = Path::new(swf_path).parent().unwrap();
let (mut executor, channel) = NullExecutor::new(); let (mut executor, channel) = NullExecutor::new();
let movie = SwfMovie::from_path(swf_path, None)?; let movie = SwfMovie::from_path(swf_path, None)?;
let frame_time = 1000.0 / movie.frame_rate() as f64; let frame_time = 1000.0 / movie.frame_rate().to_f64();
let trace_output = Rc::new(RefCell::new(Vec::new())); let trace_output = Rc::new(RefCell::new(Vec::new()));
let player = Player::new( let player = Player::new(

View File

@ -991,7 +991,7 @@ impl Ruffle {
let metadata = MovieMetadata { let metadata = MovieMetadata {
width: width.to_pixels(), width: width.to_pixels(),
height: height.to_pixels(), height: height.to_pixels(),
frame_rate: swf_header.frame_rate(), frame_rate: swf_header.frame_rate().to_f32(),
num_frames: swf_header.num_frames(), num_frames: swf_header.num_frames(),
swf_version: swf_header.version(), swf_version: swf_header.version(),
background_color, background_color,