From d35db792dcf7034b88d34e1368edde6f9319f7f5 Mon Sep 17 00:00:00 2001 From: Matthew Farrow Date: Fri, 9 Oct 2026 10:29:11 -0400 Subject: [PATCH] PDF tests: the system-fonts test checks the first installed family that stays live text The test took the first installed family that isn't bundled and expected its PDF text to stay live. The PDF doesn't embed the font, so the page draws a stand-in and text stays live only where the installed font's glyphs match it. With suitcase fonts now found, the first family on a Mac is a condensed display face whose glyphs don't, so the importer rightly kept outlines and the test failed. Which family comes first depends on the machine's fonts: the test now tries up to 200 families and checks the first that stays live. Co-Authored-By: Claude Sonnet 5.5 --- crates/pdf/tests/system_fonts.rs | 41 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/crates/pdf/tests/system_fonts.rs b/crates/pdf/tests/system_fonts.rs index 262c4bde..b3eaa7bd 100644 --- a/crates/pdf/tests/system_fonts.rs +++ b/crates/pdf/tests/system_fonts.rs @@ -14,21 +14,36 @@ fn a_fresh_session_resolves_pdf_fonts_to_installed_families() { let probe = FontDb::with_font_dirs(system_font_dirs()); probe.load_system_fonts(); let installed = probe.families(); - // A family whose PDF name is its name without the spaces (as "TimesNewRoman"). - let Some(family) = installed.iter().find(|f| !bundled.contains(f) && f.contains(' ') && f.chars().all(|c| c.is_ascii_alphanumeric() || c == ' ')) - else { + // Families whose PDF name is their name without the spaces (as "TimesNewRoman"). The font + // isn't embedded, so the page draws a stand-in; text stays live only where the installed + // font's glyphs match it, as a plain sans-serif's do and a condensed display face's don't: + // which family that is depends on the machine's fonts, so the first of them to do is checked. + let candidates: Vec<&String> = installed + .iter() + .filter(|f| !bundled.contains(f) && f.contains(' ') && f.chars().all(|c| c.is_ascii_alphanumeric() || c == ' ')) + .take(200) + .collect(); + if candidates.is_empty() { eprintln!("no system fonts installed: nothing to check"); return; + } + let import = |family: &str| { + let resources = format!("/Font << /F1 << /Type /Font /Subtype /TrueType /BaseFont /{} >> >>", family.replace(' ', "")); + let page = PdfPage { resources, ..PdfPage::new(100.0, 100.0, "BT /F1 12 Tf 10 30 Td (Hi) Tj ET") }; + let r = import_with_report(&pdf_with(&[page], &[], None), &ImportOptions::default()).unwrap(); + let mut families = vec![]; + r.document.walk(|n| { + if let NodeKind::Text(t) = &n.kind { + families.extend(t.runs.iter().map(|r| r.style.font_family.clone())); + } + }); + (families, r.warnings) }; - let resources = format!("/Font << /F1 << /Type /Font /Subtype /TrueType /BaseFont /{} >> >>", family.replace(' ', "")); - let page = PdfPage { resources, ..PdfPage::new(100.0, 100.0, "BT /F1 12 Tf 10 30 Td (Hi) Tj ET") }; - let r = import_with_report(&pdf_with(&[page], &[], None), &ImportOptions::default()).unwrap(); - let mut families = vec![]; - r.document.walk(|n| { - if let NodeKind::Text(t) = &n.kind { - families.extend(t.runs.iter().map(|r| r.style.font_family.clone())); - } + let found = candidates.iter().find_map(|family| { + let (families, warnings) = import(family); + (!families.is_empty()).then_some((family, families, warnings)) }); - assert_eq!(families, std::slice::from_ref(family)); - assert!(!r.warnings.iter().any(|w| w.contains(family.as_str())), "{:?}", r.warnings); + let (family, families, warnings) = found.expect("one of the installed families stays live text"); + assert_eq!(families, std::slice::from_ref(*family)); + assert!(!warnings.iter().any(|w| w.contains(family.as_str())), "{warnings:?}"); }