Merge pull request #1093 from silnrsi/graphite

Fix small graphite round trip bugs
This commit is contained in:
Cosimo Lupo 2017-11-07 09:53:36 +00:00 committed by GitHub
commit f100754ffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 16 deletions

View File

@ -41,23 +41,27 @@ class table_F__e_a_t(DefaultTable.DefaultTable):
if len(data) >= 4 * (i + 1): if len(data) >= 4 * (i + 1):
(val, lid) = struct.unpack(">HH", data[4*i:4*(i+1)]) (val, lid) = struct.unpack(">HH", data[4*i:4*(i+1)])
allsettings.append((val, lid)) allsettings.append((val, lid))
for f in allfeats: for i,f in enumerate(allfeats):
(fid, nums, offset, flags, lid) = f (fid, nums, offset, flags, lid) = f
fobj = Feature() fobj = Feature()
fobj.flags = flags fobj.flags = flags
fobj.label = lid fobj.label = lid
self.features[grUtils.num2tag(fid)] = fobj self.features[grUtils.num2tag(fid)] = fobj
fobj.settings = {} fobj.settings = {}
fobj.default = None
fobj.index = i
for i in range(offset, offset + nums): for i in range(offset, offset + nums):
if i >= len(allsettings): continue if i >= len(allsettings): continue
(vid, vlid) = allsettings[i] (vid, vlid) = allsettings[i]
fobj.settings[vid] = vlid fobj.settings[vid] = vlid
if fobj.default is None:
fobj.default = vid
def compile(self, ttFont): def compile(self, ttFont):
fdat = "" fdat = ""
vdat = "" vdat = ""
offset = 0 offset = 0
for f, v in sorted(self.features.items()): for f, v in sorted(self.features.items(), key=lambda x:x[1].index):
fnum = grUtils.tag2num(f) fnum = grUtils.tag2num(f)
if self.version >= 2.0: if self.version >= 2.0:
fdat += struct.pack(">LHHLHH", grUtils.tag2num(f), len(v.settings), fdat += struct.pack(">LHHLHH", grUtils.tag2num(f), len(v.settings),
@ -68,7 +72,7 @@ class table_F__e_a_t(DefaultTable.DefaultTable):
else: else:
fdat += struct.pack(">HHLHH", grUtils.tag2num(f), len(v.settings), fdat += struct.pack(">HHLHH", grUtils.tag2num(f), len(v.settings),
offset * 4 + 12 + 12 * len(self.features), v.flags, v.label) offset * 4 + 12 + 12 * len(self.features), v.flags, v.label)
for s, l in sorted(v.settings.items()): for s, l in sorted(v.settings.items(), key=lambda x:(-1, x[1]) if x[0] == v.default else x):
vdat += struct.pack(">HH", s, l) vdat += struct.pack(">HH", s, l)
offset += len(v.settings) offset += len(v.settings)
hdr = sstruct.pack(Feat_hdr_format, self) hdr = sstruct.pack(Feat_hdr_format, self)
@ -77,8 +81,9 @@ class table_F__e_a_t(DefaultTable.DefaultTable):
def toXML(self, writer, ttFont): def toXML(self, writer, ttFont):
writer.simpletag('version', version=self.version) writer.simpletag('version', version=self.version)
writer.newline() writer.newline()
for f, v in sorted(self.features.items()): for f, v in sorted(self.features.items(), key=lambda x:x[1].index):
writer.begintag('feature', fid=f, label=v.label, flags=v.flags) writer.begintag('feature', fid=f, label=v.label, flags=v.flags,
default=(v.default if v.default else 0))
writer.newline() writer.newline()
for s, l in sorted(v.settings.items()): for s, l in sorted(v.settings.items()):
writer.simpletag('setting', value=s, label=l) writer.simpletag('setting', value=s, label=l)
@ -94,6 +99,8 @@ class table_F__e_a_t(DefaultTable.DefaultTable):
fobj = Feature() fobj = Feature()
fobj.flags = int(safeEval(attrs['flags'])) fobj.flags = int(safeEval(attrs['flags']))
fobj.label = int(safeEval(attrs['label'])) fobj.label = int(safeEval(attrs['label']))
fobj.default = int(safeEval(attrs.get('default','0')))
fobj.index = len(self.features)
self.features[fid] = fobj self.features[fid] = fobj
fobj.settings = {} fobj.settings = {}
for element in content: for element in content:

View File

@ -195,7 +195,7 @@ def disassemble(aCode):
pc = 0 pc = 0
res = [] res = []
while pc < codelen: while pc < codelen:
opcode = ord(aCode[pc:pc+1]) opcode = byteord(aCode[pc:pc+1])
if opcode > len(aCode_info): if opcode > len(aCode_info):
instr = aCode_info[0] instr = aCode_info[0]
else: else:
@ -203,7 +203,7 @@ def disassemble(aCode):
pc += 1 pc += 1
if instr[1] != 0 and pc >= codelen : return res if instr[1] != 0 and pc >= codelen : return res
if instr[1] == -1: if instr[1] == -1:
count = ord(aCode[pc]) count = byteord(aCode[pc])
fmt = "%dB" % count fmt = "%dB" % count
pc += 1 pc += 1
elif instr[1] == 0: elif instr[1] == 0:
@ -230,7 +230,7 @@ def assemble(instrs):
if m.group(2): if m.group(2):
if parmfmt == 0: if parmfmt == 0:
continue continue
parms = map(int, re.split(",\s*", m.group(2))) parms = [int(x) for x in re.split(",\s*", m.group(2))]
if parmfmt == -1: if parmfmt == -1:
l = len(parms) l = len(parms)
res.append(struct.pack(("%dB" % (l+1)), l, *parms)) res.append(struct.pack(("%dB" % (l+1)), l, *parms))
@ -727,9 +727,6 @@ class Pass(object):
oConstraints[i] = oConstraints[i+1] oConstraints[i] = oConstraints[i+1]
self.ruleConstraints = [(data[s:e] if (e-s > 1) else "") for (s,e) in zip(oConstraints, oConstraints[1:])] self.ruleConstraints = [(data[s:e] if (e-s > 1) else "") for (s,e) in zip(oConstraints, oConstraints[1:])]
data = data[oConstraints[-1]:] data = data[oConstraints[-1]:]
for i in range(len(oActions)-2,-1,-1):
if oActions[i] == 0:
oActions[i] = oActions[i+1]
self.actions = [(data[s:e] if (e-s > 1) else "") for (s,e) in zip(oActions, oActions[1:])] self.actions = [(data[s:e] if (e-s > 1) else "") for (s,e) in zip(oActions, oActions[1:])]
data = data[oActions[-1]:] data = data[oActions[-1]:]
# not using debug # not using debug
@ -737,8 +734,8 @@ class Pass(object):
def compile(self, ttFont, base, version=2.0): def compile(self, ttFont, base, version=2.0):
# build it all up backwards # build it all up backwards
oActions = reduce(lambda a, x: (a[0]+len(x), a[1]+[a[0]]), self.actions + [""], (0, []))[1] oActions = reduce(lambda a, x: (a[0]+len(x), a[1]+[a[0]]), self.actions + [""], (0, []))[1]
oConstraints = reduce(lambda a, x: (a[0]+len(x), a[1]+[a[0]]), self.ruleConstraints + [""], (0, []))[1] oConstraints = reduce(lambda a, x: (a[0]+len(x), a[1]+[a[0]]), self.ruleConstraints + [""], (1, []))[1]
constraintCode = "".join(self.ruleConstraints) constraintCode = "\000" + "".join(self.ruleConstraints)
transes = [] transes = []
for t in self.stateTrans: for t in self.stateTrans:
t.byteswap() t.byteswap()

View File

@ -3,13 +3,13 @@
<Feat> <Feat>
<version version="2.0"/> <version version="2.0"/>
<feature fid="1" flags="32768" label="258"> <feature default="0" fid="1" flags="32768" label="258">
</feature> </feature>
<feature fid="nom " flags="32768" label="262"> <feature default="0" fid="nom " flags="32768" label="262">
<setting label="261" value="0"/> <setting label="261" value="0"/>
<setting label="260" value="1"/> <setting label="260" value="1"/>
</feature> </feature>
<feature fid="yesm" flags="32768" label="259"> <feature default="0" fid="yesm" flags="32768" label="259">
<setting label="261" value="0"/> <setting label="261" value="0"/>
<setting label="260" value="1"/> <setting label="260" value="1"/>
</feature> </feature>

View File

@ -32,6 +32,12 @@
<rules> <rules>
<rule index="0" precontext="0" sortkey="2"> <rule index="0" precontext="0" sortkey="2">
<action> <action>
PUT_GLYPH_8BIT_OBS(0)
ASSOC(0, 1)
NEXT
DELETE
NEXT
RET_ZERO
</action> </action>
</rule> </rule>
<rule index="1" precontext="1" sortkey="2"> <rule index="1" precontext="1" sortkey="2">
@ -63,6 +69,22 @@
<rules> <rules>
<rule index="0" precontext="0" sortkey="2"> <rule index="0" precontext="0" sortkey="2">
<action> <action>
COPY_NEXT
PUT_COPY(0)
PUSH_BYTE(-1)
ATTR_SET_SLOT(2)
PUSH_BYTE(0)
ATTR_SET(17)
PUSH_GLYPH_ATTR_OBS(6, 0)
ATTR_SET(8)
PUSH_GLYPH_ATTR_OBS(7, 0)
ATTR_SET(9)
PUSH_ATT_TO_GATTR_OBS(6, 0)
ATTR_SET(3)
PUSH_ATT_TO_GATTR_OBS(7, 0)
ATTR_SET(4)
NEXT
RET_ZERO
</action> </action>
</rule> </rule>
</rules> </rules>