From 5ea06b0ce658107b601989696744940b0749cb1f Mon Sep 17 00:00:00 2001 From: Mike Welsh Date: Thu, 3 Sep 2020 17:41:58 -0700 Subject: [PATCH] swf: Use Option for more PlaceObject parameters There is a difference between empty/default (change value to default) and none (don't modify), so make this explicit for some PlaceObject parameters where it wasn't. Fixes #1104. --- core/src/display_object.rs | 7 ++-- swf/src/read.rs | 39 ++++++++++++++-------- swf/src/test_data.rs | 68 +++++++++++++++++++------------------- swf/src/types.rs | 10 +++--- swf/src/write.rs | 32 +++++++++--------- 5 files changed, 84 insertions(+), 72 deletions(-) diff --git a/core/src/display_object.rs b/core/src/display_object.rs index 8261dcd894f8..9e9138ec331f 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -767,13 +767,14 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug + Into> } } // Clip events only apply to movie clips. - if let Some(clip) = self.as_movie_clip() { + if let (Some(clip_actions), Some(clip)) = + (&place_object.clip_actions, self.as_movie_clip()) + { // Convert from `swf::ClipAction` to Ruffle's `ClipAction`. use crate::display_object::movie_clip::ClipAction; clip.set_clip_actions( gc_context, - place_object - .clip_actions + clip_actions .iter() .cloned() .map(|a| ClipAction::from_action_and_movie(a, clip.movie().unwrap())) diff --git a/swf/src/read.rs b/swf/src/read.rs index 837ffec55b19..10ed45167155 100644 --- a/swf/src/read.rs +++ b/swf/src/read.rs @@ -2094,13 +2094,13 @@ impl Reader { name: None, clip_depth: None, class_name: None, - filters: vec![], + filters: None, background_color: None, - blend_mode: BlendMode::Normal, - clip_actions: vec![], + blend_mode: None, + clip_actions: None, is_image: false, - is_bitmap_cached: false, - is_visible: true, + is_bitmap_cached: None, + is_visible: None, amf_data: None, }) } @@ -2161,20 +2161,31 @@ impl Reader { }; // PlaceObject3 - let mut filters = vec![]; - if (flags & 0b1_00000000) != 0 { + let filters = if (flags & 0b1_00000000) != 0 { + let mut filters = vec![]; let num_filters = self.read_u8()?; for _ in 0..num_filters { filters.push(self.read_filter()?); } - } + Some(filters) + } else { + None + }; let blend_mode = if (flags & 0b10_00000000) != 0 { - self.read_blend_mode()? + Some(self.read_blend_mode()?) } else { - BlendMode::Normal + None + }; + let is_bitmap_cached = if (flags & 0b100_00000000) != 0 { + Some(self.read_u8()? != 0) + } else { + None + }; + let is_visible = if (flags & 0b100000_00000000) != 0 { + Some(self.read_u8()? != 0) + } else { + None }; - let is_bitmap_cached = (flags & 0b100_00000000) != 0 && self.read_u8()? != 0; - let is_visible = (flags & 0b100000_00000000) == 0 || self.read_u8()? != 0; let background_color = if (flags & 0b1000000_00000000) != 0 { Some(self.read_rgba()?) } else { @@ -2182,9 +2193,9 @@ impl Reader { }; let clip_actions = if (flags & 0b1000_0000) != 0 { - self.read_clip_actions()? + Some(self.read_clip_actions()?) } else { - vec![] + None }; let amf_data = if place_object_version >= 4 { let mut amf = vec![]; diff --git a/swf/src/test_data.rs b/swf/src/test_data.rs index e3a7a2a220d3..6a09d97bda51 100644 --- a/swf/src/test_data.rs +++ b/swf/src/test_data.rs @@ -2096,13 +2096,13 @@ pub fn tag_tests() -> Vec { name: None, clip_depth: None, class_name: None, - filters: vec![], + filters: None, background_color: None, - blend_mode: BlendMode::Normal, - clip_actions: vec![], + blend_mode: None, + clip_actions: None, is_image: false, - is_bitmap_cached: false, - is_visible: true, + is_bitmap_cached: None, + is_visible: None, amf_data: None, })), read_tag_bytes_from_file("tests/swfs/DefineShape.swf", TagCode::PlaceObject2), @@ -2119,17 +2119,17 @@ pub fn tag_tests() -> Vec { name: None, clip_depth: None, class_name: None, - filters: vec![], + filters: None, background_color: None, - blend_mode: BlendMode::Normal, - clip_actions: vec![ClipAction { + blend_mode: None, + clip_actions: Some(vec![ClipAction { events: ClipEventFlag::EnterFrame.into(), key_code: None, action_data: vec![150, 6, 0, 0, 99, 108, 105, 112, 0, 38, 0], - }], + }]), is_image: false, - is_bitmap_cached: false, - is_visible: true, + is_bitmap_cached: None, + is_visible: None, amf_data: None, })), read_tag_bytes_from_file( @@ -2149,10 +2149,10 @@ pub fn tag_tests() -> Vec { name: None, clip_depth: None, class_name: None, - filters: vec![], + filters: None, background_color: None, - blend_mode: BlendMode::Normal, - clip_actions: vec![ + blend_mode: None, + clip_actions: Some(vec![ ClipAction { events: ClipEventFlag::Press | ClipEventFlag::Release, key_code: None, @@ -2168,10 +2168,10 @@ pub fn tag_tests() -> Vec { key_code: None, action_data: vec![150, 3, 0, 0, 67, 0, 38, 0], }, - ], + ]), is_image: false, - is_bitmap_cached: false, - is_visible: true, + is_bitmap_cached: None, + is_visible: None, amf_data: None, })), read_tag_bytes_from_file( @@ -2198,13 +2198,13 @@ pub fn tag_tests() -> Vec { name: None, clip_depth: None, class_name: None, - filters: vec![], + filters: None, background_color: None, - blend_mode: BlendMode::Normal, - clip_actions: vec![], + blend_mode: None, + clip_actions: None, is_image: true, - is_bitmap_cached: false, - is_visible: true, + is_bitmap_cached: None, + is_visible: None, amf_data: None, })), read_tag_bytes_from_file("tests/swfs/PlaceObject3-Image.swf", TagCode::PlaceObject3), @@ -2237,7 +2237,7 @@ pub fn tag_tests() -> Vec { name: Some("test".to_string()), clip_depth: None, class_name: None, - filters: vec![ + filters: Some(vec![ Filter::GradientBevelFilter(Box::new(GradientBevelFilter { colors: vec![ GradientRecord { @@ -2314,15 +2314,15 @@ pub fn tag_tests() -> Vec { blur_y: 20f64, num_passes: 2, })), - ], + ]), background_color: Some(Color { r: 255, g: 0, b: 0, a: 255, }), - blend_mode: BlendMode::Difference, - clip_actions: vec![ + blend_mode: Some(BlendMode::Difference), + clip_actions: Some(vec![ ClipAction { events: ClipEventFlag::ReleaseOutside | ClipEventFlag::RollOver, key_code: None, @@ -2333,10 +2333,10 @@ pub fn tag_tests() -> Vec { key_code: None, action_data: vec![150, 3, 0, 0, 66, 0, 38, 0], }, - ], + ]), is_image: false, - is_bitmap_cached: true, - is_visible: false, + is_bitmap_cached: Some(true), + is_visible: Some(false), amf_data: None, })), read_tag_bytes_from_file( @@ -2364,13 +2364,13 @@ pub fn tag_tests() -> Vec { name: None, clip_depth: None, class_name: None, - filters: vec![], + filters: None, background_color: None, - blend_mode: BlendMode::Normal, - clip_actions: vec![], + blend_mode: None, + clip_actions: None, is_image: false, - is_bitmap_cached: false, - is_visible: true, + is_bitmap_cached: None, + is_visible: None, amf_data: Some(vec![ 10, 11, 1, 9, 116, 101, 115, 116, 6, 17, 84, 101, 115, 116, 105, 110, 103, 33, 1, diff --git a/swf/src/types.rs b/swf/src/types.rs index 14e48b224aa7..dd0c97edbada 100644 --- a/swf/src/types.rs +++ b/swf/src/types.rs @@ -266,13 +266,13 @@ pub struct PlaceObject { pub name: Option, pub clip_depth: Option, pub class_name: Option, - pub filters: Vec, + pub filters: Option>, pub background_color: Option, - pub blend_mode: BlendMode, - pub clip_actions: Vec, + pub blend_mode: Option, + pub clip_actions: Option>, pub is_image: bool, - pub is_bitmap_cached: bool, - pub is_visible: bool, + pub is_bitmap_cached: Option, + pub is_visible: Option, pub amf_data: Option>, } diff --git a/swf/src/write.rs b/swf/src/write.rs index d0d068f16499..4e9a158611ec 100644 --- a/swf/src/write.rs +++ b/swf/src/write.rs @@ -1929,7 +1929,7 @@ impl Writer { // TODO: Assert version. let mut writer = Writer::new(&mut buf, self.version); writer.write_u8( - if !place_object.clip_actions.is_empty() { + if place_object.clip_actions.is_some() { 0b1000_0000 } else { 0 @@ -1965,7 +1965,7 @@ impl Writer { 0b100_0000 } else { 0 - } | if !place_object.is_visible { + } | if place_object.is_visible.is_some() { 0b10_0000 } else { 0 @@ -1975,17 +1975,17 @@ impl Writer { } else { 0 } - | if place_object.is_bitmap_cached { + | if place_object.is_bitmap_cached.is_some() { 0b100 } else { 0 } - | if place_object.blend_mode != BlendMode::Normal { + | if place_object.blend_mode.is_some() { 0b10 } else { 0 } - | if !place_object.filters.is_empty() { + | if place_object.filters.is_some() { 0b1 } else { 0 @@ -2022,23 +2022,23 @@ impl Writer { } if place_object_version >= 3 { - if !place_object.filters.is_empty() { - writer.write_u8(place_object.filters.len() as u8)?; - for filter in &place_object.filters { + if let Some(filters) = &place_object.filters { + writer.write_u8(filters.len() as u8)?; + for filter in filters { writer.write_filter(filter)?; } } - if place_object.blend_mode != BlendMode::Normal { - writer.write_blend_mode(place_object.blend_mode)?; + if let Some(blend_mode) = place_object.blend_mode { + writer.write_blend_mode(blend_mode)?; } - if place_object.is_bitmap_cached { - writer.write_u8(1)?; + if let Some(is_bitmap_cached) = place_object.is_bitmap_cached { + writer.write_u8(if is_bitmap_cached { 1 } else { 0 })?; } - if !place_object.is_visible { - writer.write_u8(0)?; + if let Some(is_visible) = place_object.is_visible { + writer.write_u8(if is_visible { 1 } else { 0 })?; } if let Some(ref background_color) = place_object.background_color { @@ -2046,8 +2046,8 @@ impl Writer { } } - if !place_object.clip_actions.is_empty() { - writer.write_clip_actions(&place_object.clip_actions)?; + if let Some(clip_actions) = &place_object.clip_actions { + writer.write_clip_actions(clip_actions)?; } writer.flush_bits()?;