[featureVars] don't overwrite FeatureVariations, append new records

Currently, addFeatureVariationsRaw always deletes existing GSUB.FeatureVariations and overwrites them with the newly built records.
It doesn't have to, though. If the features for which we are adding feature variations are not already "variable", we can simply append the DS-rules-generated records to the FeatureVariations.
We raise an error if the existing FeatureVariations already reference the same feature tags used for the DS rules, as that could generate ambiguity/undefined logic.
This commit is contained in:
Cosimo Lupo 2023-12-01 19:02:16 +00:00
parent 4c527e6e69
commit 6358b47682
No known key found for this signature in database
GPG Key ID: DF65A8A5A119C9A8

View File

@ -69,6 +69,14 @@ def addFeatureVariations(font, conditionalSubstitutions, featureTag="rvrn"):
)
if "GSUB" not in font:
font["GSUB"] = buildGSUB()
else:
existingTags = _existingVariableFeatures(font["GSUB"].table).intersection(
featureTags
)
if existingTags:
raise VarLibError(
f"FeatureVariations already exist for feature tag(s): {existingTags}"
)
# setup lookups
lookupMap = buildSubstitutionLookups(
@ -87,6 +95,16 @@ def addFeatureVariations(font, conditionalSubstitutions, featureTag="rvrn"):
addFeatureVariationsRaw(font, font["GSUB"].table, conditionsAndLookups, featureTags)
def _existingVariableFeatures(table):
existingFeatureVarsTags = set()
if hasattr(table, "FeatureVariations") and table.FeatureVariations is not None:
features = table.FeatureList.FeatureRecord
for fvr in table.FeatureVariations.FeatureVariationRecord:
for ftsr in fvr.FeatureTableSubstitution.SubstitutionRecord:
existingFeatureVarsTags.add(features[ftsr.FeatureIndex].FeatureTag)
return existingFeatureVarsTags
def _checkSubstitutionGlyphsExist(glyphNames, substitutions):
referencedGlyphNames = set()
for _, substitution in substitutions:
@ -349,8 +367,6 @@ def addFeatureVariationsRaw(font, table, conditionalSubstitutions, featureTag="r
if table.Version < 0x00010001:
table.Version = 0x00010001 # allow table.FeatureVariations
table.FeatureVariations = None # delete any existing FeatureVariations
varFeatureIndices = set()
existingTags = {
@ -428,7 +444,18 @@ def addFeatureVariationsRaw(font, table, conditionalSubstitutions, featureTag="r
buildFeatureVariationRecord(conditionTable, records)
)
table.FeatureVariations = buildFeatureVariations(featureVariationRecords)
if hasattr(table, "FeatureVariations") and table.FeatureVariations is not None:
if table.FeatureVariations.Version != 0x00010000:
raise VarLibError(
"Unsupported FeatureVariations table version: "
f"0x{table.FeatureVariations.Version:08x} (expected 0x00010000)."
)
table.FeatureVariations.FeatureVariationRecord.extend(featureVariationRecords)
table.FeatureVariations.FeatureVariationCount = len(
table.FeatureVariations.FeatureVariationRecord
)
else:
table.FeatureVariations = buildFeatureVariations(featureVariationRecords)
#