specializer: T2CharString operator specializer and generalizer

T2CharString operator specializer and generalizer.

PostScript glyph drawing operations can be expressed in multiple different ways. For example, as well as the lineto operator, there is also a hlineto operator which draws a horizontal line, removing the need to specify a dx coordinate, and a vlineto operator which draws a vertical line, removing the need to specify a dy coordinate. As well as decompiling fontTools.misc.psCharStrings.T2CharString objects into lists of operations, this module allows for conversion between general and specific forms of the operation.


Takes a commands list as returned by programToCommands() and converts it back to a T2CharString program list.

fontTools.cffLib.specializer.generalizeCommands(commands, ignoreErrors=False)[source]
fontTools.cffLib.specializer.generalizeProgram(program, getNumRegions=None, **kwargs)[source]
fontTools.cffLib.specializer.programToCommands(program, getNumRegions=None)[source]

Takes a T2CharString program list and returns list of commands. Each command is a two-tuple of commandname,arg-list. The commandname might be empty string if no commandname shall be emitted (used for glyph width, hintmask/cntrmask argument, as well as stray arguments at the end of the program (🤷). ‘getNumRegions’ may be None, or a callable object. It must return the number of regions. ‘getNumRegions’ takes a single argument, vsindex. It returns the numRegions for the vsindex. The Charstring may or may not start with a width value. If the first non-blend operator has an odd number of arguments, then the first argument is a width, and is popped off. This is complicated with blend operators, as there may be more than one before the first hint or moveto operator, and each one reduces several arguments to just one list argument. We have to sum the number of arguments that are not part of the blend arguments, and all the ‘numBlends’ values. We could instead have said that by definition, if there is a blend operator, there is no width value, since CFF2 Charstrings don’t have width values. I discussed this with Behdad, and we are allowing for an initial width value in this case because developers may assemble a CFF2 charstring from CFF Charstrings, which could have width values.

fontTools.cffLib.specializer.specializeCommands(commands, ignoreErrors=False, generalizeFirst=True, preserveTopology=False, maxstack=48)[source]
fontTools.cffLib.specializer.specializeProgram(program, getNumRegions=None, **kwargs)[source]