diff --git a/core/src/html/layout.rs b/core/src/html/layout.rs
index c4ef734e5..7ca634b94 100644
--- a/core/src/html/layout.rs
+++ b/core/src/html/layout.rs
@@ -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,
diff --git a/core/src/library.rs b/core/src/library.rs
index 10ae6b5fc..2517e54e1 100644
--- a/core/src/library.rs
+++ b/core/src/library.rs
@@ -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})");
- }
-
- // 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);
- }
-
- None
+ // 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.
+ if let Some(font) = self.device_fonts.get(name, is_bold, is_italic) {
+ return Some(*font);
}
- Some(font) => Some(*font),
+
+ warn!("Unknown device font \"{name}\" (bold: {is_bold}, italic: {is_italic})");
}
+
+ None
+ }
+
+ /// 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> {
+ // 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) {