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;
|
// 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(
|
if let Some(font) = context.library.get_or_load_device_font(
|
||||||
&font_name,
|
&font_name,
|
||||||
span.bold,
|
span.bold,
|
||||||
|
@ -497,19 +521,13 @@ impl<'a, 'gc> LayoutContext<'a, 'gc> {
|
||||||
return Some(font);
|
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
|
// 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
|
context
|
||||||
.library
|
.library
|
||||||
.default_font(
|
.default_font(
|
||||||
default_font,
|
DefaultFont::Serif,
|
||||||
span.bold,
|
span.bold,
|
||||||
span.italic,
|
span.italic,
|
||||||
context.ui,
|
context.ui,
|
||||||
|
|
|
@ -456,21 +456,31 @@ impl<'gc> Library<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
|
// First try to find any exactly matching fonts.
|
||||||
for name in self.default_font_names.entry(name).or_default().clone() {
|
for name in self.default_font_names.entry(name).or_default().clone() {
|
||||||
if let Some(font) =
|
if let Some(font) = self
|
||||||
self.get_or_load_device_font(&name, is_bold, is_italic, ui, renderer, gc_context)
|
.get_or_load_exact_device_font(&name, is_bold, is_italic, ui, renderer, gc_context)
|
||||||
{
|
{
|
||||||
result.push(font);
|
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
|
self.default_font_cache
|
||||||
.insert((name, is_bold, is_italic), result.clone());
|
.insert((name, is_bold, is_italic), result.clone());
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the device font for use when a font is unavailable.
|
/// Returns the device font exactly matching the requested options.
|
||||||
pub fn get_or_load_device_font(
|
fn get_or_load_exact_device_font(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
is_bold: bool,
|
is_bold: bool,
|
||||||
|
@ -494,26 +504,38 @@ impl<'gc> Library<'gc> {
|
||||||
ui.load_device_font(name, is_bold, is_italic, &mut |definition| {
|
ui.load_device_font(name, is_bold, is_italic, &mut |definition| {
|
||||||
self.register_device_font(gc_context, renderer, definition)
|
self.register_device_font(gc_context, renderer, definition)
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Check again. A backend may or may not have provided some new fonts,
|
// 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.
|
// 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) {
|
if let Some(font) = self.device_fonts.get(name, is_bold, is_italic) {
|
||||||
None => {
|
return Some(*font);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
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<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>) {
|
pub fn set_default_font(&mut self, font: DefaultFont, names: Vec<String>) {
|
||||||
|
|
Loading…
Reference in New Issue