@@ -264,11 +264,14 @@ class Type1Font:
264264 Subrs - array of byte code subroutines
265265 OtherSubrs - bytes object encoding some PostScript code
266266 """
267- __slots__ = ('parts' , 'decrypted' , 'prop' , '_pos' )
267+ __slots__ = ('parts' , 'decrypted' , 'prop' , '_pos' , '_abbr' )
268268 # the _pos dict contains (begin, end) indices to parts[0] + decrypted
269269 # so that they can be replaced when transforming the font;
270270 # but since sometimes a definition appears in both parts[0] and decrypted,
271271 # _pos[name] is an array of such pairs
272+ #
273+ # _abbr maps three standard abbreviations to their particular names in
274+ # this font (e.g. 'RD' is named '-|' in some fonts)
272275
273276 def __init__ (self , input ):
274277 """
@@ -288,6 +291,7 @@ def __init__(self, input):
288291 self .parts = self ._split (data )
289292
290293 self .decrypted = self ._decrypt (self .parts [1 ], 'eexec' )
294+ self ._abbr = {'RD' : b'RD' , 'ND' : b'ND' , 'NP' : b'NP' }
291295 self ._parse ()
292296
293297 def _read (self , file ):
@@ -482,10 +486,18 @@ def convert(x): return x.decode('ascii', 'replace')
482486 break
483487
484488 # sometimes noaccess def and readonly def are abbreviated
485- if kw .is_name (b'def' , b 'ND', b'RD' , b'|-' ):
489+ if kw .is_name (b'def' , self . _abbr [ 'ND' ], self . _abbr [ 'NP' ] ):
486490 prop [key ] = value
487491 pos .setdefault (key , []).append ((keypos , kw .endpos ()))
488492
493+ # detect the standard abbreviations
494+ if value == b'{noaccess def}' :
495+ self ._abbr ['ND' ] = key .encode ('ascii' )
496+ elif value == b'{noaccess put}' :
497+ self ._abbr ['NP' ] = key .encode ('ascii' )
498+ elif value == b'{string currentfile exch readstring pop}' :
499+ self ._abbr ['RD' ] = key .encode ('ascii' )
500+
489501 # Fill in the various *Name properties
490502 if 'FontName' not in prop :
491503 prop ['FontName' ] = (prop .get ('FullName' ) or
@@ -511,8 +523,7 @@ def convert(x): return x.decode('ascii', 'replace')
511523 self .prop = prop
512524 self ._pos = pos
513525
514- @staticmethod
515- def _parse_subrs (tokens , _data ):
526+ def _parse_subrs (self , tokens , _data ):
516527 count_token = next (tokens )
517528 if not count_token .is_number ():
518529 raise RuntimeError (
@@ -539,7 +550,12 @@ def _parse_subrs(tokens, _data):
539550 "Second token following dup in Subrs definition must "
540551 f"be a number, was { nbytes_token } "
541552 )
542- token = next (tokens ) # usually RD or |- but the font can define this to be anything
553+ token = next (tokens )
554+ if not token .is_name (self ._abbr ['RD' ]):
555+ raise RuntimeError (
556+ "Token preceding subr must be RD or equivalent, "
557+ f"was { token } "
558+ )
543559 binary_token = tokens .send (1 + nbytes_token .numeric_value ())
544560 array [index_token .numeric_value ()] = binary_token .value [1 :]
545561
0 commit comments