Fix Silf v2 support

This commit is contained in:
Martin Hosken 2017-09-14 15:17:02 +07:00 committed by Sascha Brawer
parent a997fae488
commit e29a41bbe3
4 changed files with 50 additions and 21 deletions

View File

@ -25,7 +25,8 @@ class table_F__e_a_t(DefaultTable.DefaultTable):
allfeats = []
maxsetting = 0
for i in range(numFeats):
(fid, nums, _, offset, flags, lid) = struct.unpack(">LHHLHH", data[16*i:16*(i+1)])
(fid, nums, _, offset, flags, lid) = struct.unpack(">LHHLHH",
data[16*i:16*(i+1)])
offset = int((offset - 12 - 16 * numFeats) / 4)
allfeats.append((fid, nums, offset, flags, lid))
maxsetting = max(maxsetting, offset + nums)
@ -52,7 +53,8 @@ class table_F__e_a_t(DefaultTable.DefaultTable):
vdat = ""
offset = 0
for f, v in sorted(self.features.items()):
fdat += struct.pack(">LHHLHH", grUtils.tag2num(f), len(v.settings), 0, offset * 4 + 12 + 16 * len(self.features), v.flags, v.label)
fdat += struct.pack(">LHHLHH", grUtils.tag2num(f), len(v.settings),
0, offset * 4 + 12 + 16 * len(self.features), v.flags, v.label)
for s, l in sorted(v.settings.items()):
vdat += struct.pack(">HH", s, l)
offset += len(v.settings)

View File

@ -12,6 +12,11 @@ import struct, operator, warnings, re
Silf_hdr_format = '''
>
version: 16.16F
'''
Silf_hdr_format_3 = '''
>
version: 16.16F
compilerVersion: L
numSilf: H
x
@ -304,12 +309,19 @@ class table_S__i_l_f(DefaultTable.DefaultTable):
sstruct.unpack2(Silf_hdr_format, data, self)
if self.version >= 5.0:
(data, self.scheme) = grUtils.decompress(data)
sstruct.unpack2(Silf_hdr_format, data, self)
sstruct.unpack2(Silf_hdr_format_3, data, self)
base = sstruct.calcsize(Silf_hdr_format_3)
elif self.version < 3.0:
self.numSilf = struct.unpack('>H', data[4:6])
self.scheme = 0
self.compilerVersion = 0
base = 8
else:
self.scheme = 0
sstruct.unpack2(Silf_hdr_format_3, data, self)
base = sstruct.calcsize(Silf_hdr_format_3)
silfoffsets = struct.unpack_from(('>%dL' % self.numSilf),
data[sstruct.calcsize(Silf_hdr_format):])
silfoffsets = struct.unpack_from(('>%dL' % self.numSilf), data[base:])
for offset in silfoffsets:
s = Silf()
self.silfs.append(s)
@ -317,7 +329,11 @@ class table_S__i_l_f(DefaultTable.DefaultTable):
def compile(self, ttFont):
self.numSilf = len(self.silfs)
hdr = sstruct.pack(Silf_hdr_format, self)
if self.version < 3.0:
hdr = sstruct.pack(Silf_hdr_format, self)
hdr += struct.pack(">HH", self.numSilf, 0)
else:
hdr = sstruct.pack(Silf_hdr_format_3, self)
offset = len(hdr) + 4 * self.numSilf
data = ""
for s in self.silfs:
@ -330,6 +346,8 @@ class table_S__i_l_f(DefaultTable.DefaultTable):
return hdr+data
def toXML(self, writer, ttFont):
writer.comment('Attributes starting with _ are informative only')
writer.newline()
writer.simpletag('version', version=self.version,
compilerVersion=self.compilerVersion, compressionScheme=self.scheme)
writer.newline()
@ -385,7 +403,10 @@ class Silf(object):
data = data[6 + 4 * self.numPasses:]
(numPseudo,) = struct.unpack(">H", data[:2])
for i in range(numPseudo):
pseudo = sstruct.unpack(Silf_pseudomap_format, data[8+6*i:14+6*i], _Object())
if version >= 3.0:
pseudo = sstruct.unpack(Silf_pseudomap_format, data[8+6*i:14+6*i], _Object())
else:
pseudo = struct.unpack('>HH', data[8+4*i:12+4*i], _Object())
self.pMap[pseudo.unicode] = ttFont.getGlyphName(pseudo.nPseudo)
data = data[8 + 6 * numPseudo:]
currpos = (sstruct.calcsize(Silf_part1_format)
@ -429,7 +450,8 @@ class Silf(object):
currpos = hdroffset + len(data) + 4 * (self.numPasses + 1)
self.pseudosOffset = currpos + len(data1)
for u, p in sorted(self.pMap.items()):
data1 += struct.pack(">LH", u, ttFont.getGlyphID(p))
data1 += struct.pack((">LH" if version >= 3.0 else ">HH"),
u, ttFont.getGlyphID(p))
data1 += self.classes.compile(ttFont, version)
currpos += len(data1)
data2 = ""
@ -492,7 +514,7 @@ class Silf(object):
writer.begintag('passes')
writer.newline()
for i, p in enumerate(self.passes):
writer.begintag('pass', index=i)
writer.begintag('pass', _index=i)
writer.newline()
p.toXML(writer, ttFont, version)
writer.endtag('pass')
@ -582,7 +604,10 @@ class Classes(object):
def compile(self, ttFont, version=2.0):
data = ""
oClasses = []
offset = 8 + 4 * (len(self.linear) + len(self.nonLinear))
if version >= 4.0:
offset = 8 + 4 * (len(self.linear) + len(self.nonLinear))
else:
offset = 6 + 2 * (len(self.linear) + len(self.nonLinear))
for l in self.linear:
oClasses.append(len(data) + offset)
gs = map(ttFont.getGlyphID, l)
@ -596,8 +621,8 @@ class Classes(object):
self.numClass = len(oClasses) - 1
self.numLinear = len(self.linear)
return sstruct.pack(Silf_classmap_format, self) + \
struct.pack((">%dL" % len(oClasses)), *oClasses) + \
data
struct.pack(((">%dL" if version >= 4.0 else ">%dH") % len(oClasses)),
*oClasses) + data
def toXML(self, writer, ttFont, version=2.0):
writer.begintag('classes')
@ -605,7 +630,7 @@ class Classes(object):
writer.begintag('linearClasses')
writer.newline()
for i,l in enumerate(self.linear):
writer.begintag('linear', index=i)
writer.begintag('linear', _index=i)
writer.newline()
wrapline(writer, l)
writer.endtag('linear')
@ -615,7 +640,7 @@ class Classes(object):
writer.begintag('nonLinearClasses')
writer.newline()
for i, l in enumerate(self.nonLinear):
writer.begintag('nonLinear', index=i + self.numLinear)
writer.begintag('nonLinear', _index=i + self.numLinear)
writer.newline()
for inp, ind in l.items():
writer.simpletag('map', glyph=inp, index=ind)
@ -794,7 +819,7 @@ class Pass(object):
writer.endtag('starts')
writer.newline()
for i, s in enumerate(self.stateTrans):
writer.begintag('row', i=i)
writer.begintag('row', _i=i)
# no newlines here
writer.write(" ".join(map(str, s)))
writer.endtag('row')

View File

@ -24,12 +24,13 @@ class table_S__i_l_l(DefaultTable.DefaultTable):
maxsetting = 0
langinfo = []
for i in range(numLangs):
(langcode, numSettings, offset) = struct.unpack(">4sHH",
(langcode, numsettings, offset) = struct.unpack(">4sHH",
data[i * 8:(i+1) * 8])
offset = int(offset / 8) - (numLangs + 1)
langcode = langcode.replace('\000', '')
langinfo.append((langcode, numsettings, offset))
maxsetting = max(maxsetting, offset + numsettings)
data[numLangs * 8:]
data = data[numLangs * 8:]
finfo = []
for i in range(maxsetting):
(fid, val, _) = struct.unpack(">LHH", data[i * 8:(i+1) * 8])
@ -45,7 +46,7 @@ class table_S__i_l_l(DefaultTable.DefaultTable):
fdat = ""
offset = 0
for c, inf in sorted(self.langs.items()):
ldat += struct.pack(">4sHH", c, len(inf), 8 * (offset + len(self.langs) + 1))
ldat += struct.pack(">4sHH", c.encode('utf8'), len(inf), 8 * (offset + len(self.langs) + 1))
for fid, val in inf:
fdat += struct.pack(">LHH", fid, val, 0)
offset += len(inf)
@ -74,5 +75,5 @@ class table_S__i_l_l(DefaultTable.DefaultTable):
if not isinstance(element, tuple): continue
tag, a, subcontent = element
if tag == 'feature':
self.langs[c].append((grUtils.tag2num(attrs['fid']),
int(safeEval(attrs['val']))))
self.langs[c].append((grUtils.tag2num(a['fid']),
int(safeEval(a['val']))))

View File

@ -68,11 +68,12 @@ def num2tag(n):
if n < 0x200000:
return str(n)
else:
return struct.unpack('4s', struct.pack('>L', n))[0]
return struct.unpack('4s', struct.pack('>L', n))[0].replace('\000', '')
def tag2num(n):
try:
return int(n)
except ValueError:
n = (n+" ")[:4]
return struct.unpack('>L', n)[0]