From 0ca29399abbb0b355e8c9c0e645a1eb788c080e7 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Mon, 12 Oct 2026 19:05:32 -0400 Subject: [PATCH] =?UTF-8?q?Fonts:=20Office=20cloud=20fonts=20(Aptos?= =?UTF-8?q?=E2=80=A6)=20keep=20their=20open=20substitute?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 (1M context) --- crates/fonts/src/fontdb.rs | 10 +++++++++- crates/fonts/src/lib.rs | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/fonts/src/fontdb.rs b/crates/fonts/src/fontdb.rs index 8bdc044..3a28ce1 100644 --- a/crates/fonts/src/fontdb.rs +++ b/crates/fonts/src/fontdb.rs @@ -87,6 +87,14 @@ fn office_twin(family: &str) -> Option<&'static str> { }) } +/// Office's downloadable (cloud) families: PowerPoint fetches them when a document uses them, so +/// they draw as themselves there, not as Calibri. Without them DeckCraft keeps their closest open +/// substitute ([`substitutes`]; Aptos as Inter). +fn is_office_cloud_font(family: &str) -> bool { + let f = family.to_ascii_lowercase(); + f.starts_with("aptos") || ["bierstadt", "grandview", "seaford", "skeena", "tenorite"].iter().any(|c| f.starts_with(c)) +} + /// The family PowerPoint draws a document's Latin text in when the font it names isn't installed, /// whatever the theme, `panose` or `pitchFamily` say. pub const MISSING_FONT_FAMILY: &str = "Calibri"; @@ -831,7 +839,7 @@ impl FontDb { /// see `office_twin`); any other missing family is drawn in Calibri (or Carlito). /// DeckCraft's own default family keeps [`FontDb::face`]'s fallbacks. pub fn document_face(&self, family: &str, style: &str) -> Arc { - if family.eq_ignore_ascii_case(FALLBACK_FAMILY) || has_metric_twin(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) { diff --git a/crates/fonts/src/lib.rs b/crates/fonts/src/lib.rs index 7e32fc6..16be2ca 100644 --- a/crates/fonts/src/lib.rs +++ b/crates/fonts/src/lib.rs @@ -237,7 +237,8 @@ mod tests { } } // Metric-compatible stand-ins and DeckCraft's default keep their own fallbacks. - for kept in ["Arial", "Times New Roman", "Cambria", "Courier New", FALLBACK_FAMILY] { + // So do Office's cloud fonts, which PowerPoint downloads and draws as themselves. + for kept in ["Arial", "Times New Roman", "Cambria", "Courier New", FALLBACK_FAMILY, "Aptos", "Aptos Display", "Grandview"] { assert_eq!(db.document_face(kept, "Regular").family, db.face(kept, "Regular").family, "{kept}"); } }