EPS/.ai import: a font is found by its exact PostScript name before the name is split

The private data a .ai file opens with names fonts by PostScript name, and
the importer split the name at its first hyphen: rounded-x-mplus-1c-black
became the family "rounded", style "x-mplus-1c-black", which no font has,
so the type fell back to Source Sans 3 although Rounded-X M+ 1c is
installed. An installed or bundled face of that exact PostScript name now
gives its own family and style; other names split as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hiroshi Inukai 2026-10-11 14:07:54 +09:00 committed by bflatastic
parent 66fd1b78a2
commit 0e5e83cf5c
2 changed files with 15 additions and 3 deletions

View File

@ -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()));
}

View File

@ -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);