diff --git a/crates/eps/src/import/tests_fontnames.rs b/crates/eps/src/import/tests_fontnames.rs index f0dd9c6c2..d925905ee 100644 --- a/crates/eps/src/import/tests_fontnames.rs +++ b/crates/eps/src/import/tests_fontnames.rs @@ -56,3 +56,10 @@ fn abbreviated_styles_in_postscript_names_are_spelled_out() { // Whole words stay as they were. assert_eq!(crate::family_style("Helvetica-BoldOblique").1, "Bold Oblique"); } + +/// A face of that exact PostScript name gives its own family and style, however the name splits +/// (a family can hold hyphens, as Rounded-X M+ 1c's `rounded-x-mplus-1c-black` does). +#[test] +fn an_installed_face_of_the_postscript_name_names_the_font() { + assert_eq!(crate::family_style("ABCDEF+SourceSans3-Semibold"), ("Source Sans 3".to_string(), "Semibold".to_string())); +} diff --git a/crates/eps/src/import/text.rs b/crates/eps/src/import/text.rs index 702cc9f1a..716e3b405 100644 --- a/crates/eps/src/import/text.rs +++ b/crates/eps/src/import/text.rs @@ -39,9 +39,11 @@ fn style_word(w: &str) -> String { .to_string() } -/// A font's family and style from its PostScript name: `Helvetica-BoldOblique` → (`Helvetica`, -/// `Bold Oblique`), `TimesNewRomanPS-BoldMT` → (`Times New Roman`, `Bold`), without a subset -/// prefix (`ABCDEF+`) or the `*1` of a re-encoded copy (`ABCDEF+RollerBabyBV*1`). +/// A font's family and style from its PostScript name, without a subset prefix (`ABCDEF+`) or the +/// `*1` of a re-encoded copy (`ABCDEF+RollerBabyBV*1`): an installed or bundled face of that +/// exact name gives its own (a family can hold hyphens: `rounded-x-mplus-1c-black` is Rounded-X +/// M+ 1c, black); else the name is split, `Helvetica-BoldOblique` → (`Helvetica`, `Bold +/// Oblique`), `TimesNewRomanPS-BoldMT` → (`Times New Roman`, `Bold`). pub fn family_style(name: &str) -> (String, String) { let name = match name.split_once('+') { Some((prefix, rest)) if prefix.len() == 6 && prefix.bytes().all(|b| b.is_ascii_uppercase()) => rest, @@ -51,6 +53,9 @@ pub fn family_style(name: &str) -> (String, String) { Some((base, n)) if !base.is_empty() && !n.is_empty() && n.bytes().all(|b| b.is_ascii_digit()) => base, _ => name, }; + if let Some(face) = vectorcraft_text::FontDb::global().find_postscript(name) { + return (face.family.clone(), face.style.clone()); + } let (family, style) = name.split_once('-').unwrap_or((name, "")); let trim = |s: &str| -> String { let s = ["PSMT", "MT", "PS"].iter().find_map(|suffix| s.strip_suffix(suffix)).unwrap_or(s);