Handle all Graphite tables now
This commit is contained in:
parent
bb162e00b9
commit
860a8e0522
92
Lib/fontTools/ttLib/tables/F__e_a_t.py
Normal file
92
Lib/fontTools/ttLib/tables/F__e_a_t.py
Normal file
@ -0,0 +1,92 @@
|
||||
from __future__ import print_function, division, absolute_import
|
||||
from fontTools.misc.py23 import *
|
||||
from fontTools.misc import sstruct
|
||||
from fontTools.misc.textTools import safeEval
|
||||
from .otBase import BaseTTXConverter
|
||||
from . import DefaultTable
|
||||
from . import grUtils
|
||||
import struct
|
||||
|
||||
Feat_hdr_format='''
|
||||
>
|
||||
version: 16.16F
|
||||
'''
|
||||
|
||||
class table_F__e_a_t(DefaultTable.DefaultTable):
|
||||
|
||||
def __init__(self, tag=None):
|
||||
DefaultTable.DefaultTable.__init__(self, tag)
|
||||
self.features = {}
|
||||
|
||||
def decompile(self, data, ttFont):
|
||||
(_, data) = sstruct.unpack2(Feat_hdr_format, data, self)
|
||||
numFeats, = struct.unpack('>H', data[:2])
|
||||
data = data[8:]
|
||||
allfeats = []
|
||||
maxsetting = 0
|
||||
for i in range(numFeats):
|
||||
(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)
|
||||
data = data[16*numFeats:]
|
||||
allsettings = []
|
||||
for i in range(maxsetting):
|
||||
if len(data) >= 4 * (i + 1):
|
||||
(val, lid) = struct.unpack(">HH", data[4*i:4*(i+1)])
|
||||
allsettings.append((val, lid))
|
||||
for f in allfeats:
|
||||
(fid, nums, offset, flags, lid) = f
|
||||
fobj = Feature()
|
||||
fobj.flags = flags
|
||||
fobj.label = lid
|
||||
self.features[grUtils.num2tag(fid)] = fobj
|
||||
fobj.settings = {}
|
||||
for i in range(offset, offset + nums):
|
||||
if i >= len(allsettings): continue
|
||||
(vid, vlid) = allsettings[i]
|
||||
fobj.settings[vid] = vlid
|
||||
|
||||
def compile(self, ttFont):
|
||||
fdat = ""
|
||||
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)
|
||||
for s, l in sorted(v.settings.items()):
|
||||
vdat += struct.pack(">HH", s, l)
|
||||
offset += len(v.settings)
|
||||
hdr = sstruct.pack(Feat_hdr_format, self)
|
||||
return hdr + struct.pack('>HHL', len(self.features), 0, 0) + fdat + vdat
|
||||
|
||||
def toXML(self, writer, ttFont):
|
||||
writer.simpletag('version', version=self.version)
|
||||
writer.newline()
|
||||
for f, v in sorted(self.features.items()):
|
||||
writer.begintag('feature', fid=f, label=v.label, flags=v.flags)
|
||||
writer.newline()
|
||||
for s, l in sorted(v.settings.items()):
|
||||
writer.simpletag('setting', value=s, label=l)
|
||||
writer.newline()
|
||||
writer.endtag('feature')
|
||||
writer.newline()
|
||||
|
||||
def fromXML(self, name, attrs, content, ttFont):
|
||||
if name == 'version':
|
||||
self.version = float(safeEval(attrs['version']))
|
||||
elif name == 'feature':
|
||||
fid = attrs['fid']
|
||||
fobj = Feature()
|
||||
fobj.flags = int(safeEval(attrs['flags']))
|
||||
fobj.label = int(safeEval(attrs['label']))
|
||||
self.features[fid] = fobj
|
||||
fobj.settings = {}
|
||||
for element in content:
|
||||
if not isinstance(element, tuple): continue
|
||||
tag, a, c = element
|
||||
if tag == 'setting':
|
||||
fobj.settings[int(safeEval(a['value']))] = int(safeEval(a['label']))
|
||||
|
||||
class Feature(object):
|
||||
pass
|
||||
|
@ -278,20 +278,6 @@ def content_string(contents):
|
||||
res += element
|
||||
return res.strip()
|
||||
|
||||
def bininfo(num, size=1):
|
||||
if num == 0:
|
||||
return struct.pack(">4H", 0, 0, 0, 0)
|
||||
srange = 1;
|
||||
select = 0
|
||||
while srange <= num:
|
||||
srange *= 2
|
||||
select += 1
|
||||
select -= 1
|
||||
srange /= 2
|
||||
srange *= size
|
||||
shift = num * size - srange
|
||||
return struct.pack(">4H", num, srange, select, shift)
|
||||
|
||||
class _Object() :
|
||||
pass
|
||||
|
||||
@ -423,7 +409,7 @@ class Silf(object):
|
||||
data += struct.pack(">H", self.lbGID)
|
||||
self.passOffset = len(data)
|
||||
|
||||
data1 = bininfo(numPseudo, 6)
|
||||
data1 = grUtils.bininfo(numPseudo, 6)
|
||||
currpos = hdroffset + len(data) + 4 * (self.numPasses + 1)
|
||||
self.pseudosOffset = currpos + len(data1)
|
||||
for u, p in sorted(self.pMap.items()):
|
||||
@ -582,7 +568,7 @@ class Classes(object):
|
||||
data += struct.pack((">%dH" % len(l)), *l)
|
||||
for l in self.nonLinear:
|
||||
oClasses.append(len(data) + offset)
|
||||
data += bininfo(len(l.lookups))
|
||||
data += grUtils.bininfo(len(l.lookups))
|
||||
data += "".join([struct.pack(">HH", *x) for x in l.lookups])
|
||||
oClasses.append(len(data) + offset)
|
||||
self.numClass = len(oClasses) - 1
|
||||
@ -731,7 +717,7 @@ class Pass(object):
|
||||
self.oDebug = 0
|
||||
# now generate output
|
||||
data = sstruct.pack(Silf_pass_format, self)
|
||||
data += bininfo(len(passRanges), 6)
|
||||
data += grUtils.bininfo(len(passRanges), 6)
|
||||
data += "".join(struct.pack(">3H", *p) for p in passRanges)
|
||||
data += struct.pack((">%dH" % len(oRuleMap)), *oRuleMap)
|
||||
flatrules = reduce(lambda a,x: a+x, self.rules, [])
|
||||
|
75
Lib/fontTools/ttLib/tables/S__i_l_l.py
Normal file
75
Lib/fontTools/ttLib/tables/S__i_l_l.py
Normal file
@ -0,0 +1,75 @@
|
||||
from __future__ import print_function, division, absolute_import
|
||||
from fontTools.misc.py23 import *
|
||||
from fontTools.misc import sstruct
|
||||
from fontTools.misc.textTools import safeEval
|
||||
from . import DefaultTable
|
||||
from . import grUtils
|
||||
import struct
|
||||
|
||||
Sill_hdr = '''
|
||||
>
|
||||
version: 16.16F
|
||||
'''
|
||||
|
||||
class table_S__i_l_l(DefaultTable.DefaultTable):
|
||||
|
||||
def __init__(self, tag=None):
|
||||
DefaultTable.DefaultTable.__init__(self, tag)
|
||||
self.langs = {}
|
||||
|
||||
def decompile(self, data, ttFont):
|
||||
(_, data) = sstruct.unpack2(Sill_hdr, data, self)
|
||||
numLangs, = struct.unpack('>H', data[:2])
|
||||
data = data[8:]
|
||||
maxsetting = 0
|
||||
langinfo = []
|
||||
for i in range(numLangs):
|
||||
(langcode, numSettings, offset) = struct.unpack(">4sHH", data[i * 8:(i+1) * 8])
|
||||
offset = int(offset / 8) - (numLangs + 1)
|
||||
langinfo.append((langcode, numsettings, offset))
|
||||
maxsetting = max(maxsetting, offset + numsettings)
|
||||
data[numLangs * 8:]
|
||||
finfo = []
|
||||
for i in range(maxsetting):
|
||||
(fid, val, _) = struct.unpack(">LHH", data[i * 8:(i+1) * 8])
|
||||
finfo.append((fid, val))
|
||||
self.langs = {}
|
||||
for c, n, o in langinfo:
|
||||
self.langs[c] = []
|
||||
for i in range(o, o+n):
|
||||
self.langs[c].append(finfo[i])
|
||||
|
||||
def compile(self, ttFont):
|
||||
ldat = ""
|
||||
fdat = ""
|
||||
offset = 0
|
||||
for c, inf in sorted(self.langs.items()):
|
||||
ldat += struct.pack(">4sHH", c, len(inf), 8 * (offset + len(self.langs) + 1))
|
||||
for fid, val in inf:
|
||||
fdat += struct.pack(">LHH", fid, val, 0)
|
||||
offset += len(inf)
|
||||
return sstruct.pack(Sill_hdr, self) + grUtils.bininfo(len(self.langs)) + ldat + fdat
|
||||
|
||||
def toXML(self, writer, ttFont):
|
||||
writer.simpletag('version', version=self.version)
|
||||
writer.newline()
|
||||
for c, inf in sorted(self.langs.items()):
|
||||
writer.begintag('lang', name=c)
|
||||
writer.newline()
|
||||
for fid, val in inf:
|
||||
writer.simpletag('feature', fid=grUtils.num2tag(fid), val=val)
|
||||
writer.newline()
|
||||
writer.endtag('lang')
|
||||
writer.newline()
|
||||
|
||||
def fromXML(self, name, attrs, content, ttFont):
|
||||
if name == 'version':
|
||||
self.version = float(safeEval(attrs['version']))
|
||||
elif name == 'lang':
|
||||
c = attrs['name']
|
||||
self.langs[c] = []
|
||||
for element in content:
|
||||
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']))))
|
@ -50,3 +50,29 @@ def entries(attributes, sameval = False):
|
||||
g = _entries(sorted(attributes.iteritems(), key=lambda x:int(x[0])), sameval)
|
||||
return g
|
||||
|
||||
def bininfo(num, size=1):
|
||||
if num == 0:
|
||||
return struct.pack(">4H", 0, 0, 0, 0)
|
||||
srange = 1;
|
||||
select = 0
|
||||
while srange <= num:
|
||||
srange *= 2
|
||||
select += 1
|
||||
select -= 1
|
||||
srange /= 2
|
||||
srange *= size
|
||||
shift = num * size - srange
|
||||
return struct.pack(">4H", num, srange, select, shift)
|
||||
|
||||
def num2tag(n):
|
||||
if n < 0x200000:
|
||||
return str(n)
|
||||
else:
|
||||
return struct.unpack('4s', struct.pack('>L', n))[0]
|
||||
|
||||
def tag2num(n):
|
||||
try:
|
||||
return int(n)
|
||||
except ValueError:
|
||||
return struct.unpack('>L', n)[0]
|
||||
|
||||
|
@ -1325,6 +1325,16 @@ otData = [
|
||||
]),
|
||||
|
||||
|
||||
#
|
||||
# Feat
|
||||
#
|
||||
|
||||
('Feat', [
|
||||
('Version', 'Version', None, None, 'Version of the feat table-initially set to 0x00010000.'),
|
||||
('FeatureNames', 'FeatureNames', None, None, 'The feature names.'),
|
||||
]),
|
||||
|
||||
|
||||
#
|
||||
# lcar
|
||||
#
|
||||
|
Loading…
x
Reference in New Issue
Block a user