diff --git a/Lib/fontTools/ttLib/tables/C_O_L_R_.py b/Lib/fontTools/ttLib/tables/C_O_L_R_.py index 743fa915d..441242ee7 100644 --- a/Lib/fontTools/ttLib/tables/C_O_L_R_.py +++ b/Lib/fontTools/ttLib/tables/C_O_L_R_.py @@ -6,7 +6,6 @@ from __future__ import print_function, division, absolute_import from fontTools.misc.py23 import * from fontTools.misc.textTools import safeEval from . import DefaultTable -import operator import struct @@ -44,12 +43,13 @@ class table_C_O_L_R_(DefaultTable.DefaultTable): self.ColorLayers = colorLayerLists = {} try: - names = list(map(operator.getitem, [glyphOrder]*numBaseGlyphRecords, gids)) + names = [glyphOrder[gid] for gid in gids] except IndexError: getGlyphName = self.getGlyphName - names = list(map(getGlyphName, gids )) + names = map(getGlyphName, gids) - list(map(operator.setitem, [colorLayerLists]*numBaseGlyphRecords, names, layerLists)) + for name, layerList in zip(names, layerLists): + colorLayerLists[name] = layerList def compile(self, ttFont): ordered = [] @@ -112,7 +112,7 @@ class table_C_O_L_R_(DefaultTable.DefaultTable): layer = LayerRecord() layer.fromXML(element[0], element[1], element[2], ttFont) layers.append (layer) - operator.setitem(self, glyphName, layers) + self[glyphName] = layers elif "value" in attrs: setattr(self, name, safeEval(attrs["value"])) diff --git a/Lib/fontTools/ttLib/tables/V_O_R_G_.py b/Lib/fontTools/ttLib/tables/V_O_R_G_.py index 8b2c317a5..1b7529406 100644 --- a/Lib/fontTools/ttLib/tables/V_O_R_G_.py +++ b/Lib/fontTools/ttLib/tables/V_O_R_G_.py @@ -30,27 +30,27 @@ class table_V_O_R_G_(DefaultTable.DefaultTable): self.VOriginRecords = vOrig = {} glyphOrder = ttFont.getGlyphOrder() try: - names = map(operator.getitem, [glyphOrder]*self.numVertOriginYMetrics, gids) + names = [glyphOrder[gid] for gid in gids] except IndexError: getGlyphName = self.getGlyphName - names = map(getGlyphName, gids ) + names = map(getGlyphName, gids) - list(map(operator.setitem, [vOrig]*self.numVertOriginYMetrics, names, vids)) + for name, vid in zip(names, vids): + vOrig[name] = vid def compile(self, ttFont): vorgs = list(self.VOriginRecords.values()) names = list(self.VOriginRecords.keys()) nameMap = ttFont.getReverseGlyphMap() - lenRecords = len(vorgs) try: - gids = map(operator.getitem, [nameMap]*lenRecords, names) + gids = [nameMap[name] for name in names] except KeyError: nameMap = ttFont.getReverseGlyphMap(rebuild=True) - gids = map(operator.getitem, [nameMap]*lenRecords, names) + gids = [nameMap[name] for name in names] vOriginTable = list(zip(gids, vorgs)) - self.numVertOriginYMetrics = lenRecords + self.numVertOriginYMetrics = len(vorgs) vOriginTable.sort() # must be in ascending GID order - dataList = [ struct.pack(">Hh", rec[0], rec[1]) for rec in vOriginTable] + dataList = [struct.pack(">Hh", rec[0], rec[1]) for rec in vOriginTable] header = struct.pack(">HHhH", self.majorVersion, self.minorVersion, self.defaultVertOriginY, self.numVertOriginYMetrics) dataList.insert(0, header) data = bytesjoin(dataList) diff --git a/Lib/fontTools/ttLib/tables/_c_m_a_p.py b/Lib/fontTools/ttLib/tables/_c_m_a_p.py index 1767ad4c6..971a3163b 100644 --- a/Lib/fontTools/ttLib/tables/_c_m_a_p.py +++ b/Lib/fontTools/ttLib/tables/_c_m_a_p.py @@ -8,7 +8,6 @@ from . import DefaultTable import sys import struct import array -import operator import logging @@ -442,13 +441,12 @@ class cmap_format_2(CmapSubtable): charCodes = [item[0] for item in items] names = [item[1] for item in items] nameMap = ttFont.getReverseGlyphMap() - lenCharCodes = len(charCodes) try: - gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names)) + gids = [nameMap[name] for name in names] except KeyError: nameMap = ttFont.getReverseGlyphMap(rebuild=True) try: - gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names)) + gids = [nameMap[name] for name in names] except KeyError: # allow virtual GIDs in format 2 tables gids = [] @@ -458,7 +456,7 @@ class cmap_format_2(CmapSubtable): except KeyError: try: if (name[:3] == 'gid'): - gid = eval(name[3:]) + gid = int(name[3:]) else: gid = ttFont.getGlyphID(name) except: @@ -744,20 +742,19 @@ class cmap_format_4(CmapSubtable): return struct.pack(">HHH", self.format, self.length, self.language) + self.data charCodes = list(self.cmap.keys()) - lenCharCodes = len(charCodes) - if lenCharCodes == 0: + if not charCodes: startCode = [0xffff] endCode = [0xffff] else: charCodes.sort() - names = list(map(operator.getitem, [self.cmap]*lenCharCodes, charCodes)) + names = [self.cmap[code] for code in charCodes] nameMap = ttFont.getReverseGlyphMap() try: - gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names)) + gids = [nameMap[name] for name in names] except KeyError: nameMap = ttFont.getReverseGlyphMap(rebuild=True) try: - gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names)) + gids = [nameMap[name] for name in names] except KeyError: # allow virtual GIDs in format 4 tables gids = [] @@ -767,7 +764,7 @@ class cmap_format_4(CmapSubtable): except KeyError: try: if (name[:3] == 'gid'): - gid = eval(name[3:]) + gid = int(name[3:]) else: gid = ttFont.getGlyphID(name) except: @@ -775,7 +772,8 @@ class cmap_format_4(CmapSubtable): gids.append(gid) cmap = {} # code:glyphID mapping - list(map(operator.setitem, [cmap]*len(charCodes), charCodes, gids)) + for code, gid in zip(charCodes, gids): + cmap[code] = gid # Build startCode and endCode lists. # Split the char codes in ranges of consecutive char codes, then split @@ -955,15 +953,14 @@ class cmap_format_12_or_13(CmapSubtable): if self.data: return struct.pack(">HHLLL", self.format, self.reserved, self.length, self.language, self.nGroups) + self.data charCodes = list(self.cmap.keys()) - lenCharCodes = len(charCodes) names = list(self.cmap.values()) nameMap = ttFont.getReverseGlyphMap() try: - gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names)) + gids = [nameMap[name] for name in names] except KeyError: nameMap = ttFont.getReverseGlyphMap(rebuild=True) try: - gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names)) + gids = [nameMap[name] for name in names] except KeyError: # allow virtual GIDs in format 12 tables gids = [] @@ -973,7 +970,7 @@ class cmap_format_12_or_13(CmapSubtable): except KeyError: try: if (name[:3] == 'gid'): - gid = eval(name[3:]) + gid = int(name[3:]) else: gid = ttFont.getGlyphID(name) except: @@ -982,7 +979,8 @@ class cmap_format_12_or_13(CmapSubtable): gids.append(gid) cmap = {} # code:glyphID mapping - list(map(operator.setitem, [cmap]*len(charCodes), charCodes, gids)) + for code, gid in zip(charCodes, gids): + cmap[code] = gid charCodes.sort() index = 0 diff --git a/Lib/fontTools/ttLib/tables/otTables.py b/Lib/fontTools/ttLib/tables/otTables.py index 4d2bc574f..af2a7c6cd 100644 --- a/Lib/fontTools/ttLib/tables/otTables.py +++ b/Lib/fontTools/ttLib/tables/otTables.py @@ -9,7 +9,6 @@ from __future__ import print_function, division, absolute_import, unicode_litera from fontTools.misc.py23 import * from fontTools.misc.textTools import pad, safeEval from .otBase import BaseTable, FormatSwitchingBaseTable, ValueRecord -import operator import logging import struct @@ -698,18 +697,19 @@ class SingleSubst(FormatSwitchingBaseTable): def postRead(self, rawTable, font): mapping = {} input = _getGlyphsFromCoverageTable(rawTable["Coverage"]) - lenMapping = len(input) if self.Format == 1: delta = rawTable["DeltaGlyphID"] inputGIDS = [ font.getGlyphID(name) for name in input ] outGIDS = [ (glyphID + delta) % 65536 for glyphID in inputGIDS ] outNames = [ font.getGlyphName(glyphID) for glyphID in outGIDS ] - list(map(operator.setitem, [mapping]*lenMapping, input, outNames)) + for inp, out in zip(input, outNames): + mapping[inp] = out elif self.Format == 2: assert len(input) == rawTable["GlyphCount"], \ "invalid SingleSubstFormat2 table" subst = rawTable["Substitute"] - list(map(operator.setitem, [mapping]*lenMapping, input, subst)) + for inp, sub in zip(input, subst): + mapping[inp] = sub else: assert 0, "unknown format: %s" % self.Format self.mapping = mapping diff --git a/Tests/ttLib/tables/_c_m_a_p_test.py b/Tests/ttLib/tables/_c_m_a_p_test.py index 306d04894..233cd14fe 100644 --- a/Tests/ttLib/tables/_c_m_a_p_test.py +++ b/Tests/ttLib/tables/_c_m_a_p_test.py @@ -51,6 +51,47 @@ class CmapSubtableTest(unittest.TestCase): self.assertEqual(subtable.getEncoding("ascii"), "ascii") self.assertEqual(subtable.getEncoding(default="xyz"), "xyz") + def test_compile_2(self): + subtable = self.makeSubtable(2, 1, 2, 0) + subtable.cmap = {c: "cid%05d" % c for c in range(32, 8192)} + font = ttLib.TTFont() + font.setGlyphOrder([".notdef"] + list(subtable.cmap.values())) + data = subtable.compile(font) + + subtable2 = CmapSubtable.newSubtable(2) + subtable2.decompile(data, font) + self.assertEqual(subtable2.cmap, subtable.cmap) + + def test_compile_2_rebuild_rev_glyph_order(self): + for fmt in [2, 4, 12]: + subtable = self.makeSubtable(fmt, 1, 2, 0) + subtable.cmap = {c: "cid%05d" % c for c in range(32, 8192)} + font = ttLib.TTFont() + font.setGlyphOrder([".notdef"] + list(subtable.cmap.values())) + font._reverseGlyphOrderDict = {} # force first KeyError branch in subtable.compile() + data = subtable.compile(font) + subtable2 = CmapSubtable.newSubtable(fmt) + subtable2.decompile(data, font) + self.assertEqual(subtable2.cmap, subtable.cmap, str(fmt)) + + def test_compile_2_gids(self): + for fmt in [2, 4, 12]: + subtable = self.makeSubtable(fmt, 1, 3, 0) + subtable.cmap = {0x0041:'gid001', 0x0042:'gid002'} + font = ttLib.TTFont() + font.setGlyphOrder([".notdef"]) + data = subtable.compile(font) + + def test_compile_decompile_4_empty(self): + subtable = self.makeSubtable(4, 3, 1, 0) + subtable.cmap = {} + font = ttLib.TTFont() + font.setGlyphOrder([]) + data = subtable.compile(font) + subtable2 = CmapSubtable.newSubtable(4) + subtable2.decompile(data, font) + self.assertEqual(subtable2.cmap, {}) + def test_decompile_4(self): subtable = CmapSubtable.newSubtable(4) font = ttLib.TTFont()