Merge pull request #1523 from justvanrossum/cmap_update2
[cmap,VORG,COLR,otTables] misc idiomatic updates
This commit is contained in:
commit
a360252709
@ -6,7 +6,6 @@ from __future__ import print_function, division, absolute_import
|
|||||||
from fontTools.misc.py23 import *
|
from fontTools.misc.py23 import *
|
||||||
from fontTools.misc.textTools import safeEval
|
from fontTools.misc.textTools import safeEval
|
||||||
from . import DefaultTable
|
from . import DefaultTable
|
||||||
import operator
|
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
|
||||||
@ -44,12 +43,13 @@ class table_C_O_L_R_(DefaultTable.DefaultTable):
|
|||||||
|
|
||||||
self.ColorLayers = colorLayerLists = {}
|
self.ColorLayers = colorLayerLists = {}
|
||||||
try:
|
try:
|
||||||
names = list(map(operator.getitem, [glyphOrder]*numBaseGlyphRecords, gids))
|
names = [glyphOrder[gid] for gid in gids]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
getGlyphName = self.getGlyphName
|
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):
|
def compile(self, ttFont):
|
||||||
ordered = []
|
ordered = []
|
||||||
@ -112,7 +112,7 @@ class table_C_O_L_R_(DefaultTable.DefaultTable):
|
|||||||
layer = LayerRecord()
|
layer = LayerRecord()
|
||||||
layer.fromXML(element[0], element[1], element[2], ttFont)
|
layer.fromXML(element[0], element[1], element[2], ttFont)
|
||||||
layers.append (layer)
|
layers.append (layer)
|
||||||
operator.setitem(self, glyphName, layers)
|
self[glyphName] = layers
|
||||||
elif "value" in attrs:
|
elif "value" in attrs:
|
||||||
setattr(self, name, safeEval(attrs["value"]))
|
setattr(self, name, safeEval(attrs["value"]))
|
||||||
|
|
||||||
|
@ -30,25 +30,25 @@ class table_V_O_R_G_(DefaultTable.DefaultTable):
|
|||||||
self.VOriginRecords = vOrig = {}
|
self.VOriginRecords = vOrig = {}
|
||||||
glyphOrder = ttFont.getGlyphOrder()
|
glyphOrder = ttFont.getGlyphOrder()
|
||||||
try:
|
try:
|
||||||
names = map(operator.getitem, [glyphOrder]*self.numVertOriginYMetrics, gids)
|
names = [glyphOrder[gid] for gid in gids]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
getGlyphName = self.getGlyphName
|
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):
|
def compile(self, ttFont):
|
||||||
vorgs = list(self.VOriginRecords.values())
|
vorgs = list(self.VOriginRecords.values())
|
||||||
names = list(self.VOriginRecords.keys())
|
names = list(self.VOriginRecords.keys())
|
||||||
nameMap = ttFont.getReverseGlyphMap()
|
nameMap = ttFont.getReverseGlyphMap()
|
||||||
lenRecords = len(vorgs)
|
|
||||||
try:
|
try:
|
||||||
gids = map(operator.getitem, [nameMap]*lenRecords, names)
|
gids = [nameMap[name] for name in names]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
||||||
gids = map(operator.getitem, [nameMap]*lenRecords, names)
|
gids = [nameMap[name] for name in names]
|
||||||
vOriginTable = list(zip(gids, vorgs))
|
vOriginTable = list(zip(gids, vorgs))
|
||||||
self.numVertOriginYMetrics = lenRecords
|
self.numVertOriginYMetrics = len(vorgs)
|
||||||
vOriginTable.sort() # must be in ascending GID order
|
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)
|
header = struct.pack(">HHhH", self.majorVersion, self.minorVersion, self.defaultVertOriginY, self.numVertOriginYMetrics)
|
||||||
|
@ -8,7 +8,6 @@ from . import DefaultTable
|
|||||||
import sys
|
import sys
|
||||||
import struct
|
import struct
|
||||||
import array
|
import array
|
||||||
import operator
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
@ -442,13 +441,12 @@ class cmap_format_2(CmapSubtable):
|
|||||||
charCodes = [item[0] for item in items]
|
charCodes = [item[0] for item in items]
|
||||||
names = [item[1] for item in items]
|
names = [item[1] for item in items]
|
||||||
nameMap = ttFont.getReverseGlyphMap()
|
nameMap = ttFont.getReverseGlyphMap()
|
||||||
lenCharCodes = len(charCodes)
|
|
||||||
try:
|
try:
|
||||||
gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names))
|
gids = [nameMap[name] for name in names]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
||||||
try:
|
try:
|
||||||
gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names))
|
gids = [nameMap[name] for name in names]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# allow virtual GIDs in format 2 tables
|
# allow virtual GIDs in format 2 tables
|
||||||
gids = []
|
gids = []
|
||||||
@ -458,7 +456,7 @@ class cmap_format_2(CmapSubtable):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
if (name[:3] == 'gid'):
|
if (name[:3] == 'gid'):
|
||||||
gid = eval(name[3:])
|
gid = int(name[3:])
|
||||||
else:
|
else:
|
||||||
gid = ttFont.getGlyphID(name)
|
gid = ttFont.getGlyphID(name)
|
||||||
except:
|
except:
|
||||||
@ -744,20 +742,19 @@ class cmap_format_4(CmapSubtable):
|
|||||||
return struct.pack(">HHH", self.format, self.length, self.language) + self.data
|
return struct.pack(">HHH", self.format, self.length, self.language) + self.data
|
||||||
|
|
||||||
charCodes = list(self.cmap.keys())
|
charCodes = list(self.cmap.keys())
|
||||||
lenCharCodes = len(charCodes)
|
if not charCodes:
|
||||||
if lenCharCodes == 0:
|
|
||||||
startCode = [0xffff]
|
startCode = [0xffff]
|
||||||
endCode = [0xffff]
|
endCode = [0xffff]
|
||||||
else:
|
else:
|
||||||
charCodes.sort()
|
charCodes.sort()
|
||||||
names = list(map(operator.getitem, [self.cmap]*lenCharCodes, charCodes))
|
names = [self.cmap[code] for code in charCodes]
|
||||||
nameMap = ttFont.getReverseGlyphMap()
|
nameMap = ttFont.getReverseGlyphMap()
|
||||||
try:
|
try:
|
||||||
gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names))
|
gids = [nameMap[name] for name in names]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
||||||
try:
|
try:
|
||||||
gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names))
|
gids = [nameMap[name] for name in names]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# allow virtual GIDs in format 4 tables
|
# allow virtual GIDs in format 4 tables
|
||||||
gids = []
|
gids = []
|
||||||
@ -767,7 +764,7 @@ class cmap_format_4(CmapSubtable):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
if (name[:3] == 'gid'):
|
if (name[:3] == 'gid'):
|
||||||
gid = eval(name[3:])
|
gid = int(name[3:])
|
||||||
else:
|
else:
|
||||||
gid = ttFont.getGlyphID(name)
|
gid = ttFont.getGlyphID(name)
|
||||||
except:
|
except:
|
||||||
@ -775,7 +772,8 @@ class cmap_format_4(CmapSubtable):
|
|||||||
|
|
||||||
gids.append(gid)
|
gids.append(gid)
|
||||||
cmap = {} # code:glyphID mapping
|
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.
|
# Build startCode and endCode lists.
|
||||||
# Split the char codes in ranges of consecutive char codes, then split
|
# 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:
|
if self.data:
|
||||||
return struct.pack(">HHLLL", self.format, self.reserved, self.length, self.language, self.nGroups) + self.data
|
return struct.pack(">HHLLL", self.format, self.reserved, self.length, self.language, self.nGroups) + self.data
|
||||||
charCodes = list(self.cmap.keys())
|
charCodes = list(self.cmap.keys())
|
||||||
lenCharCodes = len(charCodes)
|
|
||||||
names = list(self.cmap.values())
|
names = list(self.cmap.values())
|
||||||
nameMap = ttFont.getReverseGlyphMap()
|
nameMap = ttFont.getReverseGlyphMap()
|
||||||
try:
|
try:
|
||||||
gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names))
|
gids = [nameMap[name] for name in names]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
nameMap = ttFont.getReverseGlyphMap(rebuild=True)
|
||||||
try:
|
try:
|
||||||
gids = list(map(operator.getitem, [nameMap]*lenCharCodes, names))
|
gids = [nameMap[name] for name in names]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# allow virtual GIDs in format 12 tables
|
# allow virtual GIDs in format 12 tables
|
||||||
gids = []
|
gids = []
|
||||||
@ -973,7 +970,7 @@ class cmap_format_12_or_13(CmapSubtable):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
if (name[:3] == 'gid'):
|
if (name[:3] == 'gid'):
|
||||||
gid = eval(name[3:])
|
gid = int(name[3:])
|
||||||
else:
|
else:
|
||||||
gid = ttFont.getGlyphID(name)
|
gid = ttFont.getGlyphID(name)
|
||||||
except:
|
except:
|
||||||
@ -982,7 +979,8 @@ class cmap_format_12_or_13(CmapSubtable):
|
|||||||
gids.append(gid)
|
gids.append(gid)
|
||||||
|
|
||||||
cmap = {} # code:glyphID mapping
|
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()
|
charCodes.sort()
|
||||||
index = 0
|
index = 0
|
||||||
|
@ -9,7 +9,6 @@ from __future__ import print_function, division, absolute_import, unicode_litera
|
|||||||
from fontTools.misc.py23 import *
|
from fontTools.misc.py23 import *
|
||||||
from fontTools.misc.textTools import pad, safeEval
|
from fontTools.misc.textTools import pad, safeEval
|
||||||
from .otBase import BaseTable, FormatSwitchingBaseTable, ValueRecord
|
from .otBase import BaseTable, FormatSwitchingBaseTable, ValueRecord
|
||||||
import operator
|
|
||||||
import logging
|
import logging
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
@ -698,18 +697,19 @@ class SingleSubst(FormatSwitchingBaseTable):
|
|||||||
def postRead(self, rawTable, font):
|
def postRead(self, rawTable, font):
|
||||||
mapping = {}
|
mapping = {}
|
||||||
input = _getGlyphsFromCoverageTable(rawTable["Coverage"])
|
input = _getGlyphsFromCoverageTable(rawTable["Coverage"])
|
||||||
lenMapping = len(input)
|
|
||||||
if self.Format == 1:
|
if self.Format == 1:
|
||||||
delta = rawTable["DeltaGlyphID"]
|
delta = rawTable["DeltaGlyphID"]
|
||||||
inputGIDS = [ font.getGlyphID(name) for name in input ]
|
inputGIDS = [ font.getGlyphID(name) for name in input ]
|
||||||
outGIDS = [ (glyphID + delta) % 65536 for glyphID in inputGIDS ]
|
outGIDS = [ (glyphID + delta) % 65536 for glyphID in inputGIDS ]
|
||||||
outNames = [ font.getGlyphName(glyphID) for glyphID in outGIDS ]
|
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:
|
elif self.Format == 2:
|
||||||
assert len(input) == rawTable["GlyphCount"], \
|
assert len(input) == rawTable["GlyphCount"], \
|
||||||
"invalid SingleSubstFormat2 table"
|
"invalid SingleSubstFormat2 table"
|
||||||
subst = rawTable["Substitute"]
|
subst = rawTable["Substitute"]
|
||||||
list(map(operator.setitem, [mapping]*lenMapping, input, subst))
|
for inp, sub in zip(input, subst):
|
||||||
|
mapping[inp] = sub
|
||||||
else:
|
else:
|
||||||
assert 0, "unknown format: %s" % self.Format
|
assert 0, "unknown format: %s" % self.Format
|
||||||
self.mapping = mapping
|
self.mapping = mapping
|
||||||
|
@ -51,6 +51,47 @@ class CmapSubtableTest(unittest.TestCase):
|
|||||||
self.assertEqual(subtable.getEncoding("ascii"), "ascii")
|
self.assertEqual(subtable.getEncoding("ascii"), "ascii")
|
||||||
self.assertEqual(subtable.getEncoding(default="xyz"), "xyz")
|
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):
|
def test_decompile_4(self):
|
||||||
subtable = CmapSubtable.newSubtable(4)
|
subtable = CmapSubtable.newSubtable(4)
|
||||||
font = ttLib.TTFont()
|
font = ttLib.TTFont()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user