Description
The T1 font parser is unable to handle some fonts (which conform to the spec). It complains:
>>> f = T1Font('some-t1-font')
fontTools.t1Lib.T1Error: can't find end of eexec part
In particular, this happens with (spec-conformant) fonts that don't have 64 consecutive ASCII 0
s immediately after the eexec
section:
$ tail -c 550 some-t1-font | xxd
00000000: 0a86 c365 74ba 6d9f 36e9 3030 3030 3030 ...et.m.6.000000
00000010: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000020: 3030 3030 3030 3030 3030 0a30 3030 3030 0000000000.00000
00000030: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000040: 3030 3030 3030 3030 3030 300a 3030 3030 00000000000.0000
00000050: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000060: 3030 3030 3030 3030 3030 3030 0a30 3030 000000000000.000
00000070: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000080: 3030 3030 3030 3030 3030 3030 300a 3030 0000000000000.00
00000090: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
000000a0: 3030 3030 3030 3030 3030 3030 3030 0a30 00000000000000.0
000000b0: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
000000c0: 3030 3030 3030 3030 3030 3030 3030 300a 000000000000000.
000000d0: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
000000e0: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
000000f0: 0a30 3030 3030 3030 3030 3030 3030 3030 .000000000000000
00000100: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000110: 300a 3030 3030 3030 3030 3030 3030 3030 0.00000000000000
00000120: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000130: 3030 0a30 3030 3030 3030 3030 3030 3030 00.0000000000000
00000140: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000150: 3030 300a 3030 3030 3030 3030 3030 3030 000.000000000000
00000160: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000170: 3030 3030 0a30 3030 3030 3030 3030 3030 0000.00000000000
00000180: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000190: 3030 3030 300a 3030 3030 3030 3030 3030 00000.0000000000
000001a0: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
000001b0: 3030 3030 3030 0a30 3030 3030 3030 3030 000000.000000000
000001c0: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
000001d0: 3030 3030 3030 300a 3030 3030 3030 3030 0000000.00000000
000001e0: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
000001f0: 3030 3030 3030 3030 0a30 3030 3030 3030 00000000.0000000
00000200: 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
00000210: 3030 3030 3030 3030 300a 636c 6561 7274 000000000.cleart
00000220: 6f6d 6172 6b0a omark.
The problem is that this file has runs of 32 ASCII 0
's separated by line feeds. According to the spec (page 14) this is valid:
The text encrypted by eexec must be followed by 512 ASCII zeros. There may be white space characters (blank, tab, carriage return or line feed) interspersed among these zeros.
The culprit here is:
fonttools/Lib/fontTools/t1Lib/__init__.py
Line 276 in f9d12be
fonttools/Lib/fontTools/t1Lib/__init__.py
Lines 308 to 329 in f9d12be
A contiguous run of 64 ASCII 0
s is expected. But it would be to spec to have 0\n0\t0\r0 0
etc. trailing the eexec section.
I have several different T1 fonts that exhibit this behavior (one such font is New Century Schoolbook--although I don't want to get you DMCA'd by uploading it). They can all be read with macOS Font Book and FontForge. And indeed, if I change EEXECEND = b'0' * 64
to EEXECEND = b'0' * 32
, fontTools successfully parses the font and is capable of drawing the glyphs.