mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 11:11:30 +00:00
Merge pull request #5497 from storytold/fix/sec-font-name-records
Fonts: cap the name records and decoded bytes read per name id
This commit is contained in:
@@ -76,9 +76,23 @@ pub(super) fn name(font: &skrifa::FontRef<'_>, ids: &[StringId]) -> Option<Strin
|
||||
/// The most distinct legacy family (and style) names of a font used as keys.
|
||||
pub(super) const MAX_LEGACY_NAMES: usize = 64;
|
||||
|
||||
/// Records can share their encoded bytes, so a small table names many long strings: stop at this
|
||||
/// many records or decoded bytes (real fonts have a few dozen short names per id).
|
||||
const MAX_NAME_RECORDS: usize = 1024;
|
||||
const MAX_NAME_BYTES: usize = 1 << 20;
|
||||
|
||||
/// Every localized string of `id`, with its language.
|
||||
pub(super) fn localized(font: &skrifa::FontRef<'_>, id: StringId) -> Vec<(Option<String>, String)> {
|
||||
font.localized_strings(id).map(|s| (s.language().map(str::to_owned), s.to_string())).filter(|(_, s)| !s.is_empty()).collect()
|
||||
let mut bytes = 0usize;
|
||||
font.localized_strings(id)
|
||||
.take(MAX_NAME_RECORDS)
|
||||
.map(|s| (s.language().map(str::to_owned), s.to_string()))
|
||||
.take_while(|(_, s)| {
|
||||
bytes = bytes.saturating_add(s.len());
|
||||
bytes <= MAX_NAME_BYTES
|
||||
})
|
||||
.filter(|(_, s)| !s.is_empty())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Whether a name-table language tag is English (Illustrator's "Show Font Names in English").
|
||||
@@ -119,3 +133,17 @@ pub(super) fn norm_chars(s: &str) -> impl Iterator<Item = char> + '_ {
|
||||
pub(super) fn norm(s: &str) -> String {
|
||||
norm_chars(s).collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_name_table_of_many_records_is_cut_short() {
|
||||
let many: Vec<(u16, &str)> = (0..2000).map(|_| (1, "Short")).collect();
|
||||
let name = crate::test_fonts::name_table(&many).unwrap_or_default();
|
||||
let font = crate::fontdb::sfnt_of(&[(b"name", &name)]).unwrap_or_default();
|
||||
let font = skrifa::FontRef::new(&font).unwrap();
|
||||
assert_eq!(localized(&font, StringId::FAMILY_NAME).len(), MAX_NAME_RECORDS);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user