From b0f25c9266af7e13c62f9a8c16c9d7e5955ff38a Mon Sep 17 00:00:00 2001 From: Will Brindle Date: Fri, 4 Oct 2019 21:09:24 +0100 Subject: [PATCH] swf: implement DefineText2 --- core/src/movie_clip.rs | 15 ++++++++ swf/src/read.rs | 78 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/core/src/movie_clip.rs b/core/src/movie_clip.rs index 078bd10cc..08e81b905 100644 --- a/core/src/movie_clip.rs +++ b/core/src/movie_clip.rs @@ -630,6 +630,7 @@ impl<'gc, 'a> MovieClip<'gc> { TagCode::DefineSound => self.define_sound(context, reader, tag_len), TagCode::DefineSprite => self.define_sprite(context, reader, tag_len, morph_shapes), TagCode::DefineText => self.define_text(context, reader), + TagCode::DefineText2 => self.define_text2(context, reader), TagCode::FrameLabel => { self.frame_label(context, reader, tag_len, cur_frame, &mut static_data) } @@ -1063,6 +1064,20 @@ impl<'gc, 'a> MovieClip<'gc> { Ok(()) } + #[inline] + fn define_text2( + &mut self, + context: &mut UpdateContext<'_, 'gc, '_>, + reader: &mut SwfStream<&'a [u8]>, + ) -> DecodeResult { + let text = reader.read_define_text2()?; + let text_object = Text::from_swf_tag(context, &text); + context + .library + .register_character(text.id, Character::Text(Box::new(text_object))); + Ok(()) + } + #[inline] fn frame_label( &mut self, diff --git a/swf/src/read.rs b/swf/src/read.rs index 8ba8ad983..0d6fb0612 100644 --- a/swf/src/read.rs +++ b/swf/src/read.rs @@ -401,6 +401,7 @@ impl Reader { Tag::DefineSound(Box::new(tag_reader.read_define_sound()?)) } Some(TagCode::DefineText) => Tag::DefineText(Box::new(tag_reader.read_define_text()?)), + Some(TagCode::DefineText2) => Tag::DefineText(Box::new(tag_reader.read_define_text2()?)), Some(TagCode::DefineVideoStream) => tag_reader.read_define_video_stream()?, Some(TagCode::EnableTelemetry) => { tag_reader.read_u16()?; // Reserved @@ -2447,6 +2448,26 @@ impl Reader { }) } + pub fn read_define_text2(&mut self) -> Result { + let id = self.read_character_id()?; + let bounds = self.read_rectangle()?; + let matrix = self.read_matrix()?; + let num_glyph_bits = self.read_u8()?; + let num_advance_bits = self.read_u8()?; + + let mut records = vec![]; + while let Some(record) = self.read_text_record2(num_glyph_bits, num_advance_bits)? { + records.push(record); + } + + Ok(Text { + id, + bounds, + matrix, + records, + }) + } + fn read_text_record( &mut self, num_glyph_bits: u8, @@ -2504,6 +2525,63 @@ impl Reader { })) } + fn read_text_record2( + &mut self, + num_glyph_bits: u8, + num_advance_bits: u8, + ) -> Result> { + let flags = self.read_u8()?; + + if flags == 0 { + // End of text records. + return Ok(None); + } + + let font_id = if flags & 0b1000 != 0 { + Some(self.read_character_id()?) + } else { + None + }; + let color = if flags & 0b100 != 0 { + Some(self.read_rgba()?) + } else { + None + }; + let x_offset = if flags & 0b1 != 0 { + Some(Twips::new(self.read_i16()?)) + } else { + None + }; + let y_offset = if flags & 0b10 != 0 { + Some(Twips::new(self.read_i16()?)) + } else { + None + }; + let height = if flags & 0b1000 != 0 { + Some(self.read_u16()?) + } else { + None + }; + // TODO(Herschel): font_id and height are tied together. Merge them into a struct? + let num_glyphs = self.read_u8()?; + let mut glyphs = Vec::with_capacity(num_glyphs as usize); + for _ in 0..num_glyphs { + glyphs.push(GlyphEntry { + index: self.read_ubits(num_glyph_bits as usize)?, + advance: self.read_sbits(num_advance_bits as usize)?, + }); + } + + Ok(Some(TextRecord { + font_id, + color, + x_offset, + y_offset, + height, + glyphs, + })) + } + fn read_define_edit_text(&mut self) -> Result { let id = self.read_character_id()?; let bounds = self.read_rectangle()?;