core: Explicitly match and use default fonts, before loading device fonts
This commit is contained in:
parent
f47e15b68c
commit
b34d3c9ad2
|
@ -486,6 +486,30 @@ impl<'a, 'gc> LayoutContext<'a, 'gc> {
|
|||
// return None;
|
||||
}
|
||||
|
||||
// For better compatibility we also match the font-family name usually
|
||||
// used for that specific default font.
|
||||
if let Some(default_font) = match font_name.deref() {
|
||||
"_serif" | "Times New Roman" | "" => Some(DefaultFont::Serif),
|
||||
"_sans" | "Arial" => Some(DefaultFont::Sans),
|
||||
"_typewriter" | "Courier New" => Some(DefaultFont::Typewriter),
|
||||
// [NA] I suspect that there might be undocumented more aliases.
|
||||
// I think I've seen translated versions of these used in the wild...
|
||||
_ => None,
|
||||
} {
|
||||
return context
|
||||
.library
|
||||
.default_font(
|
||||
default_font,
|
||||
span.bold,
|
||||
span.italic,
|
||||
context.ui,
|
||||
context.renderer,
|
||||
context.gc_context,
|
||||
)
|
||||
.first()
|
||||
.copied();
|
||||
}
|
||||
|
||||
if let Some(font) = context.library.get_or_load_device_font(
|
||||
&font_name,
|
||||
span.bold,
|
||||
|
@ -497,19 +521,13 @@ impl<'a, 'gc> LayoutContext<'a, 'gc> {
|
|||
return Some(font);
|
||||
}
|
||||
|
||||
// [NA] I suspect that there might be undocumented more aliases.
|
||||
// I think I've seen translated versions of these used in the wild...
|
||||
let default_font = match font_name.deref() {
|
||||
"_serif" => DefaultFont::Serif,
|
||||
"_typewriter" => DefaultFont::Typewriter,
|
||||
_ => DefaultFont::Sans,
|
||||
};
|
||||
|
||||
// TODO: handle multiple fonts for a definition, each covering different sets of glyphs
|
||||
|
||||
// Use the default serif font, when no other matching font was found.
|
||||
context
|
||||
.library
|
||||
.default_font(
|
||||
default_font,
|
||||
DefaultFont::Serif,
|
||||
span.bold,
|
||||
span.italic,
|
||||
context.ui,
|
||||
|
|
|
@ -456,21 +456,31 @@ impl<'gc> Library<'gc> {
|
|||
}
|
||||
|
||||
let mut result = vec![];
|
||||
// First try to find any exactly matching fonts.
|
||||
for name in self.default_font_names.entry(name).or_default().clone() {
|
||||
if let Some(font) =
|
||||
self.get_or_load_device_font(&name, is_bold, is_italic, ui, renderer, gc_context)
|
||||
if let Some(font) = self
|
||||
.get_or_load_exact_device_font(&name, is_bold, is_italic, ui, renderer, gc_context)
|
||||
{
|
||||
result.push(font);
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing found, try a compatible font.
|
||||
if result.is_empty() {
|
||||
for name in self.default_font_names.entry(name).or_default().clone() {
|
||||
if let Some(font) = self.device_fonts.find(&name, is_bold, is_italic) {
|
||||
result.push(font);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.default_font_cache
|
||||
.insert((name, is_bold, is_italic), result.clone());
|
||||
result
|
||||
}
|
||||
|
||||
/// Returns the device font for use when a font is unavailable.
|
||||
pub fn get_or_load_device_font(
|
||||
/// Returns the device font exactly matching the requested options.
|
||||
fn get_or_load_exact_device_font(
|
||||
&mut self,
|
||||
name: &str,
|
||||
is_bold: bool,
|
||||
|
@ -494,26 +504,38 @@ impl<'gc> Library<'gc> {
|
|||
ui.load_device_font(name, is_bold, is_italic, &mut |definition| {
|
||||
self.register_device_font(gc_context, renderer, definition)
|
||||
});
|
||||
}
|
||||
|
||||
// Check again. A backend may or may not have provided some new fonts,
|
||||
// and they may or may not be relevant to the one we're asking for.
|
||||
match self.device_fonts.get(name, is_bold, is_italic) {
|
||||
None => {
|
||||
if new_request {
|
||||
warn!("Unknown device font \"{name}\" (bold: {is_bold} italic: {is_italic})");
|
||||
if let Some(font) = self.device_fonts.get(name, is_bold, is_italic) {
|
||||
return Some(*font);
|
||||
}
|
||||
|
||||
// The default fallback:
|
||||
// Try to find an existing font to re-use instead of giving up.
|
||||
if let Some(font) = self.device_fonts.find(name, is_bold, is_italic) {
|
||||
return Some(font);
|
||||
warn!("Unknown device font \"{name}\" (bold: {is_bold}, italic: {is_italic})");
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
Some(font) => Some(*font),
|
||||
|
||||
/// Returns the device font compatible with the requested options.
|
||||
pub fn get_or_load_device_font(
|
||||
&mut self,
|
||||
name: &str,
|
||||
is_bold: bool,
|
||||
is_italic: bool,
|
||||
ui: &dyn UiBackend,
|
||||
renderer: &mut dyn RenderBackend,
|
||||
gc_context: &Mutation<'gc>,
|
||||
) -> Option<Font<'gc>> {
|
||||
// Try to find an exactly matching font.
|
||||
if let Some(font) =
|
||||
self.get_or_load_exact_device_font(name, is_bold, is_italic, ui, renderer, gc_context)
|
||||
{
|
||||
return Some(font);
|
||||
}
|
||||
|
||||
// Fallback: Try to find an existing font to re-use instead of giving up.
|
||||
self.device_fonts.find(name, is_bold, is_italic)
|
||||
}
|
||||
|
||||
pub fn set_default_font(&mut self, font: DefaultFont, names: Vec<String>) {
|
||||
|
|
Loading…
Reference in New Issue