Implement DefineFontInfo2 tag

This commit is contained in:
Mike Welsh 2017-02-16 20:15:35 -08:00
parent a82c1d22a6
commit 2fa889a414
6 changed files with 81 additions and 9 deletions

View File

@ -373,6 +373,19 @@ impl<R: Read> Reader<R> {
Ok(m) Ok(m)
} }
fn read_language(&mut self) -> Result<Language> {
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<Vec<Tag>> { fn read_tag_list(&mut self) -> Result<Vec<Tag>> {
let mut tags = Vec::new(); let mut tags = Vec::new();
loop { loop {
@ -479,7 +492,8 @@ impl<R: Read> Reader<R> {
}, },
Some(TagCode::DefineEditText) => tag_reader.read_define_edit_text()?, Some(TagCode::DefineEditText) => tag_reader.read_define_edit_text()?,
Some(TagCode::DefineFont) => tag_reader.read_define_font()?, 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::DefineShape) => try!(tag_reader.read_define_shape(1)),
Some(TagCode::DefineShape2) => try!(tag_reader.read_define_shape(2)), Some(TagCode::DefineShape2) => try!(tag_reader.read_define_shape(2)),
Some(TagCode::DefineShape3) => try!(tag_reader.read_define_shape(3)), Some(TagCode::DefineShape3) => try!(tag_reader.read_define_shape(3)),
@ -929,7 +943,7 @@ impl<R: Read> Reader<R> {
))) )))
} }
fn read_define_font_info(&mut self) -> Result<Tag> { fn read_define_font_info(&mut self, version: u8) -> Result<Tag> {
let id = self.read_u16()?; let id = self.read_u16()?;
let font_name_len = self.read_u8()?; let font_name_len = self.read_u8()?;
@ -937,7 +951,14 @@ impl<R: Read> Reader<R> {
self.input.by_ref().take(font_name_len as u64).read_to_string(&mut font_name)?; self.input.by_ref().take(font_name_len as u64).read_to_string(&mut font_name)?;
let flags = self.read_u8()?; 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![]; let mut code_table = vec![];
if use_wide_codes { if use_wide_codes {
while let Ok(code) = self.read_u16() { while let Ok(code) = self.read_u16() {
@ -952,12 +973,14 @@ impl<R: Read> Reader<R> {
// SWF19 has ANSI and Shift-JIS backwards? // SWF19 has ANSI and Shift-JIS backwards?
Ok(Tag::DefineFontInfo(Box::new(FontInfo { Ok(Tag::DefineFontInfo(Box::new(FontInfo {
id: id, id: id,
version: version,
name: font_name, name: font_name,
is_small_text: flags & 0b100000 != 0, is_small_text: flags & 0b100000 != 0,
is_ansi: flags & 0b10000 != 0, is_ansi: flags & 0b10000 != 0,
is_shift_jis: flags & 0b1000 != 0, is_shift_jis: flags & 0b1000 != 0,
is_italic: flags & 0b100 != 0, is_italic: flags & 0b100 != 0,
is_bold: flags & 0b10 != 0, is_bold: flags & 0b10 != 0,
language: language,
code_table: code_table, code_table: code_table,
}))) })))
} }

View File

@ -302,17 +302,36 @@ pub fn tag_tests() -> Vec<TagTestData> { vec![
1, 1,
Tag::DefineFontInfo(Box::new(FontInfo { Tag::DefineFontInfo(Box::new(FontInfo {
id: 1, id: 1,
version: 1,
name: "Verdana".to_string(), name: "Verdana".to_string(),
is_small_text: false, is_small_text: false,
is_ansi: true, is_ansi: true,
is_shift_jis: false, is_shift_jis: false,
is_italic: false, is_italic: false,
is_bold: false, is_bold: false,
language: Language::Unknown,
code_table: vec![45, 95], code_table: vec![45, 95],
})), })),
read_tag_bytes_from_file("tests/swfs/DefineFont-MX.swf", TagCode::DefineFontInfo) 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, 8,
Tag::DefineScalingGrid { Tag::DefineScalingGrid {

View File

@ -85,6 +85,16 @@ impl Matrix {
} }
} }
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Language {
Unknown,
Latin,
Japanese,
Korean,
SimplifiedChinese,
TraditionalChinese,
}
#[derive(Debug,PartialEq)] #[derive(Debug,PartialEq)]
pub struct FileAttributes { pub struct FileAttributes {
pub use_direct_blit: bool, pub use_direct_blit: bool,
@ -405,13 +415,13 @@ pub struct Sprite {
pub tags: Vec<Tag>, pub tags: Vec<Tag>,
} }
#[derive(Debug,PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct ShapeStyles { pub struct ShapeStyles {
pub fill_styles: Vec<FillStyle>, pub fill_styles: Vec<FillStyle>,
pub line_styles: Vec<LineStyle>, pub line_styles: Vec<LineStyle>,
} }
#[derive(Debug,PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum ShapeRecord { pub enum ShapeRecord {
// TODO: Twips // TODO: Twips
StyleChange(StyleChangeData), StyleChange(StyleChangeData),
@ -424,7 +434,7 @@ pub enum ShapeRecord {
}, },
} }
#[derive(Debug,PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct StyleChangeData { pub struct StyleChangeData {
pub move_to: Option<(f32, f32)>, pub move_to: Option<(f32, f32)>,
pub fill_style_0: Option<u32>, pub fill_style_0: Option<u32>,
@ -609,7 +619,7 @@ pub enum ButtonActionCondition {
KeyPress KeyPress
} }
#[derive(Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Font { pub struct Font {
pub id: CharacterId, pub id: CharacterId,
pub glyphs: Vec<Glyph>, pub glyphs: Vec<Glyph>,
@ -618,12 +628,14 @@ pub struct Font {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct FontInfo { pub struct FontInfo {
pub id: CharacterId, pub id: CharacterId,
pub version: u8,
pub name: String, pub name: String,
pub is_small_text: bool, pub is_small_text: bool,
pub is_shift_jis: bool, pub is_shift_jis: bool,
pub is_ansi: bool, pub is_ansi: bool,
pub is_bold: bool, pub is_bold: bool,
pub is_italic: bool, pub is_italic: bool,
pub language: Language,
pub code_table: Vec<u16>, pub code_table: Vec<u16>,
} }

View File

@ -384,6 +384,17 @@ impl<W: Write> Writer<W> {
Ok(()) 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<()> { fn write_tag(&mut self, tag: &Tag) -> Result<()> {
match tag { match tag {
&Tag::ShowFrame => try!(self.write_tag_header(TagCode::ShowFrame, 0)), &Tag::ShowFrame => try!(self.write_tag_header(TagCode::ShowFrame, 0)),
@ -536,13 +547,16 @@ impl<W: Write> Writer<W> {
}, },
&Tag::DefineFontInfo(ref font_info) => { &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() + let len = font_info.name.len() +
if use_wide_codes { 2 } else { 1 } * font_info.code_table.len() + if use_wide_codes { 2 } else { 1 } * font_info.code_table.len() +
if font_info.version >= 2 { 1 } else { 0 } +
4; 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)?; self.write_u16(font_info.id)?;
// SWF19 has ANSI and Shift-JIS backwards? // SWF19 has ANSI and Shift-JIS backwards?
@ -556,6 +570,10 @@ impl<W: Write> Writer<W> {
if font_info.is_bold { 0b10 } else { 0 } | if font_info.is_bold { 0b10 } else { 0 } |
if use_wide_codes { 0b1 } 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 { for &code in &font_info.code_table {
if use_wide_codes { if use_wide_codes {
self.write_u16(code)?; self.write_u16(code)?;

Binary file not shown.

Binary file not shown.