2
2
A PostScript backend, which can produce both PostScript .ps and .eps.
3
3
"""
4
4
5
- import binascii
6
5
import bisect
7
6
import codecs
8
7
import datetime
9
8
from enum import Enum
10
9
import functools
11
- from io import BytesIO , StringIO
10
+ from io import StringIO
12
11
import itertools
13
12
import logging
14
13
import math
@@ -272,6 +271,7 @@ def _serialize_type42(font, subset, fontdata):
272
271
def _version_and_breakpoints (loca , fontdata ):
273
272
"""
274
273
Read the version number of the font and determine sfnts breakpoints.
274
+
275
275
When a TrueType font file is written as a Type 42 font, it has to be
276
276
broken into substrings of at most 65535 bytes. These substrings must
277
277
begin at font table boundaries or glyph boundaries in the glyf table.
@@ -289,31 +289,24 @@ def _version_and_breakpoints(loca, fontdata):
289
289
290
290
Returns
291
291
-------
292
- tuple
293
- ((v1, v2), breakpoints) where v1 is the major version number,
294
- v2 is the minor version number and breakpoints is a sorted list
295
- of offsets into fontdata; if loca is not available, just the table
296
- boundaries
292
+ version : tuple[int, int]
293
+ A 2-tuple of the major version number and minor version number.
294
+ breakpoints : list[int]
295
+ The breakpoints is a sorted list of offsets into fontdata; if loca is not
296
+ available, just the table boundaries.
297
297
"""
298
298
v1 , v2 , numTables = struct .unpack ('>3h' , fontdata [:6 ])
299
299
version = (v1 , v2 )
300
300
301
301
tables = {}
302
302
for i in range (numTables ):
303
- tag , _ , offset , _ = struct .unpack (
304
- '>4sIII' ,
305
- fontdata [12 + i * 16 :12 + (i + 1 )* 16 ]
306
- )
303
+ tag , _ , offset , _ = struct .unpack ('>4sIII' , fontdata [12 + i * 16 :12 + (i + 1 )* 16 ])
307
304
tables [tag .decode ('ascii' )] = offset
308
305
if loca is not None :
309
- glyf_breakpoints = {
310
- tables ['glyf' ] + offset for offset in loca .locations [:- 1 ]
311
- }
306
+ glyf_breakpoints = {tables ['glyf' ] + offset for offset in loca .locations [:- 1 ]}
312
307
else :
313
308
glyf_breakpoints = set ()
314
- breakpoints = sorted (
315
- set (tables .values ()) | glyf_breakpoints | {len (fontdata )}
316
- )
309
+ breakpoints = sorted ({* tables .values (), * glyf_breakpoints , len (fontdata )})
317
310
318
311
return version , breakpoints
319
312
@@ -359,13 +352,12 @@ def _charstrings(font):
359
352
str
360
353
A definition of the CharStrings dictionary in PostScript
361
354
"""
362
- s = StringIO ()
363
355
go = font .getGlyphOrder ()
364
- s . write ( f'/CharStrings { len (go )} dict dup begin\n ' )
356
+ s = f'/CharStrings { len (go )} dict dup begin\n '
365
357
for i , name in enumerate (go ):
366
- s . write ( f'/{ name } { i } def\n ' )
367
- s . write ( 'end readonly def' )
368
- return s . getvalue ()
358
+ s += f'/{ name } { i } def\n '
359
+ s += 'end readonly def'
360
+ return s
369
361
370
362
371
363
def _sfnts (fontdata , font , breakpoints ):
@@ -389,21 +381,17 @@ def _sfnts(fontdata, font, breakpoints):
389
381
The sfnts array for the font definition, consisting
390
382
of hex-encoded strings in PostScript format
391
383
"""
392
- b = BytesIO ()
393
- b .write (b'/sfnts[' )
384
+ s = '/sfnts['
394
385
pos = 0
395
386
while pos < len (fontdata ):
396
387
i = bisect .bisect_left (breakpoints , pos + 65534 )
397
388
newpos = breakpoints [i - 1 ]
398
389
if newpos <= pos :
399
390
# have to accept a larger string
400
391
newpos = breakpoints [- 1 ]
401
- b .write (b'<' )
402
- b .write (binascii .hexlify (fontdata [pos :newpos ]))
403
- b .write (b'00>' ) # need an extra zero byte on every string
392
+ s += f'<{ fontdata [pos :newpos ].hex ()} 00>' # Always NUL terminate.
404
393
pos = newpos
405
- b .write (b']def' )
406
- s = b .getvalue ().decode ('ascii' )
394
+ s += ']def'
407
395
return '\n ' .join (s [i :i + 100 ] for i in range (0 , len (s ), 100 ))
408
396
409
397
0 commit comments