@@ -85,25 +85,6 @@ def _to_bool(s):
8585 return True
8686
8787
88- def _sanity_check (fh ):
89- """
90- Check if the file looks like AFM; if it doesn't, raise `RuntimeError`.
91- """
92- # Remember the file position in case the caller wants to
93- # do something else with the file.
94- pos = fh .tell ()
95- try :
96- line = next (fh )
97- finally :
98- fh .seek (pos , 0 )
99- # AFM spec, Section 4: The StartFontMetrics keyword [followed by a
100- # version number] must be the first line in the file, and the
101- # EndFontMetrics keyword must be the last non-empty line in the
102- # file. We just check the first line.
103- if not line .startswith (b'StartFontMetrics' ):
104- raise RuntimeError ('Not an AFM file' )
105-
106-
10788def _parse_header (fh ):
10889 """
10990 Reads the font metrics header (up to the char metrics) and returns
@@ -157,13 +138,11 @@ def _parse_header(fh):
157138 if line .startswith (b'Comment' ):
158139 continue
159140 lst = line .split (b' ' , 1 )
160-
161141 key = lst [0 ]
162142 if len (lst ) == 2 :
163143 val = lst [1 ]
164144 else :
165145 val = b''
166-
167146 try :
168147 converter = header_converters [key ]
169148 except KeyError :
@@ -175,8 +154,16 @@ def _parse_header(fh):
175154 _log .error ('Value error parsing header in AFM: %s, %s' , key , val )
176155 continue
177156 if key == b'StartCharMetrics' :
178- return d
179- raise RuntimeError ('Bad parse' )
157+ break
158+ else :
159+ raise RuntimeError ('Bad parse' )
160+ # AFM spec, Section 4: The StartFontMetrics keyword [followed by a version
161+ # number] must be the first line in the file, and the EndFontMetrics
162+ # keyword must be the last non-empty line in the file. We just check the
163+ # first header entry.
164+ if next (iter (d )) != b'StartFontMetrics' :
165+ raise RuntimeError ('Not an AFM file' )
166+ return d
180167
181168
182169CharMetrics = namedtuple ('CharMetrics' , 'width, name, bbox' )
@@ -366,40 +353,13 @@ def _parse_optional(fh):
366353 return d [b'StartKernData' ], d [b'StartComposites' ]
367354
368355
369- def _parse_afm (fh ):
370- """
371- Parse the Adobe Font Metrics file in file handle *fh*.
372-
373- Returns
374- -------
375- header : dict
376- A header dict. See :func:`_parse_header`.
377- cmetrics_by_ascii : dict
378- From :func:`_parse_char_metrics`.
379- cmetrics_by_name : dict
380- From :func:`_parse_char_metrics`.
381- kernpairs : dict
382- From :func:`_parse_kern_pairs`.
383- composites : dict
384- From :func:`_parse_composites`
385-
386- """
387- _sanity_check (fh )
388- header = _parse_header (fh )
389- cmetrics_by_ascii , cmetrics_by_name = _parse_char_metrics (fh )
390- kernpairs , composites = _parse_optional (fh )
391- return header , cmetrics_by_ascii , cmetrics_by_name , kernpairs , composites
392-
393-
394356class AFM :
395357
396358 def __init__ (self , fh ):
397359 """Parse the AFM file in file object *fh*."""
398- (self ._header ,
399- self ._metrics ,
400- self ._metrics_by_name ,
401- self ._kern ,
402- self ._composite ) = _parse_afm (fh )
360+ self ._header = _parse_header (fh )
361+ self ._metrics , self ._metrics_by_name = _parse_char_metrics (fh )
362+ self ._kern , self ._composite = _parse_optional (fh )
403363
404364 def get_bbox_char (self , c , isord = False ):
405365 if not isord :
0 commit comments