mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-02 06:57:04 -06:00
Fonts: refine monospace heuristic and preserve office_twin order (#1598)
- Avoid false-positive monospace match on 'code' in split_whitespace for proportional families like Code Pro. - Check office_twin before is_monospace_family in document_face so alias families like Courier New CE resolve to Courier New when installed. - Add negative tests for Code Pro and test Courier New CE mapping. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -105,7 +105,7 @@ pub fn is_monospace_family(family: &str) -> bool {
|
||||
|| s.ends_with(" console")
|
||||
|| s.ends_with(" typewriter")
|
||||
|| s.ends_with(" monospace")
|
||||
|| s.split_whitespace().any(|w| w == "mono" || w == "code" || w == "terminal" || w == "monospace")
|
||||
|| s.split_whitespace().any(|w| w == "mono" || w == "terminal" || w == "monospace")
|
||||
}
|
||||
|
||||
/// Families whose open substitutes ([`substitutes`]) keep their metrics, so text drawn with
|
||||
@@ -1149,17 +1149,15 @@ impl FontDb {
|
||||
/// Monospaced families keep a monospaced substitute instead of falling back to Calibri.
|
||||
/// DeckCraft's own default family keeps [`FontDb::face`]'s fallbacks.
|
||||
pub fn document_face(&self, family: &str, style: &str) -> Arc<FontFace> {
|
||||
if family.eq_ignore_ascii_case(FALLBACK_FAMILY)
|
||||
|| has_metric_twin(family)
|
||||
|| is_monospace_family(family)
|
||||
|| is_office_cloud_font(family)
|
||||
|| self.has_family(family)
|
||||
{
|
||||
if family.eq_ignore_ascii_case(FALLBACK_FAMILY) || has_metric_twin(family) || is_office_cloud_font(family) || self.has_family(family) {
|
||||
return self.face(family, style);
|
||||
}
|
||||
if let Some(twin) = office_twin(family) {
|
||||
return self.face(twin, style);
|
||||
}
|
||||
if is_monospace_family(family) {
|
||||
return self.face(family, style);
|
||||
}
|
||||
self.face(MISSING_FONT_FAMILY, style)
|
||||
}
|
||||
|
||||
|
||||
@@ -216,9 +216,13 @@ fn missing_document_fonts_are_drawn_in_calibri() {
|
||||
assert_eq!(f.family, db.face(MISSING_FONT_FAMILY, "Bold").family, "{missing:?}");
|
||||
}
|
||||
// PowerPoint's own twins and Windows' substitutes, when the font itself is missing.
|
||||
for (missing, twin) in
|
||||
[("Liberation Sans", "Arial"), ("Liberation Serif", "Times New Roman"), ("Arial CE", "Arial"), ("Times New Roman CYR", "Times New Roman")]
|
||||
{
|
||||
for (missing, twin) in [
|
||||
("Liberation Sans", "Arial"),
|
||||
("Liberation Serif", "Times New Roman"),
|
||||
("Arial CE", "Arial"),
|
||||
("Times New Roman CYR", "Times New Roman"),
|
||||
("Courier New CE", "Courier New"),
|
||||
] {
|
||||
if !db.has_family(missing) {
|
||||
assert_eq!(db.document_face(missing, "Regular").family, db.face(twin, "Regular").family, "{missing}");
|
||||
}
|
||||
@@ -261,7 +265,7 @@ fn office_fonts_have_substitutes() {
|
||||
assert!(is_monospace_family(mono), "{mono} should be recognized as monospace");
|
||||
}
|
||||
|
||||
for prop in ["Calibri", "Arial", "Times New Roman", "Inter", "Monotype Corsiva", "Monotype Baskerville", "zzz"] {
|
||||
for prop in ["Calibri", "Arial", "Times New Roman", "Inter", "Monotype Corsiva", "Monotype Baskerville", "Code Pro", "zzz"] {
|
||||
assert!(!is_monospace_family(prop), "{prop} should not be recognized as monospace");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user