Merge pull request #3240 from fonttools/issue3238

[t1Lib] Fix several Type 1 issues
This commit is contained in:
Just van Rossum 2023-08-04 09:57:37 +02:00 committed by GitHub
commit 7d6d0575de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,4 +1,4 @@
"""fontTools.t1Lib.py -- Tools for PostScript Type 1 fonts (Python2 only) """fontTools.t1Lib.py -- Tools for PostScript Type 1 fonts.
Functions for reading and writing raw Type 1 data: Functions for reading and writing raw Type 1 data:
@ -170,8 +170,13 @@ class T1Font(object):
# '-|', '|-', '|' # '-|', '|-', '|'
RD_key, ND_key, NP_key = None, None, None RD_key, ND_key, NP_key = None, None, None
lenIV = 4
subrs = std_subrs
for key, value in eexec_dict.items(): # Ensure we look at Private first, because we need RD_key, ND_key, NP_key and lenIV
sortedItems = sorted(eexec_dict.items(), key=lambda item: item[0] != "Private")
for key, value in sortedItems:
if key == "Private": if key == "Private":
pr = eexec_dict["Private"] pr = eexec_dict["Private"]
# follow t1write.c:writePrivateDict # follow t1write.c:writePrivateDict
@ -183,20 +188,25 @@ class T1Font(object):
for subkey, subvalue in pr.items(): for subkey, subvalue in pr.items():
if not RD_key and subvalue == RD_value: if not RD_key and subvalue == RD_value:
RD_key = subkey RD_key = subkey
elif not ND_key and subvalue == ND_value: elif not ND_key and subvalue in ND_values:
ND_key = subkey ND_key = subkey
elif not NP_key and subvalue == PD_value: elif not NP_key and subvalue in PD_values:
NP_key = subkey NP_key = subkey
if subkey == "lenIV":
lenIV = subvalue
if subkey == "OtherSubrs": if subkey == "OtherSubrs":
# XXX: assert that no flex hint is used # XXX: assert that no flex hint is used
lines.append(self._tobytes(hintothers)) lines.append(self._tobytes(hintothers))
elif subkey == "Subrs": elif subkey == "Subrs":
# XXX: standard Subrs only for subr_bin in subvalue:
lines.append(b"/Subrs 5 array") subr_bin.compile()
for i, subr_bin in enumerate(std_subrs): subrs = [subr_bin.bytecode for subr_bin in subvalue]
lines.append(f"/Subrs {len(subrs)} array".encode("ascii"))
for i, subr_bin in enumerate(subrs):
encrypted_subr, R = eexec.encrypt( encrypted_subr, R = eexec.encrypt(
bytesjoin([char_IV, subr_bin]), 4330 bytesjoin([char_IV[:lenIV], subr_bin]), 4330
) )
lines.append( lines.append(
bytesjoin( bytesjoin(
@ -222,7 +232,7 @@ class T1Font(object):
for glyph_name, char_bin in eexec_dict["CharStrings"].items(): for glyph_name, char_bin in eexec_dict["CharStrings"].items():
char_bin.compile() char_bin.compile()
encrypted_char, R = eexec.encrypt( encrypted_char, R = eexec.encrypt(
bytesjoin([char_IV, char_bin.bytecode]), 4330 bytesjoin([char_IV[:lenIV], char_bin.bytecode]), 4330
) )
lines.append( lines.append(
bytesjoin( bytesjoin(
@ -634,5 +644,5 @@ std_subrs = [
eexec_IV = b"cccc" eexec_IV = b"cccc"
char_IV = b"\x0c\x0c\x0c\x0c" char_IV = b"\x0c\x0c\x0c\x0c"
RD_value = ("string", "currentfile", "exch", "readstring", "pop") RD_value = ("string", "currentfile", "exch", "readstring", "pop")
ND_value = ("def",) ND_values = [("def",), ("noaccess", "def")]
PD_value = ("put",) PD_values = [("put",), ("noaccess", "put")]