8000 Cleanup subsetting tool. · matplotlib/matplotlib@756013a · GitHub
[go: up one dir, main page]

Skip to content

Commit 756013a

Browse files
committed
Cleanup subsetting tool.
Fix flake8 and problems running on Python 3.
1 parent 0ac5c29 commit 756013a

File tree

2 files changed

+106
-77
lines changed

2 files changed

+106
-77
lines changed

.flake8

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ per-file-ignores =
4545
setupext.py: E501
4646
tests.py: F401
4747

48-
tools/subset.py: E221, E251, E261, E302, E501
49-
5048
lib/matplotlib/__init__.py: F401
5149
lib/matplotlib/_api/__init__.py: F401
5250
lib/matplotlib/_cm.py: E202, E203, E302

tools/subset.py

Lines changed: 106 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
#
2222
# A script for subsetting a font, using FontForge. See README for details.
2323

24-
# TODO 2013-04-08 ensure the menu files are as compact as possible by default, similar to subset.pl
25-
# TODO 2013-05-22 in Arimo, the latin subset doesn't include ; but the greek does. why on earth is this happening?
24+
# TODO 2013-04-08 ensure the menu files are as compact as possible by default,
25+
# similar to subset.pl
26+
# TODO 2013-05-22 in Arimo, the latin subset doesn't include ; but the greek
27+
# does. why on earth is this happening?
2628

2729
import getopt
2830
import os
@@ -35,29 +37,31 @@
3537

3638
def log_namelist(nam, unicode):
3739
if nam and isinstance(unicode, int):
38-
print("0x%0.4X" % unicode, fontforge.nameFromUnicode(unicode), file=nam)
40+
print(f"0x{unicode:04X}", fontforge.nameFromUnicode(unicode), file=nam)
3941

40-
def select_with_refs(font, unicode, newfont, pe = None, nam = None):
42+
43+
def select_with_refs(font, unicode, newfont, pe=None, nam=None):
4144
newfont.selection.select(('more', 'unicode'), unicode)
4245
log_namelist(nam, unicode)
4346
if pe:
44-
print("SelectMore(%d)" % unicode, file=pe)
47+
print(f"SelectMore({unicode})", file=pe)
4548
try:
4649
for ref in font[unicode].references:
4750
newfont.selection.select(('more',), ref[0])
4851
log_namelist(nam, ref[0])
4952
if pe:
50-
print('SelectMore("%s")' % ref[0], file=pe)
53+
print(f'SelectMore("{ref[0]}")', file=pe)
5154
except Exception:
52-
print('Resolving references on u+%04x failed' % unicode)
55+
print(f'Resolving references on u+{unicode:04x} failed')
56+
5357

5458
def subset_font_raw(font_in, font_out, unicodes, opts):
5559
if '--namelist' in opts:
5660
# 2010-12-06 DC To allow setting namelist filenames,
5761
# change getopt.gnu_getopt from namelist to namelist=
5862
# and invert comments on following 2 lines
5963
# nam_fn = opts['--namelist']
60-
nam_fn = font_out + '.nam'
64+
nam_fn = f'{font_out}.nam'
6165
nam = open(nam_fn, 'w')
6266
else:
6367
nam = None
@@ -68,7 +72,7 @@ def subset_font_raw(font_in, font_out, unicodes, opts):
6872
pe = None
6973
font = fontforge.open(font_in)
7074
if pe:
71-
print('Open("' + font_in + '")', file=pe)
75+
print(f'Open("{font_in}")', file=pe)
7276
extract_vert_to_script(font_in, pe)
7377
for i in unicodes:
7478
select_with_refs(font, i, font, pe, nam)
@@ -83,9 +87,10 @@ def subset_font_raw(font_in, font_out, unicodes, opts):
8387
for glyph in addl_glyphs:
8488
font.selection.select(('more',), glyph)
8589
if nam:
86-
print("0x%0.4X" % fontforge.unicodeFromName(glyph), glyph, file=nam)
90+
print(f"0x{fontforge.unicodeFromName(glyph):0.4X}", glyph,
91+
file=nam)
8792
if pe:
88-
print('SelectMore("%s")' % glyph, file=pe)
93+
print(f'SelectMore("{glyph}")', file=pe)
8994

9095
flags = ()
9196

@@ -149,19 +154,20 @@ def subset_font_raw(font_in, font_out, unicodes, opts):
149154
nam.close()
150155

151156
if pe:
152-
print('Generate("' + font_out + '")', file=pe)
157+
print(f'Generate("{font_out}")', file=pe)
153158
pe.close()
154159
subprocess.call(["fontforge", "-script", pe_fn])
155160
else:
156-
font.generate(font_out, flags = flags)
161+
font.generate(font_out, flags=flags)
157162
font.close()
158163

159164
if '--roundtrip' in opts:
160165
# FontForge apparently contains a bug where it incorrectly calculates
161166
# the advanceWidthMax in the hhea table, and a workaround is to open
162167
# and re-generate
163168
font2 = fontforge.open(font_out)
164-
font2.generate(font_out, flags = flags)
169+
font2.generate(font_out, flags=flags)
170+
165171

166172
def subset_font(font_in, font_out, unicodes, opts):
167173
font_out_raw = font_out
@@ -173,81 +179,97 @@ def subset_font(font_in, font_out, unicodes, opts):
173179
# 2011-02-14 DC this needs to only happen with --namelist is used
174180
# os.rename(font_out_raw + '.nam', font_out + '.nam')
175181

182+
176183
def getsubset(subset, font_in):
177184
subsets = subset.split('+')
178185

179-
quotes = [0x2013] # endash
180-
quotes += [0x2014] # emdash
181-
quotes += [0x2018] # quoteleft
182-
quotes += [0x2019] # quoteright
183-
quotes += [0x201A] # quotesinglbase
184-
quotes += [0x201C] # quotedblleft
185-
quotes += [0x201D] # quotedblright
186-
quotes += [0x201E] # quotedblbase
187-
quotes += [0x2022] # bullet
188-
quotes += [0x2039] # guilsinglleft
189-
quotes += [0x203A] # guilsinglright
190-
191-
latin = range(0x20, 0x7f) # Basic Latin (A-Z, a-z, numbers)
192-
latin += range(0xa0, 0x100) # Western European symbols and diacritics
193-
latin += [0x20ac] # Euro
194-
latin += [0x0152] # OE
195-
latin += [0x0153] # oe
196-
latin += [0x003b] # semicolon
197-
latin += [0x00b7] # periodcentered
198-
latin += [0x0131] # dotlessi
199-
latin += [0x02c6] # circumflex
200-
latin += [0x02da] # ring
201-
latin += [0x02dc] # tilde
202-
latin += [0x2074] # foursuperior
203-
latin += [0x2215] # division slash
204-
latin += [0x2044] # fraction slash
205-
latin += [0xe0ff] # PUA: Font logo
206-
latin += [0xeffd] # PUA: Font version number
207-
latin += [0xf000] # PUA: font ppem size indicator: run `ftview -f 1255 10 Ubuntu-Regular.ttf` to see it in action!
186+
quotes = [
187+
0x2013, # endash
188+
0x2014, # emdash
189+
0x2018, # quoteleft
190+
0x2019, # quoteright
191+
0x201A, # quotesinglbase
192+
0x201C, # quotedblleft
193+
0x201D, # quotedblright
194+
0x201E, # quotedblbase
195+
0x2022, # bullet
196+
0x2039, # guilsinglleft
197+
0x203A, # guilsinglright
198+
]
199+
200+
latin = [
201+
*range(0x20, 0x7f), # Basic Latin (A-Z, a-z, numbers)
202+
*range(0xa0, 0x100), # Western European symbols and diacritics
203+
0x20ac, # Euro
204+
0x0152, # OE
205+
0x0153, # oe
206+
0x003b, # semicolon
207+
0x00b7, # periodcentered
208+
0x0131, # dotlessi
209+
0x02c6, # circumflex
210+
0x02da, # ring
211+
0x02dc, # tilde
212+
0x2074, # foursuperior
213+
0x2215, # division slash
214+
0x2044, # fraction slash
215+
0xe0ff, # PUA: Font logo
216+
0xeffd, # PUA: Font version number
217+
0xf000, # PUA: font ppem size indicator: run
218+
# `ftview -f 1255 10 Ubuntu-Regular.ttf` to see it in action!
219+
]
208220

209221
result = quotes
210222

211223
if 'menu' in subset:
212224
font = fontforge.open(font_in)
213-
result = map(ord, font.familyname)
214-
result += [0x0020]
225+
result = [
226+
*map(ord, font.familyname),
227+
0x0020,
228+
]
215229

216230
if 'latin' in subset:
217231
result += latin
218232
if 'latin-ext' in subset:
219233
# These ranges include Extended A, B, C, D, and Additional with the
220234
# exception of Vietnamese, which is a separate range
221-
result += (range(0x100, 0x370) +
222-
range(0x1d00, 0x1ea0) +
223-
range(0x1ef2, 0x1f00) +
224-
range(0x2070, 0x20d0) +
225-
range(0x2c60, 0x2c80) +
226-
range(0xa700, 0xa800))
235+
result += [
236+
*range(0x100, 0x370),
237+
*range(0x1d00, 0x1ea0),
238+
*range(0x1ef2, 0x1f00),
239+
*range(0x2070, 0x20d0),
240+
*range(0x2c60, 0x2c80),
241+
*range(0xa700, 0xa800),
242+
]
227243
if 'vietnamese' in subset:
228-
# 2011-07-16 DC: Charset from http://vietunicode.sourceforge.net/charset/ + U+1ef9 from Fontaine
244+
# 2011-07-16 DC: Charset from
245+
# http://vietunicode.sourceforge.net/charset/ + U+1ef9 from Fontaine
229246
result += [0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00C8, 0x00C9,
230247
0x00CA, 0x00CC, 0x00CD, 0x00D2, 0x00D3, 0x00D4,
231248
0x00D5, 0x00D9, 0x00DA, 0x00DD, 0x00E0, 0x00E1,
232249
0x00E2, 0x00E3, 0x00E8, 0x00E9, 0x00EA, 0x00EC,
233250
0x00ED, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F9,
234251
0x00FA, 0x00FD, 0x0102, 0x0103, 0x0110, 0x0111,
235252
0x0128, 0x0129, 0x0168, 0x0169, 0x01A0, 0x01A1,
236-
0x01AF, 0x01B0, 0x20AB] + range(0x1EA0, 0x1EFA)
253+
0x01AF, 0x01B0, 0x20AB, *range(0x1EA0, 0x1EFA)]
237254
if 'greek' in subset:
238-
# Could probably be more aggressive here and exclude archaic characters,
239-
# but lack data
240-
result += range(0x370, 0x400)
255+
# Could probably be more aggressive here and exclude archaic
256+
# characters, but lack data
257+
result += [*range(0x370, 0x400)]
241258
if 'greek-ext' in subset:
242-
result += range(0x370, 0x400) + range(0x1f00, 0x2000)
259+
result += [*range(0x370, 0x400), *range(0x1f00, 0x2000)]
243260
if 'cyrillic' in subset:
244261
# Based on character frequency analysis
245-
result += range(0x400, 0x460) + [0x490, 0x491, 0x4b0, 0x4b1, 0x2116]
262+
result += [*range(0x400, 0x460), 0x490, 0x491, 0x4b0, 0x4b1, 0x2116]
246263
if 'cyrillic-ext' in subset:
247-
result += (range(0x400, 0x530) +
248-
[0x20b4, 0x2116] + # 0x2116 is the russian No, a number abbreviation similar to the latin #, suggested by Alexei Vanyashin
249-
range(0x2de0, 0x2e00) +
250-
range(0xa640, 0xa6a0))
264+
result += [
265+
*range(0x400, 0x530),
266+
0x20b4,
267+
# 0x2116 is the russian No, a number abbreviation similar to the
268+
# latin #, suggested by Alexei Vanyashin
269+
0x2116,
270+
*range(0x2de0, 0x2e00),
271+
*range(0xa640, 0xa6a0),
272+
]
251273
if 'arabic' in subset:
252274
# Based on Droid Arabic Kufi 1.0
253275
result += [0x000D, 0x0020, 0x0621, 0x0627, 0x062D,
@@ -295,7 +317,8 @@ def getsubset(subset, font_in):
295317
0x06C8, 0x06C9, 0x06CA, 0x06CB, 0x06CF, 0x06CE,
296318
0x06D0, 0x06D1, 0x06D4, 0x06FA, 0x06DD, 0x06DE,
297319
0x06E0, 0x06E9, 0x060D, 0xFD3E, 0xFD3F, 0x25CC,
298-
# Added from https://groups.google.com/d/topic/googlefontdirectory-discuss/MwlMWMPNCXs/discussion
320+
# Added from
321+
# https://groups.google.com/d/topic/googlefontdirectory-discuss/MwlMWMPNCXs/discussion
299322
0x063b, 0x063c, 0x063d, 0x063e, 0x063f, 0x0620,
300323
0x0674, 0x0674, 0x06EC]
301324

@@ -308,42 +331,48 @@ def getsubset(subset, font_in):
308331

309332
return result
310333

311-
# code for extracting vertical metrics from a TrueType font
312334

335+
# code for extracting vertical metrics from a TrueType font
313336
class Sfnt:
314337
def __init__(self, data):
315338
version, numTables, _, _, _ = struct.unpack('>IHHHH', data[:12])
316339
self.tables = {}
317340
for i in range(numTables):
318-
tag, checkSum, offset, length = struct.unpack('>4sIII', data[12 + 16 * i: 28 + 16 * i])
341+
tag, checkSum, offset, length = struct.unpack(
342+
'>4sIII', data[12 + 16 * i: 28 + 16 * i])
319343
self.tables[tag] = data[offset: offset + length]
320344

321345
def hhea(self):
322346
r = {}
323347
d = self.tables['hhea']
324-
r['Ascender'], r['Descender'], r['LineGap'] = struct.unpack('>hhh', d[4:10])
348+
r['Ascender'], r['Descender'], r['LineGap'] = struct.unpack(
349+
'>hhh', d[4:10])
325350
return r
326351

327352
def os2(self):
328353
r = {}
329354
d = self.tables['OS/2']
330355
r['fsSelection'], = struct.unpack('>H', d[62:64])
331-
r['sTypoAscender'], r['sTypoDescender'], r['sTypoLineGap'] = struct.unpack('>hhh', d[68:74])
332-
r['usWinAscender'], r['usWinDescender'] = struct.unpack('>HH', d[74:78])
356+
r['sTypoAscender'], r['sTypoDescender'], r['sTypoLineGap'] = \
357+
struct.unpack('>hhh', d[68:74])
358+
r['usWinAscender'], r['usWinDescender'] = struct.unpack(
359+
'>HH', d[74:78])
333360
return r
334361

362+
335363
def set_os2(pe, name, val):
336-
print('SetOS2Value("' + name + '", %d)' % val, file=pe)
364+
print(f'SetOS2Value("{name}", {val:d})', file=pe)
365+
337366

338367
def set_os2_vert(pe, name, val):
339368
set_os2(pe, name + 'IsOffset', 0)
340369
set_os2(pe, name, val)
341370

371+
342372
# Extract vertical metrics data directly out of font file, and emit
343373
# script code to set the values in the generated font. This is a (rather
344374
# ugly) workaround for the issue described in:
345-
# http://sourceforge.net/mailarchive/forum.php?thread_name=20100906085718.GB1907%40khaled-laptop&forum_name=fontforge-users
346-
375+
# https://sourceforge.net/p/fontforge/mailman/fontforge-users/thread/20100906085718.GB1907@khaled-laptop/
347376
def extract_vert_to_script(font_in, pe):
348377
with open(font_in, 'rb') as in_file:
349378
data = in_file.read()
@@ -357,11 +386,12 @@ def extract_vert_to_script(font_in, pe):
357386
set_os2_vert(pe, "HHeadAscent", hhea['Ascender'])
358387
set_os2_vert(pe, "HHeadDescent", hhea['Descender'])
359388

389+
360390
def main(argv):
361-
optlist, args = getopt.gnu_getopt(argv, '', ['string=', 'strip_names', 'opentype-features',
362-
'simplify', 'new', 'script',
363-
'nmr', 'roundtrip', 'subset=',
364-
'namelist', 'null', 'nd', 'move-display'])
391+
optlist, args = getopt.gnu_getopt(argv, '', [
392+
'string=', 'strip_names', 'opentype-features', 'simplify', 'new',
393+
'script', 'nmr', 'roundtrip', 'subset=', 'namelist', 'null', 'nd',
394+
'move-display'])
365395

366396
font_in, font_out = args
367397
opts = dict(optlist)
@@ -371,5 +401,6 @@ def main(argv):
371401
subset = getsubset(opts.get('--subset', 'latin'), font_in)
372402
subset_font(font_in, font_out, subset, opts)
373403

404+
374405
if __name__ == '__main__':
375406
main(sys.argv[1:])

0 commit comments

Comments
 (0)
0