[instancer/CFF2] Fixups with used-vsindex handing
vsindex 0 is implied. Also, add Unimplemented code for private-dict variable values. I couldn't find any fonts using them, so for now they remain unimplemented.
This commit is contained in:
parent
68f87dd850
commit
bdd42f14fc
@ -97,6 +97,7 @@ from fontTools import varLib
|
||||
# we import the `subset` module because we use the `prune_lookups` method on the GSUB
|
||||
# table class, and that method is only defined dynamically upon importing `subset`
|
||||
from fontTools import subset # noqa: F401
|
||||
from fontTools.cffLib import privateDictOperators2
|
||||
from fontTools.cffLib.specializer import (
|
||||
programToCommands,
|
||||
commandsToProgram,
|
||||
@ -588,7 +589,6 @@ def instantiateCFF2(
|
||||
cff.desubroutinize()
|
||||
|
||||
varStore2 = topDict.CharStrings.varStore.otVarStore
|
||||
|
||||
assert varStore is varStore2 # Who knows why it's in two places?!
|
||||
|
||||
def getNumRegions(vsindex):
|
||||
@ -597,6 +597,18 @@ def instantiateCFF2(
|
||||
)
|
||||
|
||||
charStrings = topDict.CharStrings.values()
|
||||
|
||||
# Gather all unique private dicts
|
||||
uniquePrivateDicts = set()
|
||||
privateDicts = []
|
||||
if hasattr(topDict, "Private"):
|
||||
uniquePrivateDicts.add(topDict.Private)
|
||||
privateDicts.append(topDict.Private)
|
||||
for cs in charStrings:
|
||||
if cs.private not in uniquePrivateDicts:
|
||||
uniquePrivateDicts.add(cs.private)
|
||||
privateDicts.append(cs.private)
|
||||
|
||||
allCommands = []
|
||||
for cs in charStrings:
|
||||
assert cs.private.vstore.otVarStore is varStore # Or in many places!!
|
||||
@ -697,18 +709,19 @@ def instantiateCFF2(
|
||||
varData.Item = []
|
||||
varData.ItemCount = 0
|
||||
|
||||
# Remove vsindex commands that are no longer needed
|
||||
for commands in allCommands:
|
||||
if any(isinstance(arg, list) for command in commands for arg in command[1]):
|
||||
continue
|
||||
commands[:] = [command for command in commands if command[0] != "vsindex"]
|
||||
|
||||
# Collect used vsindex values
|
||||
# Remove vsindex commands that are no longer needed, collect those that are.
|
||||
usedVsindex = set()
|
||||
for commands in allCommands:
|
||||
for command in commands:
|
||||
if command[0] == "vsindex":
|
||||
usedVsindex.add(command[1][0])
|
||||
if any(isinstance(arg, list) for command in commands for arg in command[1]):
|
||||
vsindex = 0
|
||||
for command in commands:
|
||||
if command[0] == "vsindex":
|
||||
vsindex = command[1][0]
|
||||
continue
|
||||
if any(isinstance(arg, list) for arg in command[1]):
|
||||
usedVsindex.add(vsindex)
|
||||
else:
|
||||
commands[:] = [command for command in commands if command[0] != "vsindex"]
|
||||
|
||||
# Remove unused VarData and update vsindex values
|
||||
vsindexMapping = {v: i for i, v in enumerate(sorted(usedVsindex))}
|
||||
@ -720,16 +733,49 @@ def instantiateCFF2(
|
||||
if command[0] == "vsindex":
|
||||
command[1][0] = vsindexMapping[command[1][0]]
|
||||
|
||||
# Ship the charstrings!
|
||||
for cs, commands in zip(charStrings, allCommands):
|
||||
cs.program = commandsToProgram(commands)
|
||||
|
||||
# TODO We don't currently instantiate the private-dict
|
||||
# variable values, as I couldn't find any fonts using those.
|
||||
# File a bug if you need this.
|
||||
|
||||
# Now to instantiate private values
|
||||
for opcode, name, arg_type, default, converter in privateDictOperators2:
|
||||
if arg_type not in ("number", "delta", "array"):
|
||||
continue
|
||||
|
||||
for private in privateDicts:
|
||||
if not hasattr(private, name):
|
||||
continue
|
||||
values = getattr(private, name)
|
||||
if arg_type == "number":
|
||||
values = [values]
|
||||
|
||||
newValues = []
|
||||
for value in values:
|
||||
if not isinstance(value, list):
|
||||
newValues.append(value)
|
||||
continue
|
||||
|
||||
raise NotImplementedError(
|
||||
"File an issue to instantiate private-dict values."
|
||||
)
|
||||
|
||||
newValues.extend(fetchBlendsFromVarStore(value))
|
||||
|
||||
if arg_type == "number":
|
||||
newValues = newValues[0]
|
||||
|
||||
setattr(private, name, newValues)
|
||||
|
||||
# Remove empty VarStore
|
||||
if not varStore.VarData:
|
||||
topDict.VarStore = None
|
||||
topDict.CharStrings.varStore = None
|
||||
for cs in charStrings:
|
||||
cs.private.vstore = None
|
||||
|
||||
# Ship it!
|
||||
for cs, commands in zip(charStrings, allCommands):
|
||||
cs.program = commandsToProgram(commands)
|
||||
for private in privateDicts:
|
||||
private.vstore = None
|
||||
|
||||
|
||||
def _instantiateGvarGlyph(
|
||||
|
Loading…
x
Reference in New Issue
Block a user