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.
This commit is contained in:
Mike Welsh 2020-09-03 17:41:58 -07:00
parent 151b13a424
commit 5ea06b0ce6
5 changed files with 85 additions and 73 deletions

View File

@ -767,13 +767,14 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug + Into<DisplayObject<'gc>>
}
}
// 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()))

View File

@ -2094,13 +2094,13 @@ impl<R: Read> Reader<R> {
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<R: Read> Reader<R> {
};
// 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()?);
}
}
let blend_mode = if (flags & 0b10_00000000) != 0 {
self.read_blend_mode()?
Some(filters)
} else {
BlendMode::Normal
None
};
let blend_mode = if (flags & 0b10_00000000) != 0 {
Some(self.read_blend_mode()?)
} else {
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<R: Read> Reader<R> {
};
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![];

View File

@ -2096,13 +2096,13 @@ pub fn tag_tests() -> Vec<TagTestData> {
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<TagTestData> {
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<TagTestData> {
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<TagTestData> {
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<TagTestData> {
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<TagTestData> {
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<TagTestData> {
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<TagTestData> {
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<TagTestData> {
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,

View File

@ -266,13 +266,13 @@ pub struct PlaceObject {
pub name: Option<String>,
pub clip_depth: Option<Depth>,
pub class_name: Option<String>,
pub filters: Vec<Filter>,
pub filters: Option<Vec<Filter>>,
pub background_color: Option<Color>,
pub blend_mode: BlendMode,
pub clip_actions: Vec<ClipAction>,
pub blend_mode: Option<BlendMode>,
pub clip_actions: Option<Vec<ClipAction>>,
pub is_image: bool,
pub is_bitmap_cached: bool,
pub is_visible: bool,
pub is_bitmap_cached: Option<bool>,
pub is_visible: Option<bool>,
pub amf_data: Option<Vec<u8>>,
}

View File

@ -1929,7 +1929,7 @@ impl<W: Write> Writer<W> {
// 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<W: Write> Writer<W> {
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<W: Write> Writer<W> {
} 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<W: Write> Writer<W> {
}
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<W: Write> Writer<W> {
}
}
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()?;