diff --git a/src/read.rs b/src/read.rs index 6800c3401..f219df90a 100644 --- a/src/read.rs +++ b/src/read.rs @@ -373,6 +373,19 @@ impl Reader { Ok(m) } + fn read_language(&mut self) -> Result { + Ok(match self.read_u8()? { + 0 => Language::Unknown, + 1 => Language::Latin, + 2 => Language::Japanese, + 3 => Language::Korean, + 4 => Language::SimplifiedChinese, + 5 => Language::TraditionalChinese, + _ => return Err(Error::new(ErrorKind::InvalidData, + "Invalid language code.")), + }) + } + fn read_tag_list(&mut self) -> Result> { let mut tags = Vec::new(); loop { @@ -479,7 +492,8 @@ impl Reader { }, Some(TagCode::DefineEditText) => tag_reader.read_define_edit_text()?, Some(TagCode::DefineFont) => tag_reader.read_define_font()?, - Some(TagCode::DefineFontInfo) => tag_reader.read_define_font_info()?, + Some(TagCode::DefineFontInfo) => tag_reader.read_define_font_info(1)?, + Some(TagCode::DefineFontInfo2) => tag_reader.read_define_font_info(2)?, Some(TagCode::DefineShape) => try!(tag_reader.read_define_shape(1)), Some(TagCode::DefineShape2) => try!(tag_reader.read_define_shape(2)), Some(TagCode::DefineShape3) => try!(tag_reader.read_define_shape(3)), @@ -929,7 +943,7 @@ impl Reader { ))) } - fn read_define_font_info(&mut self) -> Result { + fn read_define_font_info(&mut self, version: u8) -> Result { let id = self.read_u16()?; let font_name_len = self.read_u8()?; @@ -937,7 +951,14 @@ impl Reader { self.input.by_ref().take(font_name_len as u64).read_to_string(&mut font_name)?; let flags = self.read_u8()?; - let use_wide_codes = flags & 0b1 != 0; + let use_wide_codes = flags & 0b1 != 0; // TODO(Herschel): Warn if false for version 2. + + let language = if version >= 2 { + self.read_language()? + } else { + Language::Unknown + }; + let mut code_table = vec![]; if use_wide_codes { while let Ok(code) = self.read_u16() { @@ -952,12 +973,14 @@ impl Reader { // SWF19 has ANSI and Shift-JIS backwards? Ok(Tag::DefineFontInfo(Box::new(FontInfo { id: id, + version: version, name: font_name, is_small_text: flags & 0b100000 != 0, is_ansi: flags & 0b10000 != 0, is_shift_jis: flags & 0b1000 != 0, is_italic: flags & 0b100 != 0, is_bold: flags & 0b10 != 0, + language: language, code_table: code_table, }))) } diff --git a/src/test_data.rs b/src/test_data.rs index ae9f44be8..31c3c7d32 100644 --- a/src/test_data.rs +++ b/src/test_data.rs @@ -302,17 +302,36 @@ pub fn tag_tests() -> Vec { vec![ 1, Tag::DefineFontInfo(Box::new(FontInfo { id: 1, + version: 1, name: "Verdana".to_string(), is_small_text: false, is_ansi: true, is_shift_jis: false, is_italic: false, is_bold: false, + language: Language::Unknown, code_table: vec![45, 95], })), read_tag_bytes_from_file("tests/swfs/DefineFont-MX.swf", TagCode::DefineFontInfo) ), + ( + 6, + Tag::DefineFontInfo(Box::new(FontInfo { + id: 1, + version: 2, + name: "Verdana".to_string(), + is_small_text: false, + is_ansi: true, + is_shift_jis: false, + is_italic: true, + is_bold: true, + language: Language::Latin, + code_table: vec![45, 95], + })), + read_tag_bytes_from_file("tests/swfs/DefineText2-MX.swf", TagCode::DefineFontInfo2) + ), + ( 8, Tag::DefineScalingGrid { diff --git a/src/types.rs b/src/types.rs index dbbdc30a7..186e20f81 100644 --- a/src/types.rs +++ b/src/types.rs @@ -85,6 +85,16 @@ impl Matrix { } } +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum Language { + Unknown, + Latin, + Japanese, + Korean, + SimplifiedChinese, + TraditionalChinese, +} + #[derive(Debug,PartialEq)] pub struct FileAttributes { pub use_direct_blit: bool, @@ -405,13 +415,13 @@ pub struct Sprite { pub tags: Vec, } -#[derive(Debug,PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct ShapeStyles { pub fill_styles: Vec, pub line_styles: Vec, } -#[derive(Debug,PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub enum ShapeRecord { // TODO: Twips StyleChange(StyleChangeData), @@ -424,7 +434,7 @@ pub enum ShapeRecord { }, } -#[derive(Debug,PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct StyleChangeData { pub move_to: Option<(f32, f32)>, pub fill_style_0: Option, @@ -609,7 +619,7 @@ pub enum ButtonActionCondition { KeyPress } -#[derive(Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct Font { pub id: CharacterId, pub glyphs: Vec, @@ -618,12 +628,14 @@ pub struct Font { #[derive(Clone, Debug, PartialEq)] pub struct FontInfo { pub id: CharacterId, + pub version: u8, pub name: String, pub is_small_text: bool, pub is_shift_jis: bool, pub is_ansi: bool, pub is_bold: bool, pub is_italic: bool, + pub language: Language, pub code_table: Vec, } diff --git a/src/write.rs b/src/write.rs index a27cc6dc3..09721324b 100644 --- a/src/write.rs +++ b/src/write.rs @@ -384,6 +384,17 @@ impl Writer { Ok(()) } + fn write_language(&mut self, language: Language) -> Result<()> { + self.write_u8(match language { + Language::Unknown => 0, + Language::Latin => 1, + Language::Japanese => 2, + Language::Korean => 3, + Language::SimplifiedChinese => 4, + Language::TraditionalChinese => 5, + }) + } + fn write_tag(&mut self, tag: &Tag) -> Result<()> { match tag { &Tag::ShowFrame => try!(self.write_tag_header(TagCode::ShowFrame, 0)), @@ -536,13 +547,16 @@ impl Writer { }, &Tag::DefineFontInfo(ref font_info) => { - let use_wide_codes = self.version >= 6; + let use_wide_codes = self.version >= 6 || font_info.version >= 2; let len = font_info.name.len() + if use_wide_codes { 2 } else { 1 } * font_info.code_table.len() + + if font_info.version >= 2 { 1 } else { 0 } + 4; - self.write_tag_header(TagCode::DefineFontInfo, len as u32)?; + let tag_id = if font_info.version == 1 { TagCode::DefineFontInfo } + else { TagCode::DefineFontInfo2 }; + self.write_tag_header(tag_id, len as u32)?; self.write_u16(font_info.id)?; // SWF19 has ANSI and Shift-JIS backwards? @@ -556,6 +570,10 @@ impl Writer { if font_info.is_bold { 0b10 } else { 0 } | if use_wide_codes { 0b1 } else { 0 } )?; + // TODO(Herschel): Assert language is unknown for v1. + if font_info.version >= 2 { + self.write_language(font_info.language)?; + } for &code in &font_info.code_table { if use_wide_codes { self.write_u16(code)?; diff --git a/tests/swfs/DefineText2-MX.fla b/tests/swfs/DefineText2-MX.fla new file mode 100644 index 000000000..ad8433193 Binary files /dev/null and b/tests/swfs/DefineText2-MX.fla differ diff --git a/tests/swfs/DefineText2-MX.swf b/tests/swfs/DefineText2-MX.swf new file mode 100644 index 000000000..c220acdd3 Binary files /dev/null and b/tests/swfs/DefineText2-MX.swf differ