[cffLib.specializer] Implement width extraction in programToCommands()
Test: ./fonttools cffLib.specializer 7 0 8 rmoveto 1 2 3 4 5 0 rrcurvet
This commit is contained in:
parent
bef46993f6
commit
0bf5044d12
@ -8,10 +8,11 @@ from fontTools.misc.py23 import *
|
|||||||
def programToCommands(program):
|
def programToCommands(program):
|
||||||
"""Takes a T2CharString program list and returns list of commands.
|
"""Takes a T2CharString program list and returns list of commands.
|
||||||
Each command is a two-tuple of commandname,arg-list. The commandname might
|
Each command is a two-tuple of commandname,arg-list. The commandname might
|
||||||
be None if no commandname shall be emitted (used for glyph width (TODO),
|
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
|
hintmask/cntrmask argument, as well as stray arguments at the end of the
|
||||||
program (¯\_(ツ)_/¯)."""
|
program (¯\_(ツ)_/¯)."""
|
||||||
|
|
||||||
|
width = None
|
||||||
commands = []
|
commands = []
|
||||||
stack = []
|
stack = []
|
||||||
it = iter(program)
|
it = iter(program)
|
||||||
@ -19,16 +20,26 @@ def programToCommands(program):
|
|||||||
if not isinstance(token, basestring):
|
if not isinstance(token, basestring):
|
||||||
stack.append(token)
|
stack.append(token)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if width is None and token in {'hstem', 'hstemhm', 'vstem', 'vstemhm',
|
||||||
|
'cntrmask', 'hintmask',
|
||||||
|
'hmoveto', 'vmoveto', 'rmoveto',
|
||||||
|
'endchar'}:
|
||||||
|
parity = token in {'hmoveto', 'vmoveto'}
|
||||||
|
if (len(stack) % 2) ^ parity:
|
||||||
|
width = stack.pop(0)
|
||||||
|
commands.append(('', [width]))
|
||||||
|
|
||||||
if token in {'hintmask', 'cntrmask'}:
|
if token in {'hintmask', 'cntrmask'}:
|
||||||
if stack:
|
if stack:
|
||||||
commands.append((None, stack))
|
commands.append(('', stack))
|
||||||
commands.append((token, []))
|
commands.append((token, []))
|
||||||
commands.append((None, [next(it)]))
|
commands.append(('', [next(it)]))
|
||||||
else:
|
else:
|
||||||
commands.append((token,stack))
|
commands.append((token,stack))
|
||||||
stack = []
|
stack = []
|
||||||
if stack:
|
if stack:
|
||||||
commands.append((None, stack))
|
commands.append(('', stack))
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
def commandsToProgram(commands):
|
def commandsToProgram(commands):
|
||||||
@ -167,7 +178,7 @@ def generalizeCommands(commands, ignoreErrors=True):
|
|||||||
result = []
|
result = []
|
||||||
mapping = _GeneralizerDecombinerCommandsMap
|
mapping = _GeneralizerDecombinerCommandsMap
|
||||||
for op,args in commands:
|
for op,args in commands:
|
||||||
func = getattr(mapping, op if op else '', None)
|
func = getattr(mapping, op, None)
|
||||||
if not func:
|
if not func:
|
||||||
result.append((op,args))
|
result.append((op,args))
|
||||||
continue
|
continue
|
||||||
@ -178,8 +189,8 @@ def generalizeCommands(commands, ignoreErrors=True):
|
|||||||
if ignoreErrors:
|
if ignoreErrors:
|
||||||
# Store op as data, such that consumers of commands do not have to
|
# Store op as data, such that consumers of commands do not have to
|
||||||
# deal with incorrect number of arguments.
|
# deal with incorrect number of arguments.
|
||||||
result.append((None,args))
|
result.append(('', args))
|
||||||
result.append((None, [op]))
|
result.append(('', [op]))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
return result
|
return result
|
||||||
|
Loading…
x
Reference in New Issue
Block a user