Fix read/write of VarIdxMap to use glyph names

Was relying on glyph IDs. Ouch.
This commit is contained in:
Behdad Esfahbod 2018-02-18 22:29:24 -08:00
parent eb6af2da72
commit 21cbab8ce9
4 changed files with 25 additions and 20 deletions

View File

@ -546,21 +546,26 @@ class VarIdxMap(BaseTable):
def populateDefaults(self, propagator=None): def populateDefaults(self, propagator=None):
if not hasattr(self, 'mapping'): if not hasattr(self, 'mapping'):
self.mapping = [] self.mapping = {}
def postRead(self, rawTable, font): def postRead(self, rawTable, font):
assert (rawTable['EntryFormat'] & 0xFFC0) == 0 assert (rawTable['EntryFormat'] & 0xFFC0) == 0
self.mapping = rawTable['mapping'] glyphOrder = font.getGlyphOrder()
mapList = rawTable['mapping']
mapList.extend([mapList[-1]] * (len(glyphOrder) - len(mapList)))
self.mapping = dict(zip(glyphOrder, mapList))
def preWrite(self, font): def preWrite(self, font):
mapping = getattr(self, "mapping", None) mapping = getattr(self, "mapping", None)
if mapping is None: if mapping is None:
mapping = self.mapping = [] mapping = self.mapping = {}
glyphOrder = font.getGlyphOrder()
mapping = [mapping[g] for g in glyphOrder]
rawTable = { 'mapping': mapping } rawTable = { 'mapping': mapping }
rawTable['MappingCount'] = len(mapping) rawTable['MappingCount'] = len(mapping)
# TODO Remove this abstraction/optimization and move it varLib.builder?
ored = 0 ored = 0
for idx in mapping: for idx in mapping:
ored |= idx ored |= idx
@ -589,9 +594,9 @@ class VarIdxMap(BaseTable):
return rawTable return rawTable
def toXML2(self, xmlWriter, font): def toXML2(self, xmlWriter, font):
for i, value in enumerate(getattr(self, "mapping", [])): for glyph, value in sorted(getattr(self, "mapping", {}).items()):
attrs = ( attrs = (
('index', i), ('glyph', glyph),
('outer', value >> 16), ('outer', value >> 16),
('inner', value & 0xFFFF), ('inner', value & 0xFFFF),
) )
@ -601,12 +606,13 @@ class VarIdxMap(BaseTable):
def fromXML(self, name, attrs, content, font): def fromXML(self, name, attrs, content, font):
mapping = getattr(self, "mapping", None) mapping = getattr(self, "mapping", None)
if mapping is None: if mapping is None:
mapping = [] mapping = {}
self.mapping = mapping self.mapping = mapping
glyph = attrs['glyph']
outer = safeEval(attrs['outer']) outer = safeEval(attrs['outer'])
inner = safeEval(attrs['inner']) inner = safeEval(attrs['inner'])
assert inner <= 0xFFFF assert inner <= 0xFFFF
mapping.append((outer << 16) | inner) mapping[glyph] = (outer << 16) | inner
class SingleSubst(FormatSwitchingBaseTable): class SingleSubst(FormatSwitchingBaseTable):

View File

@ -436,9 +436,7 @@ def _add_HVAR(font, model, master_ttfs, axisTags):
newItems = sorted(uniq) newItems = sorted(uniq)
mapper = {v:i for i,v in enumerate(newItems)} mapper = {v:i for i,v in enumerate(newItems)}
mapping = [mapper[item] for item in items] mapping = [mapper[item] for item in items]
while len(mapping) > 1 and mapping[-1] == mapping[-2]: advanceMapping = builder.buildVarIdxMap(mapping, font.getGlyphOrder())
del mapping[-1]
advanceMapping = builder.buildVarIdxMap(mapping)
items = newItems items = newItems
del mapper, mapping, newItems del mapper, mapping, newItems
del uniq del uniq

View File

@ -84,10 +84,9 @@ def buildVarStore(varRegionList, varDataList):
# Variation helpers # Variation helpers
def buildVarIdxMap(varIdxes): def buildVarIdxMap(varIdxes, glyphOrder):
# TODO Change VarIdxMap mapping to hold separate outer,inner indices
self = ot.VarIdxMap() self = ot.VarIdxMap()
self.mapping = list(varIdxes) self.mapping = {g:v for g,v in zip(glyphOrder, varIdxes)}
return self return self
def buildVarDevTable(varIdx): def buildVarDevTable(varIdx):

View File

@ -405,11 +405,13 @@
</VarData> </VarData>
</VarStore> </VarStore>
<AdvWidthMap> <AdvWidthMap>
<Map index="0" outer="0" inner="1"/> <Map glyph=".notdef" outer="0" inner="1"/>
<Map index="1" outer="0" inner="1"/> <Map glyph="NULL" outer="0" inner="1"/>
<Map index="2" outer="0" inner="1"/> <Map glyph="a" outer="0" inner="0"/>
<Map index="3" outer="0" inner="1"/> <Map glyph="b" outer="0" inner="0"/>
<Map index="4" outer="0" inner="0"/> <Map glyph="q" outer="0" inner="0"/>
<Map glyph="nonmarkingreturn" outer="0" inner="1"/>
<Map glyph="space" outer="0" inner="1"/>
</AdvWidthMap> </AdvWidthMap>
</HVAR> </HVAR>