Skip to content

Commit 48e3536

Browse files
committed
fonts: Make STAT table optional for variable fonts
Some of the test fonts in the text-rendering-tests lack a STAT table and all of the other implementations accept this. unicode-org/text-rendering-tests#91
1 parent 428f53f commit 48e3536

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

Diff for: src/variations.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,11 @@ pub fn instance(
146146
.as_ref()
147147
.map(|mvar_data| ReadScope::new(mvar_data).read::<MvarTable<'_>>())
148148
.transpose()?;
149-
let stat_data = provider.read_table_data(tag::STAT)?;
150-
let stat = ReadScope::new(&stat_data).read::<StatTable<'_>>()?;
149+
let stat_data = provider.table_data(tag::STAT)?;
150+
let stat = stat_data
151+
.as_ref()
152+
.map(|stat_data| ReadScope::new(stat_data).read::<StatTable<'_>>())
153+
.transpose()?;
151154
let name_data = provider.read_table_data(tag::NAME)?;
152155
let name = ReadScope::new(&name_data).read::<NameTable<'_>>()?;
153156

@@ -238,17 +241,24 @@ pub fn instance(
238241
let prep = provider.table_data(tag::PREP)?;
239242

240243
// Update name
241-
let names = typographic_subfamily_name(user_instance, &fvar, &stat, &name, "Regular")?;
244+
let subfamily_name = stat
245+
.as_ref()
246+
.map(|stat| typographic_subfamily_name(user_instance, &fvar, stat, &name, "Regular"))
247+
.unwrap_or_else(|| {
248+
name.string_for_id(NameTable::TYPOGRAPHIC_SUBFAMILY_NAME)
249+
.or_else(|| name.string_for_id(NameTable::FONT_SUBFAMILY_NAME))
250+
.ok_or(VariationError::NameError)
251+
})?;
242252
let typographic_family = name
243253
.string_for_id(NameTable::TYPOGRAPHIC_FAMILY_NAME)
244254
.or_else(|| name.string_for_id(NameTable::FONT_FAMILY_NAME))
245255
.ok_or(VariationError::NameError)?;
246256
let postscript_prefix = name.string_for_id(NameTable::VARIATIONS_POSTSCRIPT_NAME_PREFIX);
247257
let mut name = owned::NameTable::try_from(&name)?;
248258

249-
// Remove name_id entries 1 & 2 and then populate 16 & 17, replacing an existing
259+
// Remove name_id entries 1 & 2 and then populate 16 & 17, replacing any existing
250260
// entries
251-
let full_name = format!("{} {}", typographic_family, names);
261+
let full_name = format!("{} {}", typographic_family, subfamily_name);
252262
let postscript_name = generate_postscript_name(
253263
&postscript_prefix,
254264
&typographic_family,
@@ -262,7 +272,7 @@ pub fn instance(
262272
name.replace_entries(NameTable::FULL_FONT_NAME, &full_name);
263273
name.replace_entries(NameTable::POSTSCRIPT_NAME, &postscript_name);
264274
name.replace_entries(NameTable::TYPOGRAPHIC_FAMILY_NAME, &typographic_family);
265-
name.replace_entries(NameTable::TYPOGRAPHIC_SUBFAMILY_NAME, &names);
275+
name.replace_entries(NameTable::TYPOGRAPHIC_SUBFAMILY_NAME, &subfamily_name);
266276

267277
// Build the new font
268278
let mut builder = FontBuilder::new(0x00010000_u32);
@@ -605,7 +615,7 @@ fn add_delta_u16(value: u16, delta: f32) -> u16 {
605615
}
606616

607617
fn is_supported_variable_font(provider: &impl FontTableProvider) -> Result<(), VariationError> {
608-
// Two tables are required in all variable fonts:
618+
// The OpenType specification says two tables are required in all variable fonts:
609619
//
610620
// * A font variations ('fvar') table is required to describe the variations
611621
// supported by the font.
@@ -616,7 +626,14 @@ fn is_supported_variable_font(provider: &impl FontTableProvider) -> Result<(), V
616626
// models that assume a limited set of axes.
617627
//
618628
// https://learn.microsoft.com/en-us/typography/opentype/spec/otvaroverview#vartables
619-
if provider.has_table(tag::FVAR) && provider.has_table(tag::STAT) {
629+
//
630+
// However it seems there are fonts in the wild that lack a `STAT` table.
631+
// These were first encountered in the Unicode text-rendering-tests and it was
632+
// suggested that the spec was overly strict. So to support these fonts we
633+
// don't require `STAT`.
634+
//
635+
// https://github.com/unicode-org/text-rendering-tests/issues/91
636+
if provider.has_table(tag::FVAR) {
620637
// Variable CFF fonts are currently not supported
621638
if provider.has_table(tag::CFF2) {
622639
Err(VariationError::NotImplemented)

0 commit comments

Comments
 (0)