core: Edit text uses device fonts when outline flag isn't set
Specifically fall back to the device font when the UseOutlines flag is not set in DefineEditText (SWF19 p.172). Fixes #451. Note that since we only use a single font for "device" rendering, this may sometimes be a different font than is specified in the Flash IDE.
This commit is contained in:
parent
1ba60ebd67
commit
068f4c3bee
|
@ -3,7 +3,7 @@ use crate::avm1::globals::text_field::attach_virtual_properties;
|
||||||
use crate::avm1::{Object, StageObject, Value};
|
use crate::avm1::{Object, StageObject, Value};
|
||||||
use crate::context::{RenderContext, UpdateContext};
|
use crate::context::{RenderContext, UpdateContext};
|
||||||
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
||||||
use crate::font::{Glyph, TextFormat};
|
use crate::font::{Font, Glyph, TextFormat};
|
||||||
use crate::library::Library;
|
use crate::library::Library;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::tag_utils::SwfMovie;
|
use crate::tag_utils::SwfMovie;
|
||||||
|
@ -291,21 +291,9 @@ impl<'gc> EditText<'gc> {
|
||||||
fn line_breaks(self, library: &Library<'gc>) -> Vec<usize> {
|
fn line_breaks(self, library: &Library<'gc>) -> Vec<usize> {
|
||||||
let edit_text = self.0.read();
|
let edit_text = self.0.read();
|
||||||
let static_data = &edit_text.static_data;
|
let static_data = &edit_text.static_data;
|
||||||
let font_id = static_data.text.font_id.unwrap_or(0);
|
|
||||||
|
|
||||||
if edit_text.is_multiline {
|
if edit_text.is_multiline {
|
||||||
if let Some(font) = library
|
if let Some(font) = self.font(library) {
|
||||||
.library_for_movie(self.movie().unwrap())
|
|
||||||
.unwrap()
|
|
||||||
.get_font(font_id)
|
|
||||||
.filter(|font| font.has_glyphs())
|
|
||||||
.or_else(|| {
|
|
||||||
library
|
|
||||||
.library_for_movie(self.movie().unwrap())
|
|
||||||
.unwrap()
|
|
||||||
.device_font()
|
|
||||||
})
|
|
||||||
{
|
|
||||||
let mut breakpoints = vec![];
|
let mut breakpoints = vec![];
|
||||||
let mut break_base = 0;
|
let mut break_base = 0;
|
||||||
let height = static_data
|
let height = static_data
|
||||||
|
@ -368,24 +356,10 @@ impl<'gc> EditText<'gc> {
|
||||||
|
|
||||||
let edit_text = self.0.read();
|
let edit_text = self.0.read();
|
||||||
let static_data = &edit_text.static_data;
|
let static_data = &edit_text.static_data;
|
||||||
let font_id = static_data.text.font_id.unwrap_or(0);
|
|
||||||
|
|
||||||
let mut size: (Twips, Twips) = Default::default();
|
let mut size: (Twips, Twips) = Default::default();
|
||||||
|
|
||||||
if let Some(font) = context
|
if let Some(font) = self.font(context.library) {
|
||||||
.library
|
|
||||||
.library_for_movie(self.movie().unwrap())
|
|
||||||
.unwrap()
|
|
||||||
.get_font(font_id)
|
|
||||||
.filter(|font| font.has_glyphs())
|
|
||||||
.or_else(|| {
|
|
||||||
context
|
|
||||||
.library
|
|
||||||
.library_for_movie(self.movie().unwrap())
|
|
||||||
.unwrap()
|
|
||||||
.device_font()
|
|
||||||
})
|
|
||||||
{
|
|
||||||
let mut start = 0;
|
let mut start = 0;
|
||||||
let mut chunks = vec![];
|
let mut chunks = vec![];
|
||||||
for breakpoint in breakpoints {
|
for breakpoint in breakpoints {
|
||||||
|
@ -413,6 +387,25 @@ impl<'gc> EditText<'gc> {
|
||||||
|
|
||||||
size
|
size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the device font if this is text field should not use outline glyphs,
|
||||||
|
/// or if the font is not found.
|
||||||
|
fn font(&self, library: &Library<'gc>) -> Option<Font<'gc>> {
|
||||||
|
let static_data = self.0.read().static_data;
|
||||||
|
let library = library.library_for_movie(static_data.swf.clone()).unwrap();
|
||||||
|
if static_data.text.is_device_font {
|
||||||
|
// We're cheating a bit and not actually rendering "device text" using the OS/web.
|
||||||
|
// Instead, we embed an SWF version of Noto Sans to use as the "device font", and render
|
||||||
|
// it the same as any other SWF outline text.
|
||||||
|
library.device_font()
|
||||||
|
} else {
|
||||||
|
let font_id = static_data.text.font_id.unwrap_or_default();
|
||||||
|
library
|
||||||
|
.get_font(font_id)
|
||||||
|
.filter(|font| font.has_glyphs())
|
||||||
|
.or_else(|| library.device_font())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
|
impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
|
||||||
|
@ -470,21 +463,12 @@ impl<'gc> TDisplayObject<'gc> for EditText<'gc> {
|
||||||
|
|
||||||
let edit_text = self.0.read();
|
let edit_text = self.0.read();
|
||||||
let static_data = &edit_text.static_data;
|
let static_data = &edit_text.static_data;
|
||||||
let font_id = static_data.text.font_id.unwrap_or(0);
|
|
||||||
|
|
||||||
// If the font can't be found or has no glyph information, use the "device font" instead.
|
// If the font can't be found or has no glyph information, use the "device font" instead.
|
||||||
// We're cheating a bit and not actually rendering text using the OS/web.
|
// We're cheating a bit and not actually rendering text using the OS/web.
|
||||||
// Instead, we embed an SWF version of Noto Sans to use as the "device font", and render
|
// Instead, we embed an SWF version of Noto Sans to use as the "device font", and render
|
||||||
// it the same as any other SWF outline text.
|
// it the same as any other SWF outline text.
|
||||||
let library = context
|
if let Some(font) = self.font(context.library) {
|
||||||
.library
|
|
||||||
.library_for_movie(edit_text.static_data.swf.clone())
|
|
||||||
.unwrap();
|
|
||||||
if let Some(font) = library
|
|
||||||
.get_font(font_id)
|
|
||||||
.filter(|font| font.has_glyphs())
|
|
||||||
.or_else(|| library.device_font())
|
|
||||||
{
|
|
||||||
let height = static_data
|
let height = static_data
|
||||||
.text
|
.text
|
||||||
.height
|
.height
|
||||||
|
|
Loading…
Reference in New Issue