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::sync::Arc;
use swf::extensions::ReadSwfExt;
use swf::{ClipEventFlag, FontFlag, FrameLabelData, SwfStr, TagCode};
use swf::{ClipEventFlag, FrameLabelData, TagCode};
use super::interactive::Avm2MousePick;
@ -3962,29 +3962,13 @@ impl<'gc, 'a> MovieClipData<'gc> {
context: &mut UpdateContext<'_, 'gc>,
reader: &mut SwfStream<'a>,
) -> Result<(), Error> {
tracing::warn!("DefineFont4 tag (TLF text) is not implemented");
let font = reader.read_define_font_4()?;
let font_id = font.id;
let font_object = Font::from_swf_tag(
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,
);
let font_object = Font::from_font4_tag(context.gc_context, font, reader.encoding())?;
context
.library
.library_for_movie_mut(self.movie())
.register_character(font_id, Character::Font(font_object));
Ok(())
}

View File

@ -381,6 +381,7 @@ impl<'gc> Font<'gc> {
descriptor: FontDescriptor,
bytes: Cow<'static, [u8]>,
font_index: u32,
font_type: FontType,
) -> Result<Font<'gc>, ttf_parser::FaceParsingError> {
let face = FontFace::new(bytes, font_index)?;
@ -393,7 +394,7 @@ impl<'gc> Font<'gc> {
leading: face.leading,
glyphs: GlyphSource::FontFace(face),
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.
/// If not, this font should be rendered as a device font.
pub fn has_glyphs(&self) -> bool {

View File

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

View File

@ -12,6 +12,9 @@ pub enum Error {
#[error("Couldn't register bitmap: {0}")]
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")]
NoSymbolClasses,