@@ -263,11 +263,14 @@ class Type1Font:
263263 Subrs - array of byte code subroutines
264264 OtherSubrs - bytes object encoding some PostScript code
265265 """
266- __slots__ = ('parts' , 'decrypted' , 'prop' , '_pos' )
266+ __slots__ = ('parts' , 'decrypted' , 'prop' , '_pos' , '_abbr' )
267267 # the _pos dict contains (begin, end) indices to parts[0] + decrypted
268268 # so that they can be replaced when transforming the font;
269269 # but since sometimes a definition appears in both parts[0] and decrypted,
270270 # _pos[name] is an array of such pairs
271+ #
272+ # _abbr maps three standard abbreviations to their particular names in
273+ # this font (e.g. 'RD' is named '-|' in some fonts)
271274
272275 def __init__ (self , input ):
273276 """
@@ -287,6 +290,7 @@ def __init__(self, input):
287290 self .parts = self ._split (data )
288291
289292 self .decrypted = self ._decrypt (self .parts [1 ], 'eexec' )
293+ self ._abbr = {'RD' : b'RD' , 'ND' : b'ND' , 'NP' : b'NP' }
290294 self ._parse ()
291295
292296 def _read (self , file ):
@@ -486,10 +490,18 @@ def convert(x): return x.decode('ascii', 'replace')
486490 break
487491
488492 # sometimes noaccess def and readonly def are abbreviated
489- if kw .is_name (b'def' , b 'ND', b'RD' , b'|-' ):
493+ if kw .is_name (b'def' , self . _abbr [ 'ND' ], self . _abbr [ 'NP' ] ):
490494 prop [key ] = value
491495 pos .setdefault (key , []).append ((keypos , kw .endpos ()))
492496
497+ # detect the standard abbreviations
498+ if value == b'{noaccess def}' :
499+ self ._abbr ['ND' ] = key .encode ('ascii' )
500+ elif value == b'{noaccess put}' :
501+ self ._abbr ['NP' ] = key .encode ('ascii' )
502+ elif value == b'{string currentfile exch readstring pop}' :
503+ self ._abbr ['RD' ] = key .encode ('ascii' )
504+
493505 # Fill in the various *Name properties
494506 if 'FontName' not in prop :
495507 prop ['FontName' ] = (prop .get ('FullName' ) or
@@ -515,8 +527,7 @@ def convert(x): return x.decode('ascii', 'replace')
515527 self .prop = prop
516528 self ._pos = pos
517529
518- @staticmethod
519- def _parse_subrs (tokens , _data ):
530+ def _parse_subrs (self , tokens , _data ):
520531 count_token = next (tokens )
521532 if not count_token .is_number ():
522533 raise RuntimeError (
@@ -543,7 +554,12 @@ def _parse_subrs(tokens, _data):
543554 "Second token following dup in Subrs definition must "
544555 f"be a number, was { nbytes_token } "
545556 )
546- token = next (tokens ) # usually RD or |- but the font can define this to be anything
557+ token = next (tokens )
558+ if not token .is_name (self ._abbr ['RD' ]):
559+ raise RuntimeError (
560+ "Token preceding subr must be RD or equivalent, "
561+ f"was { token } "
562+ )
547563 binary_token = tokens .send (1 + nbytes_token .numeric_value ())
548564 array [index_token .numeric_value ()] = binary_token .value [1 :]
549565
0 commit comments