From 9efe6dc76462fed745ed303a02cce1de345b916c Mon Sep 17 00:00:00 2001 From: bflatastic Date: Sat, 31 Oct 2026 18:56:19 +0700 Subject: [PATCH] PDF import: a font name's family is looked for at no more than 16 of its hyphens The name comes from the file, and each lookup walks it, so a name made of thousands of hyphens took quadratic time. --- crates/pdf/src/import_text.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/pdf/src/import_text.rs b/crates/pdf/src/import_text.rs index 373437cfa..8157759e7 100644 --- a/crates/pdf/src/import_text.rs +++ b/crates/pdf/src/import_text.rs @@ -985,8 +985,9 @@ impl Families { } // The longest part of the name before a hyphen (or the comma of `Arial,Bold`, ISO 32000-1 // ยง9.6.3) that names an available family, the rest its style: a family can hold hyphens - // (`Noto-Sans-Bold` is Noto Sans, Bold). - let cuts = std::iter::once(name.len()).chain(name.rmatch_indices(['-', ',']).map(|(i, _)| i)); + // (`Noto-Sans-Bold` is Noto Sans, Bold). The name is the file's: a few cuts from its end are + // enough for any family, and each costs a pass over the name. + let cuts = std::iter::once(name.len()).chain(name.rmatch_indices(['-', ',']).map(|(i, _)| i).take(16)); for cut in cuts { let (fam, style) = (name.get(..cut).unwrap_or(name), name.get(cut + 1..).unwrap_or("")); if let Some(f) = [fam, strip_ps(fam)].iter().find_map(|f| self.0.get(&norm(f)).cloned()) {