Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e1d2ae3

Browse files
committed
Inline some afm parsing code.
Splitting _parse_afm out of `__init__` doesn't buy much, and its docstring is not particularly informative either, so just inline it to the AFM constructor. Likewise, most of the benefits from `_sanity_check` can be obtained by just looking for the first entry of the header (this admittedly relies on dict-order-maintaining, which is present on Py3.6 though not mandated (it is mandated in Py3.7), but I'm not aware of Matplotlib running on an alternative Py3.6 that does not support that behavior...).
1 parent d601e03 commit e1d2ae3

1 file changed

Lines changed: 13 additions & 53 deletions

File tree

lib/matplotlib/afm.py

Lines changed: 13 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
10788
def _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

182169
CharMetrics = 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-
394356
class 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

Comments
 (0)