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

Skip to content

Commit 7c9e385

Browse files
committed
fix exception when guessing the AFM familyname
1 parent 66967ab commit 7c9e385

File tree

2 files changed

+106
-7
lines changed

2 files changed

+106
-7
lines changed

lib/matplotlib/afm.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,13 @@ def _parse_optional(fh):
312312
def parse_afm(fh):
313313
"""
314314
Parse the Adobe Font Metics file in file handle *fh*. Return value
315-
is a (*dhead*, *dcmetrics*, *dkernpairs*, *dcomposite*) tuple where
316-
*dhead* is a :func:`_parse_header` dict, *dcmetrics* is a
317-
:func:`_parse_composites` dict, *dkernpairs* is a
318-
:func:`_parse_kern_pairs` dict (possibly {}), and *dcomposite* is a
319-
:func:`_parse_composites` dict (possibly {})
315+
is a (*dhead*, *dcmetrics_ascii*, *dmetrics_name*, *dkernpairs*,
316+
*dcomposite*) tuple where
317+
*dhead* is a :func:`_parse_header` dict,
318+
*dcmetrics_ascii* and *dcmetrics_name* are the two resulting dicts
319+
from :func:`_parse_char_metrics`,
320+
*dkernpairs* is a :func:`_parse_kern_pairs` dict (possibly {}) and
321+
*dcomposite* is a :func:`_parse_composites` dict (possibly {})
320322
"""
321323
_sanity_check(fh)
322324
dhead = _parse_header(fh)
@@ -503,8 +505,8 @@ def get_familyname(self):
503505

504506
# FamilyName not specified so we'll make a guess
505507
name = self.get_fullname()
506-
extras = (br'(?i)([ -](regular|plain|italic|oblique|bold|semibold|'
507-
br'light|ultralight|extra|condensed))+$')
508+
extras = (r'(?i)([ -](regular|plain|italic|oblique|bold|semibold|'
509+
r'light|ultralight|extra|condensed))+$')
508510
return re.sub(extras, '', name)
509511

510512
@property

lib/matplotlib/tests/test_afm.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,45 @@
22

33
from __future__ import (absolute_import, division, print_function,
44
unicode_literals)
5+
from six import BytesIO
56

67
import matplotlib.afm as afm
78

89

10+
AFM_TEST_DATA = b"""StartFontMetrics 2.0
11+
Comment Copyright (c) 1989 Adobe Systems Incorporated. All Rights Reserved.
12+
Comment Creation Date:Mon Jul 10 12:13:32 PDT 1989
13+
FontName AGaramondAlt-Regular
14+
EncodingScheme FontSpecific
15+
FullName Adobe Garamond Alternate Regular
16+
FamilyName AdobeGaramond
17+
Weight Regular
18+
ItalicAngle 0.0
19+
IsFixedPitch false
20+
UnderlinePosition -100
21+
UnderlineThickness 50
22+
Version 001.000
23+
Notice Copyright (c) 1989 Adobe Systems Incorporated.
24+
FontBBox 0 -354 1354 693
25+
StartCharMetrics 13
26+
C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
27+
C 49 ; WX 1141 ; N ornament1 ; B 40 57 1101 560 ;
28+
C 50 ; WX 583 ; N ornament2 ; B 40 -92 543 693 ;
29+
C 81 ; WX 795 ; N Qalt ; B 46 -354 1354 676 ;
30+
C 82 ; WX 797 ; N Qalttitling ; B 50 -346 1353 676 ;
31+
C 84 ; WX 560 ; N tswashalt ; B 34 -14 550 464 ;
32+
C 97 ; WX 714 ; N aswash ; B 35 -21 697 408 ;
33+
C 99 ; WX 702 ; N ct ; B 35 -14 695 676 ;
34+
C 101 ; WX 657 ; N eswash ; B 35 -14 650 408 ;
35+
C 110 ; WX 810 ; N nswash ; B 35 -3 804 422 ;
36+
C 114 ; WX 558 ; N rswash ; B 37 -3 552 448 ;
37+
C 116 ; WX 512 ; N tswash ; B 34 -14 513 523 ;
38+
C 122 ; WX 582 ; N zswash ; B 21 -3 583 414 ;
39+
EndCharMetrics
40+
EndFontMetrics
41+
"""
42+
43+
944
def test_nonascii_str():
1045
# This tests that we also decode bytes as utf-8 properly.
1146
# Else, font files with non ascii characters fail to load.
@@ -14,3 +49,65 @@ def test_nonascii_str():
1449

1550
ret = afm._to_str(byte_str)
1651
assert ret == inp_str
52+
53+
54+
def test_parse_header():
55+
fh = BytesIO(AFM_TEST_DATA)
56+
header = afm._parse_header(fh)
57+
assert header == {
58+
b'StartFontMetrics': 2.0,
59+
b'FontName': 'AGaramondAlt-Regular',
60+
b'EncodingScheme': 'FontSpecific',
61+
b'FullName': 'Adobe Garamond Alternate Regular',
62+
b'FamilyName': 'AdobeGaramond',
63+
b'Weight': 'Regular',
64+
b'ItalicAngle': 0.0,
65+
b'IsFixedPitch': False,
66+
b'UnderlinePosition': -100,
67+
b'UnderlineThickness': 50,
68+
b'Version': '001.000',
69+
b'Notice': 'Copyright (c) 1989 Adobe Systems Incorporated.',
70+
b'FontBBox': [0, -354, 1354, 693],
71+
b'StartCharMetrics': 13,
72+
}
73+
74+
75+
def test_parse_char_metrics():
76+
fh = BytesIO(AFM_TEST_DATA)
77+
afm._parse_header(fh) # position
78+
metrics = afm._parse_char_metrics(fh)
79+
assert metrics == (
80+
{32: (250.0, 'space', [0, 0, 0, 0]),
81+
49: (1141.0, 'ornament1', [40, 57, 1101, 560]),
82+
50: (583.0, 'ornament2', [40, -92, 543, 693]),
83+
81: (795.0, 'Qalt', [46, -354, 1354, 676]),
84+
82: (797.0, 'Qalttitling', [50, -346, 1353, 676]),
85+
84: (560.0, 'tswashalt', [34, -14, 550, 464]),
86+
97: (714.0, 'aswash', [35, -21, 697, 408]),
87+
99: (702.0, 'ct', [35, -14, 695, 676]),
88+
101: (657.0, 'eswash', [35, -14, 650, 408]),
89+
110: (810.0, 'nswash', [35, -3, 804, 422]),
90+
114: (558.0, 'rswash', [37, -3, 552, 448]),
91+
116: (512.0, 'tswash', [34, -14, 513, 523]),
92+
122: (582.0, 'zswash', [21, -3, 583, 414])
93+
},
94+
{'space': (250.0, [0, 0, 0, 0]),
95+
'ornament1': (1141.0, [40, 57, 1101, 560]),
96+
'ornament2': (583.0, [40, -92, 543, 693]),
97+
'Qalt': (795.0, [46, -354, 1354, 676]),
98+
'Qalttitling': (797.0, [50, -346, 1353, 676]),
99+
'tswashalt': (560.0, [34, -14, 550, 464]),
100+
'aswash': (714.0, [35, -21, 697, 408]),
101+
'ct': (702.0, [35, -14, 695, 676]),
102+
'eswash': (657.0, [35, -14, 650, 408]),
103+
'nswash': (810.0, [35, -3, 804, 422]),
104+
'rswash': (558.0, [37, -3, 552, 448]),
105+
'tswash': (512.0, [34, -14, 513, 523]),
106+
'zswash': (582.0, [21, -3, 583, 414])})
107+
108+
109+
def test_get_familyname_guessed():
110+
fh = BytesIO(AFM_TEST_DATA)
111+
fm = afm.AFM(fh)
112+
del fm._header[b'FamilyName'] # remove FamilyName, so we have to guess
113+
assert fm.get_familyname() == 'Adobe Garamond Alternate'

0 commit comments

Comments
 (0)