core: Implement DefineFont4

This commit is contained in:
Tom Schuster 2024-01-14 19:41:17 +01:00
parent e0f5b8906d
commit 0a6cf92a53
4 changed files with 46 additions and 22 deletions

View File

@ -47,7 +47,7 @@ use std::cmp::max;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use swf::extensions::ReadSwfExt; use swf::extensions::ReadSwfExt;
use swf::{ClipEventFlag, FontFlag, FrameLabelData, SwfStr, TagCode}; use swf::{ClipEventFlag, FrameLabelData, TagCode};
use super::interactive::Avm2MousePick; use super::interactive::Avm2MousePick;
@ -3962,29 +3962,13 @@ impl<'gc, 'a> MovieClipData<'gc> {
context: &mut UpdateContext<'_, 'gc>, context: &mut UpdateContext<'_, 'gc>,
reader: &mut SwfStream<'a>, reader: &mut SwfStream<'a>,
) -> Result<(), Error> { ) -> Result<(), Error> {
tracing::warn!("DefineFont4 tag (TLF text) is not implemented");
let font = reader.read_define_font_4()?; let font = reader.read_define_font_4()?;
let font_id = font.id; let font_id = font.id;
let font_object = Font::from_swf_tag( let font_object = Font::from_font4_tag(context.gc_context, font, reader.encoding())?;
context.gc_context,
context.renderer,
swf::Font {
version: 4,
id: font.id,
name: SwfStr::from_bytes(b"<Unknown Font4>"),
language: swf::Language::Unknown,
layout: None,
glyphs: Vec::new(),
flags: FontFlag::empty(),
},
reader.encoding(),
FontType::EmbeddedCFF,
);
context context
.library .library
.library_for_movie_mut(self.movie()) .library_for_movie_mut(self.movie())
.register_character(font_id, Character::Font(font_object)); .register_character(font_id, Character::Font(font_object));
Ok(()) Ok(())
} }

View File

@ -381,6 +381,7 @@ impl<'gc> Font<'gc> {
descriptor: FontDescriptor, descriptor: FontDescriptor,
bytes: Cow<'static, [u8]>, bytes: Cow<'static, [u8]>,
font_index: u32, font_index: u32,
font_type: FontType,
) -> Result<Font<'gc>, ttf_parser::FaceParsingError> { ) -> Result<Font<'gc>, ttf_parser::FaceParsingError> {
let face = FontFace::new(bytes, font_index)?; let face = FontFace::new(bytes, font_index)?;
@ -393,7 +394,7 @@ impl<'gc> Font<'gc> {
leading: face.leading, leading: face.leading,
glyphs: GlyphSource::FontFace(face), glyphs: GlyphSource::FontFace(face),
descriptor, descriptor,
font_type: FontType::Device, font_type,
}, },
))) )))
} }
@ -472,6 +473,38 @@ impl<'gc> Font<'gc> {
)) ))
} }
pub fn from_font4_tag(
gc_context: &Mutation<'gc>,
tag: swf::Font4,
encoding: &'static swf::Encoding,
) -> Result<Font<'gc>, ttf_parser::FaceParsingError> {
let name = tag.name.to_str_lossy(encoding);
let descriptor = FontDescriptor::from_parts(&name, tag.is_bold, tag.is_italic);
if let Some(bytes) = tag.data {
Font::from_font_file(
gc_context,
descriptor,
Cow::Owned(bytes.to_vec()),
0,
FontType::EmbeddedCFF,
)
} else {
Ok(Font(Gc::new(
gc_context,
FontData {
scale: 1.0,
ascent: 0,
descent: 0,
leading: 0,
glyphs: GlyphSource::Empty,
descriptor,
font_type: FontType::EmbeddedCFF,
},
)))
}
}
/// Returns whether this font contains glyph shapes. /// Returns whether this font contains glyph shapes.
/// If not, this font should be rendered as a device font. /// If not, this font should be rendered as a device font.
pub fn has_glyphs(&self) -> bool { pub fn has_glyphs(&self) -> bool {

View File

@ -565,9 +565,13 @@ impl<'gc> Library<'gc> {
index, index,
} => { } => {
let descriptor = FontDescriptor::from_parts(&name, is_bold, is_italic); let descriptor = FontDescriptor::from_parts(&name, is_bold, is_italic);
if let Ok(font) = if let Ok(font) = Font::from_font_file(
Font::from_font_file(gc_context, descriptor, Cow::Owned(data), index) gc_context,
{ descriptor,
Cow::Owned(data),
index,
FontType::Device,
) {
let name = font.descriptor().name().to_owned(); let name = font.descriptor().name().to_owned();
info!("Loaded new device font \"{name}\" from file"); info!("Loaded new device font \"{name}\" from file");
self.device_fonts.register(font); self.device_fonts.register(font);

View File

@ -12,6 +12,9 @@ pub enum Error {
#[error("Couldn't register bitmap: {0}")] #[error("Couldn't register bitmap: {0}")]
InvalidBitmap(#[from] ruffle_render::error::Error), InvalidBitmap(#[from] ruffle_render::error::Error),
#[error("Couldn't register font: {0}")]
InvalidFont(#[from] ttf_parser::FaceParsingError),
#[error("Attempted to set symbol classes on movie without any")] #[error("Attempted to set symbol classes on movie without any")]
NoSymbolClasses, NoSymbolClasses,