swf: Use bitflags for `FontInfoFlag`

This commit is contained in:
relrelb 2022-03-18 15:51:03 +02:00 committed by Mike Welsh
parent fd06fa0537
commit 71b0a6e32e
4 changed files with 62 additions and 64 deletions

View File

@ -1211,9 +1211,8 @@ impl<'a> Reader<'a> {
fn read_define_font_info(&mut self, version: u8) -> Result<Tag<'a>> {
let id = self.read_u16()?;
let font_name = self.read_str_with_len()?;
let flags = self.read_u8()?;
let use_wide_codes = flags & 0b1 != 0; // TODO(Herschel): Warn if false for version 2.
let name = self.read_str_with_len()?;
let flags = FontInfoFlag::from_bits_truncate(self.read_u8()?);
let language = if version >= 2 {
self.read_language()?
@ -1222,11 +1221,12 @@ impl<'a> Reader<'a> {
};
let mut code_table = vec![];
if use_wide_codes {
if flags.contains(FontInfoFlag::HAS_WIDE_CODES) {
while let Ok(code) = self.read_u16() {
code_table.push(code);
}
} else {
// TODO(Herschel): Warn for version 2.
while let Ok(code) = self.read_u8() {
code_table.push(code.into());
}
@ -1236,12 +1236,8 @@ impl<'a> Reader<'a> {
Ok(Tag::DefineFontInfo(Box::new(FontInfo {
id,
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,
name,
flags,
language,
code_table,
})))

View File

@ -655,11 +655,7 @@ pub fn tag_tests() -> Vec<TagTestData> {
id: 1,
version: 1,
name: SwfStr::from_str_with_encoding("Verdana", WINDOWS_1252).unwrap(),
is_small_text: false,
is_ansi: true,
is_shift_jis: false,
is_italic: false,
is_bold: false,
flags: FontInfoFlag::IS_ANSI,
language: Language::Unknown,
code_table: vec![45, 95],
})),
@ -671,11 +667,10 @@ pub fn tag_tests() -> Vec<TagTestData> {
id: 1,
version: 2,
name: "Verdana".into(),
is_small_text: false,
is_ansi: true,
is_shift_jis: false,
is_italic: true,
is_bold: true,
flags: FontInfoFlag::HAS_WIDE_CODES
| FontInfoFlag::IS_BOLD
| FontInfoFlag::IS_ITALIC
| FontInfoFlag::IS_ANSI,
language: Language::Latin,
code_table: vec![45, 95],
})),

View File

@ -1375,15 +1375,22 @@ pub struct FontInfo<'a> {
pub id: CharacterId,
pub version: u8,
pub name: &'a SwfStr,
pub is_small_text: bool,
pub is_shift_jis: bool,
pub is_ansi: bool,
pub is_bold: bool,
pub is_italic: bool,
pub flags: FontInfoFlag,
pub language: Language,
pub code_table: Vec<u16>,
}
bitflags! {
pub struct FontInfoFlag: u8 {
const HAS_WIDE_CODES = 1 << 0;
const IS_BOLD = 1 << 1;
const IS_ITALIC = 1 << 2;
const IS_SHIFT_JIS = 1 << 3;
const IS_ANSI = 1 << 4;
const IS_SMALL_TEXT = 1 << 5;
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct DefineBinaryData<'a> {
pub id: CharacterId,

View File

@ -667,45 +667,7 @@ impl<W: Write> Writer<W> {
}
}
Tag::DefineFontInfo(ref font_info) => {
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;
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?
self.write_u8(font_info.name.len() as u8)?;
self.output.write_all(font_info.name.as_bytes())?;
self.write_u8(
if font_info.is_small_text { 0b100000 } else { 0 }
| if font_info.is_ansi { 0b10000 } else { 0 }
| if font_info.is_shift_jis { 0b1000 } else { 0 }
| if font_info.is_italic { 0b100 } else { 0 }
| 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)?;
} else {
self.write_u8(code as u8)?;
}
}
}
Tag::DefineFontInfo(ref font_info) => self.write_define_font_info(font_info)?,
Tag::DefineFontName {
id,
@ -2212,6 +2174,44 @@ impl<W: Write> Writer<W> {
Ok(())
}
fn write_define_font_info(&mut self, font_info: &FontInfo) -> Result<()> {
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;
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?
self.write_u8(font_info.name.len() as u8)?;
self.output.write_all(font_info.name.as_bytes())?;
let mut flags = font_info.flags;
flags.set(FontInfoFlag::HAS_WIDE_CODES, use_wide_codes);
self.write_u8(flags.bits())?;
// 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)?;
} else {
self.write_u8(code as u8)?;
}
}
Ok(())
}
fn write_kerning_record(
&mut self,
kerning: &KerningRecord,