Behdad Esfahbod 2021-08-21 11:16:27 -06:00
parent 3ec769907b
commit 7a22c0fb07
4 changed files with 31 additions and 23 deletions

View File

@ -57,6 +57,9 @@ class FakeFont:
def getGlyphID(self, name): def getGlyphID(self, name):
return self.reverseGlyphOrderDict_[name] return self.reverseGlyphOrderDict_[name]
def getGlyphIDMany(self, lst):
return [self.getGlyphID(gid) for gid in lst]
def getGlyphName(self, glyphID): def getGlyphName(self, glyphID):
if glyphID < len(self.glyphOrder_): if glyphID < len(self.glyphOrder_):
return self.glyphOrder_[glyphID] return self.glyphOrder_[glyphID]

View File

@ -347,18 +347,11 @@ class GlyphID(SimpleValue):
staticSize = 2 staticSize = 2
typecode = "H" typecode = "H"
def readArray(self, reader, font, tableDict, count): def readArray(self, reader, font, tableDict, count):
gids = reader.readArray(self.typecode, self.staticSize, count) return font.getGlyphNameMany(reader.readArray(self.typecode, self.staticSize, count))
return font.getGlyphNameMany(gids)
def read(self, reader, font, tableDict): def read(self, reader, font, tableDict):
return font.getGlyphName(reader.readValue(self.typecode, self.staticSize)) return font.getGlyphName(reader.readValue(self.typecode, self.staticSize))
def writeArray(self, writer, font, tableDict, values): def writeArray(self, writer, font, tableDict, values):
glyphMap = font.getReverseGlyphMap() writer.writeArray(self.typecode, font.getGlyphIDMany(values))
try:
values = [glyphMap[glyphname] for glyphname in values]
except KeyError:
# Slower, but will not throw a KeyError on an out-of-range glyph name.
values = [font.getGlyphID(glyphname) for glyphname in values]
writer.writeArray(self.typecode, values)
def write(self, writer, font, tableDict, value, repeatIndex=None): def write(self, writer, font, tableDict, value, repeatIndex=None):
writer.writeValue(self.typecode, font.getGlyphID(value)) writer.writeValue(self.typecode, font.getGlyphID(value))

View File

@ -549,10 +549,9 @@ class Coverage(FormatSwitchingBaseTable):
glyphs = self.glyphs = [] glyphs = self.glyphs = []
format = 1 format = 1
rawTable = {"GlyphArray": glyphs} rawTable = {"GlyphArray": glyphs}
getGlyphID = font.getGlyphID
if glyphs: if glyphs:
# find out whether Format 2 is more compact or not # find out whether Format 2 is more compact or not
glyphIDs = [getGlyphID(glyphName) for glyphName in glyphs ] glyphIDs = font.getGlyphIDMany(glyphs)
brokenOrder = sorted(glyphIDs) != glyphIDs brokenOrder = sorted(glyphIDs) != glyphIDs
last = glyphIDs[0] last = glyphIDs[0]
@ -751,7 +750,7 @@ class SingleSubst(FormatSwitchingBaseTable):
input = _getGlyphsFromCoverageTable(rawTable["Coverage"]) input = _getGlyphsFromCoverageTable(rawTable["Coverage"])
if self.Format == 1: if self.Format == 1:
delta = rawTable["DeltaGlyphID"] delta = rawTable["DeltaGlyphID"]
inputGIDS = [ font.getGlyphID(name) for name in input ] inputGIDS = font.getGlyphIDMany(input)
outGIDS = [ (glyphID + delta) % 65536 for glyphID in inputGIDS ] outGIDS = [ (glyphID + delta) % 65536 for glyphID in inputGIDS ]
outNames = font.getGlyphNameMany(outGIDS) outNames = font.getGlyphNameMany(outGIDS)
for inp, out in zip(input, outNames): for inp, out in zip(input, outNames):

View File

@ -533,6 +533,7 @@ class TTFont(object):
return self.getGlyphOrder()[glyphID] return self.getGlyphOrder()[glyphID]
except IndexError: except IndexError:
return "glyph%.5d" % glyphID return "glyph%.5d" % glyphID
def getGlyphNameMany(self, lst): def getGlyphNameMany(self, lst):
glyphOrder = self.getGlyphOrder(); glyphOrder = self.getGlyphOrder();
cnt = len(glyphOrder) cnt = len(glyphOrder)
@ -540,14 +541,15 @@ class TTFont(object):
for gid in lst] for gid in lst]
def getGlyphID(self, glyphName): def getGlyphID(self, glyphName):
if not hasattr(self, "_reverseGlyphOrderDict"):
self._buildReverseGlyphOrderDict()
glyphOrder = self.getGlyphOrder() glyphOrder = self.getGlyphOrder()
d = self._reverseGlyphOrderDict d = self.getReverseGlyphMap()
if glyphName not in d:
glyphID = d.get(glyphName)
if glyphID is None:
# TODO This check is really expensive
if glyphName in glyphOrder: if glyphName in glyphOrder:
self._buildReverseGlyphOrderDict() return self._buildReverseGlyphOrderDict()[glyphName]
return self.getGlyphID(glyphName)
else: else:
# Handle glyphXXX only # Handle glyphXXX only
if glyphName[:5] == "glyph": if glyphName[:5] == "glyph":
@ -556,12 +558,22 @@ class TTFont(object):
except (NameError, ValueError): except (NameError, ValueError):
raise KeyError(glyphName) raise KeyError(glyphName)
glyphID = d[glyphName]
if glyphName != glyphOrder[glyphID]: if glyphName != glyphOrder[glyphID]:
self._buildReverseGlyphOrderDict() return self._buildReverseGlyphOrderDict()[glyphName]
return self.getGlyphID(glyphName)
return glyphID return glyphID
def getGlyphIDMany(self, lst):
d = self.getReverseGlyphMap()
glyphIDs = [d.get(glyphName) for glyphName in lst]
if any(glyphID is None for glyphID in glyphIDs):
getGlyphID = self.getGlyphID
return [getGlyphID(glyphName) for glyphName in lst]
return glyphIDs
def getReverseGlyphMap(self, rebuild=False): def getReverseGlyphMap(self, rebuild=False):
if rebuild or not hasattr(self, "_reverseGlyphOrderDict"): if rebuild or not hasattr(self, "_reverseGlyphOrderDict"):
self._buildReverseGlyphOrderDict() self._buildReverseGlyphOrderDict()
@ -570,8 +582,9 @@ class TTFont(object):
def _buildReverseGlyphOrderDict(self): def _buildReverseGlyphOrderDict(self):
self._reverseGlyphOrderDict = d = {} self._reverseGlyphOrderDict = d = {}
glyphOrder = self.getGlyphOrder() glyphOrder = self.getGlyphOrder()
for glyphID in range(len(glyphOrder)): for glyphID,glyphName in enumerate(self.getGlyphOrder()):
d[glyphOrder[glyphID]] = glyphID d[glyphName] = glyphID
return d
def _writeTable(self, tag, writer, done, tableCache=None): def _writeTable(self, tag, writer, done, tableCache=None):
"""Internal helper function for self.save(). Keeps track of """Internal helper function for self.save(). Keeps track of