diff options
author | Elliott Hughes <enh@google.com> | 2023-11-10 19:23:18 +0000 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2023-11-10 19:23:18 +0000 |
commit | 02cec46c7a3918f19153e4e2de707f9d7de83fc8 (patch) | |
tree | c927c514a071f3a5ec125b3f474ad4ce4d39a7fa /Lib/fontTools/ttLib/tables/S__i_l_f.py | |
parent | a936b27b9394502de80c116f46aff5b1a1cc3925 (diff) | |
download | fonttools-02cec46c7a3918f19153e4e2de707f9d7de83fc8.tar.gz |
Upgrade fonttools to 4.44.0
This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update fonttools
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
Test: TreeHugger
Change-Id: I5de68c96999d1b8671c251a2555948da63de5bc6
Diffstat (limited to 'Lib/fontTools/ttLib/tables/S__i_l_f.py')
-rw-r--r-- | Lib/fontTools/ttLib/tables/S__i_l_f.py | 672 |
1 files changed, 412 insertions, 260 deletions
diff --git a/Lib/fontTools/ttLib/tables/S__i_l_f.py b/Lib/fontTools/ttLib/tables/S__i_l_f.py index f326c386..324ffd01 100644 --- a/Lib/fontTools/ttLib/tables/S__i_l_f.py +++ b/Lib/fontTools/ttLib/tables/S__i_l_f.py @@ -1,6 +1,7 @@ from fontTools.misc import sstruct from fontTools.misc.fixedTools import floatToFixedToStr from fontTools.misc.textTools import byteord, safeEval + # from itertools import * from . import DefaultTable from . import grUtils @@ -8,28 +9,28 @@ from array import array from functools import reduce import struct, re, sys -Silf_hdr_format = ''' +Silf_hdr_format = """ > version: 16.16F -''' +""" -Silf_hdr_format_3 = ''' +Silf_hdr_format_3 = """ > version: 16.16F compilerVersion: L numSilf: H x x -''' +""" -Silf_part1_format_v3 = ''' +Silf_part1_format_v3 = """ > ruleVersion: 16.16F passOffset: H pseudosOffset: H -''' +""" -Silf_part1_format = ''' +Silf_part1_format = """ > maxGlyphID: H extraAscent: h @@ -48,9 +49,9 @@ Silf_part1_format = ''' attrMirroring: B attrSkipPasses: B numJLevels: B -''' +""" -Silf_justify_format = ''' +Silf_justify_format = """ > attrStretch: B attrShrink: B @@ -60,9 +61,9 @@ Silf_justify_format = ''' x x x -''' +""" -Silf_part2_format = ''' +Silf_part2_format = """ > numLigComp: H numUserDefn: B @@ -73,41 +74,41 @@ Silf_part2_format = ''' x x numCritFeatures: B -''' +""" -Silf_pseudomap_format = ''' +Silf_pseudomap_format = """ > unicode: L nPseudo: H -''' +""" -Silf_pseudomap_format_h = ''' +Silf_pseudomap_format_h = """ > unicode: H nPseudo: H -''' +""" -Silf_classmap_format = ''' +Silf_classmap_format = """ > numClass: H numLinear: H -''' +""" -Silf_lookupclass_format = ''' +Silf_lookupclass_format = """ > numIDs: H searchRange: H entrySelector: H rangeShift: H -''' +""" -Silf_lookuppair_format = ''' +Silf_lookuppair_format = """ > glyphId: H index: H -''' +""" -Silf_pass_format = ''' +Silf_pass_format = """ > flags: B maxRuleLoop: B @@ -123,7 +124,7 @@ Silf_pass_format = ''' numTransitional: H numSuccess: H numColumns: H -''' +""" aCode_info = ( ("NOP", 0), @@ -142,7 +143,7 @@ aCode_info = ( ("TRUNC8", 0), ("TRUNC16", 0), ("COND", 0), - ("AND", 0), # x10 + ("AND", 0), # x10 ("OR", 0), ("NOT", 0), ("EQUAL", 0), @@ -158,7 +159,7 @@ aCode_info = ( ("PUT_SUBS_8BIT_OBS", "bBB"), ("PUT_COPY", "b"), ("INSERT", 0), - ("DELETE", 0), # x20 + ("DELETE", 0), # x20 ("ASSOC", -1), ("CNTXT_ITEM", "bB"), ("ATTR_SET", "B"), @@ -174,7 +175,7 @@ aCode_info = ( ("PUSH_ATT_TO_GLYPH_METRIC", "Bbb"), ("PUSH_ISLOT_ATTR", "Bbb"), ("PUSH_IGLYPH_ATTR", "Bbb"), - ("POP_RET", 0), # x30 + ("POP_RET", 0), # x30 ("RET_ZERO", 0), ("RET_TRUE", 0), ("IATTR_SET", "BB"), @@ -190,31 +191,33 @@ aCode_info = ( ("PUSH_ATT_TO_GLYPH_ATTR", ">Hb"), ("BITOR", 0), ("BITAND", 0), - ("BITNOT", 0), # x40 + ("BITNOT", 0), # x40 ("BITSET", ">HH"), - ("SET_FEAT", "Bb") + ("SET_FEAT", "Bb"), ) -aCode_map = dict([(x[0], (i, x[1])) for i,x in enumerate(aCode_info)]) +aCode_map = dict([(x[0], (i, x[1])) for i, x in enumerate(aCode_info)]) + def disassemble(aCode): codelen = len(aCode) pc = 0 res = [] while pc < codelen: - opcode = byteord(aCode[pc:pc+1]) + opcode = byteord(aCode[pc : pc + 1]) if opcode > len(aCode_info): instr = aCode_info[0] else: instr = aCode_info[opcode] pc += 1 - if instr[1] != 0 and pc >= codelen : return res + if instr[1] != 0 and pc >= codelen: + return res if instr[1] == -1: count = byteord(aCode[pc]) fmt = "%dB" % count pc += 1 elif instr[1] == 0: fmt = "" - else : + else: fmt = instr[1] if fmt == "": res.append(instr[0]) @@ -224,7 +227,10 @@ def disassemble(aCode): pc += struct.calcsize(fmt) return res + instre = re.compile(r"^\s*([^(]+)\s*(?:\(([^)]+)\))?") + + def assemble(instrs): res = b"" for inst in instrs: @@ -239,11 +245,12 @@ def assemble(instrs): parms = [int(x) for x in re.split(r",\s*", m.group(2))] if parmfmt == -1: l = len(parms) - res += struct.pack(("%dB" % (l+1)), l, *parms) + res += struct.pack(("%dB" % (l + 1)), l, *parms) else: res += struct.pack(parmfmt, *parms) return res + def writecode(tag, writer, instrs): writer.begintag(tag) writer.newline() @@ -253,41 +260,71 @@ def writecode(tag, writer, instrs): writer.endtag(tag) writer.newline() + def readcode(content): res = [] - for e in content_string(content).split('\n'): + for e in content_string(content).split("\n"): e = e.strip() - if not len(e): continue + if not len(e): + continue res.append(e) return assemble(res) - -attrs_info=('flags', 'extraAscent', 'extraDescent', 'maxGlyphID', - 'numLigComp', 'numUserDefn', 'maxCompPerLig', 'direction', 'lbGID') -attrs_passindexes = ('iSubst', 'iPos', 'iJust', 'iBidi') -attrs_contexts = ('maxPreContext', 'maxPostContext') -attrs_attributes = ('attrPseudo', 'attrBreakWeight', 'attrDirectionality', - 'attrMirroring', 'attrSkipPasses', 'attCollisions') -pass_attrs_info = ('flags', 'maxRuleLoop', 'maxRuleContext', 'maxBackup', - 'minRulePreContext', 'maxRulePreContext', 'collisionThreshold') -pass_attrs_fsm = ('numRows', 'numTransitional', 'numSuccess', 'numColumns') + + +attrs_info = ( + "flags", + "extraAscent", + "extraDescent", + "maxGlyphID", + "numLigComp", + "numUserDefn", + "maxCompPerLig", + "direction", + "lbGID", +) +attrs_passindexes = ("iSubst", "iPos", "iJust", "iBidi") +attrs_contexts = ("maxPreContext", "maxPostContext") +attrs_attributes = ( + "attrPseudo", + "attrBreakWeight", + "attrDirectionality", + "attrMirroring", + "attrSkipPasses", + "attCollisions", +) +pass_attrs_info = ( + "flags", + "maxRuleLoop", + "maxRuleContext", + "maxBackup", + "minRulePreContext", + "maxRulePreContext", + "collisionThreshold", +) +pass_attrs_fsm = ("numRows", "numTransitional", "numSuccess", "numColumns") + def writesimple(tag, self, writer, *attrkeys): attrs = dict([(k, getattr(self, k)) for k in attrkeys]) writer.simpletag(tag, **attrs) writer.newline() + def getSimple(self, attrs, *attr_list): for k in attr_list: if k in attrs: setattr(self, k, int(safeEval(attrs[k]))) + def content_string(contents): res = "" for element in contents: - if isinstance(element, tuple): continue + if isinstance(element, tuple): + continue res += element return res.strip() + def wrapline(writer, dat, length=80): currline = "" for d in dat: @@ -300,11 +337,13 @@ def wrapline(writer, dat, length=80): writer.write(currline[:-1]) writer.newline() -class _Object() : + +class _Object: pass + class table_S__i_l_f(DefaultTable.DefaultTable): - '''Silf table support''' + """Silf table support""" def __init__(self, tag=None): DefaultTable.DefaultTable.__init__(self, tag) @@ -318,7 +357,7 @@ class table_S__i_l_f(DefaultTable.DefaultTable): 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.numSilf = struct.unpack(">H", data[4:6]) self.scheme = 0 self.compilerVersion = 0 base = 8 @@ -327,7 +366,7 @@ class table_S__i_l_f(DefaultTable.DefaultTable): sstruct.unpack2(Silf_hdr_format_3, data, self) base = sstruct.calcsize(Silf_hdr_format_3) - silfoffsets = struct.unpack_from(('>%dL' % self.numSilf), data[base:]) + silfoffsets = struct.unpack_from((">%dL" % self.numSilf), data[base:]) for offset in silfoffsets: s = Silf() self.silfs.append(s) @@ -348,38 +387,44 @@ class table_S__i_l_f(DefaultTable.DefaultTable): offset += len(subdata) data += subdata if self.version >= 5.0: - return grUtils.compress(self.scheme, hdr+data) - return hdr+data + return grUtils.compress(self.scheme, hdr + data) + return hdr + data def toXML(self, writer, ttFont): - writer.comment('Attributes starting with _ are informative only') + writer.comment("Attributes starting with _ are informative only") writer.newline() - writer.simpletag('version', version=self.version, - compilerVersion=self.compilerVersion, compressionScheme=self.scheme) + writer.simpletag( + "version", + version=self.version, + compilerVersion=self.compilerVersion, + compressionScheme=self.scheme, + ) writer.newline() for s in self.silfs: - writer.begintag('silf') + writer.begintag("silf") writer.newline() s.toXML(writer, ttFont, self.version) - writer.endtag('silf') + writer.endtag("silf") writer.newline() def fromXML(self, name, attrs, content, ttFont): - if name == 'version': - self.scheme=int(safeEval(attrs['compressionScheme'])) - self.version = float(safeEval(attrs['version'])) - self.compilerVersion = int(safeEval(attrs['compilerVersion'])) + if name == "version": + self.scheme = int(safeEval(attrs["compressionScheme"])) + self.version = float(safeEval(attrs["version"])) + self.compilerVersion = int(safeEval(attrs["compilerVersion"])) return - if name == 'silf': + if name == "silf": s = Silf() self.silfs.append(s) for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue tag, attrs, subcontent = element s.fromXML(tag, attrs, subcontent, ttFont, self.version) + class Silf(object): - '''A particular Silf subtable''' + """A particular Silf subtable""" def __init__(self): self.passes = [] @@ -389,37 +434,59 @@ class Silf(object): self.pMap = {} def decompile(self, data, ttFont, version=2.0): - if version >= 3.0 : + if version >= 3.0: _, data = sstruct.unpack2(Silf_part1_format_v3, data, self) - self.ruleVersion = float(floatToFixedToStr(self.ruleVersion, precisionBits=16)) + self.ruleVersion = float( + floatToFixedToStr(self.ruleVersion, precisionBits=16) + ) _, data = sstruct.unpack2(Silf_part1_format, data, self) for jlevel in range(self.numJLevels): j, data = sstruct.unpack2(Silf_justify_format, data, _Object()) self.jLevels.append(j) _, data = sstruct.unpack2(Silf_part2_format, data, self) if self.numCritFeatures: - self.critFeatures = struct.unpack_from(('>%dH' % self.numCritFeatures), data) - data = data[self.numCritFeatures * 2 + 1:] - (numScriptTag,) = struct.unpack_from('B', data) + self.critFeatures = struct.unpack_from( + (">%dH" % self.numCritFeatures), data + ) + data = data[self.numCritFeatures * 2 + 1 :] + (numScriptTag,) = struct.unpack_from("B", data) if numScriptTag: - self.scriptTags = [struct.unpack("4s", data[x:x+4])[0].decode("ascii") for x in range(1, 1 + 4 * numScriptTag, 4)] - data = data[1 + 4 * numScriptTag:] - (self.lbGID,) = struct.unpack('>H', data[:2]) + self.scriptTags = [ + struct.unpack("4s", data[x : x + 4])[0].decode("ascii") + for x in range(1, 1 + 4 * numScriptTag, 4) + ] + data = data[1 + 4 * numScriptTag :] + (self.lbGID,) = struct.unpack(">H", data[:2]) if self.numPasses: - self.oPasses = struct.unpack(('>%dL' % (self.numPasses+1)), data[2:6+4*self.numPasses]) - data = data[6 + 4 * self.numPasses:] + self.oPasses = struct.unpack( + (">%dL" % (self.numPasses + 1)), data[2 : 6 + 4 * self.numPasses] + ) + data = data[6 + 4 * self.numPasses :] (numPseudo,) = struct.unpack(">H", data[:2]) for i in range(numPseudo): if version >= 3.0: - pseudo = sstruct.unpack(Silf_pseudomap_format, data[8+6*i:14+6*i], _Object()) + pseudo = sstruct.unpack( + Silf_pseudomap_format, data[8 + 6 * i : 14 + 6 * i], _Object() + ) else: - pseudo = sstruct.unpack(Silf_pseudomap_format_h, data[8+4*i:12+4*i], _Object()) + pseudo = sstruct.unpack( + Silf_pseudomap_format_h, 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) - + sstruct.calcsize(Silf_justify_format) * self.numJLevels - + sstruct.calcsize(Silf_part2_format) + 2 * self.numCritFeatures - + 1 + 1 + 4 * numScriptTag + 6 + 4 * self.numPasses + 8 + 6 * numPseudo) + data = data[8 + 6 * numPseudo :] + currpos = ( + sstruct.calcsize(Silf_part1_format) + + sstruct.calcsize(Silf_justify_format) * self.numJLevels + + sstruct.calcsize(Silf_part2_format) + + 2 * self.numCritFeatures + + 1 + + 1 + + 4 * numScriptTag + + 6 + + 4 * self.numPasses + + 8 + + 6 * numPseudo + ) if version >= 3.0: currpos += sstruct.calcsize(Silf_part1_format_v3) self.classes = Classes() @@ -427,8 +494,11 @@ class Silf(object): for i in range(self.numPasses): p = Pass() self.passes.append(p) - p.decompile(data[self.oPasses[i]-currpos:self.oPasses[i+1]-currpos], - ttFont, version) + p.decompile( + data[self.oPasses[i] - currpos : self.oPasses[i + 1] - currpos], + ttFont, + version, + ) def compile(self, ttFont, version=2.0): self.numPasses = len(self.passes) @@ -457,8 +527,9 @@ 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" if version >= 3.0 else ">HH"), - 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 = b"" @@ -475,136 +546,147 @@ class Silf(object): data3 = b"" return data3 + data + datao + data1 + data2 - def toXML(self, writer, ttFont, version=2.0): if version >= 3.0: - writer.simpletag('version', ruleVersion=self.ruleVersion) + writer.simpletag("version", ruleVersion=self.ruleVersion) writer.newline() - writesimple('info', self, writer, *attrs_info) - writesimple('passindexes', self, writer, *attrs_passindexes) - writesimple('contexts', self, writer, *attrs_contexts) - writesimple('attributes', self, writer, *attrs_attributes) + writesimple("info", self, writer, *attrs_info) + writesimple("passindexes", self, writer, *attrs_passindexes) + writesimple("contexts", self, writer, *attrs_contexts) + writesimple("attributes", self, writer, *attrs_attributes) if len(self.jLevels): - writer.begintag('justifications') + writer.begintag("justifications") writer.newline() jformat, jnames, jfixes = sstruct.getformat(Silf_justify_format) for i, j in enumerate(self.jLevels): attrs = dict([(k, getattr(j, k)) for k in jnames]) - writer.simpletag('justify', **attrs) + writer.simpletag("justify", **attrs) writer.newline() - writer.endtag('justifications') + writer.endtag("justifications") writer.newline() if len(self.critFeatures): - writer.begintag('critFeatures') + writer.begintag("critFeatures") writer.newline() writer.write(" ".join(map(str, self.critFeatures))) writer.newline() - writer.endtag('critFeatures') + writer.endtag("critFeatures") writer.newline() if len(self.scriptTags): - writer.begintag('scriptTags') + writer.begintag("scriptTags") writer.newline() writer.write(" ".join(self.scriptTags)) writer.newline() - writer.endtag('scriptTags') + writer.endtag("scriptTags") writer.newline() if self.pMap: - writer.begintag('pseudoMap') + writer.begintag("pseudoMap") writer.newline() for k, v in sorted(self.pMap.items()): - writer.simpletag('pseudo', unicode=hex(k), pseudo=v) + writer.simpletag("pseudo", unicode=hex(k), pseudo=v) writer.newline() - writer.endtag('pseudoMap') + writer.endtag("pseudoMap") writer.newline() self.classes.toXML(writer, ttFont, version) if len(self.passes): - writer.begintag('passes') + 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') + writer.endtag("pass") writer.newline() - writer.endtag('passes') + writer.endtag("passes") writer.newline() def fromXML(self, name, attrs, content, ttFont, version=2.0): - if name == 'version': - self.ruleVersion = float(safeEval(attrs.get('ruleVersion', "0"))) - if name == 'info': + if name == "version": + self.ruleVersion = float(safeEval(attrs.get("ruleVersion", "0"))) + if name == "info": getSimple(self, attrs, *attrs_info) - elif name == 'passindexes': + elif name == "passindexes": getSimple(self, attrs, *attrs_passindexes) - elif name == 'contexts': + elif name == "contexts": getSimple(self, attrs, *attrs_contexts) - elif name == 'attributes': + elif name == "attributes": getSimple(self, attrs, *attrs_attributes) - elif name == 'justifications': + elif name == "justifications": for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue (tag, attrs, subcontent) = element - if tag == 'justify': + if tag == "justify": j = _Object() for k, v in attrs.items(): setattr(j, k, int(v)) self.jLevels.append(j) - elif name == 'critFeatures': + elif name == "critFeatures": self.critFeatures = [] element = content_string(content) self.critFeatures.extend(map(int, element.split())) - elif name == 'scriptTags': + elif name == "scriptTags": self.scriptTags = [] element = content_string(content) for n in element.split(): self.scriptTags.append(n) - elif name == 'pseudoMap': + elif name == "pseudoMap": self.pMap = {} for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue (tag, attrs, subcontent) = element - if tag == 'pseudo': - k = int(attrs['unicode'], 16) - v = attrs['pseudo'] + if tag == "pseudo": + k = int(attrs["unicode"], 16) + v = attrs["pseudo"] self.pMap[k] = v - elif name == 'classes': + elif name == "classes": self.classes = Classes() for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue tag, attrs, subcontent = element self.classes.fromXML(tag, attrs, subcontent, ttFont, version) - elif name == 'passes': + elif name == "passes": for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue tag, attrs, subcontent = element - if tag == 'pass': + if tag == "pass": p = Pass() for e in subcontent: - if not isinstance(e, tuple): continue + if not isinstance(e, tuple): + continue p.fromXML(e[0], e[1], e[2], ttFont, version) self.passes.append(p) class Classes(object): - def __init__(self): self.linear = [] self.nonLinear = [] def decompile(self, data, ttFont, version=2.0): sstruct.unpack2(Silf_classmap_format, data, self) - if version >= 4.0 : - oClasses = struct.unpack((">%dL" % (self.numClass+1)), - data[4:8+4*self.numClass]) + if version >= 4.0: + oClasses = struct.unpack( + (">%dL" % (self.numClass + 1)), data[4 : 8 + 4 * self.numClass] + ) else: - oClasses = struct.unpack((">%dH" % (self.numClass+1)), - data[4:6+2*self.numClass]) - for s,e in zip(oClasses[:self.numLinear], oClasses[1:self.numLinear+1]): - self.linear.append(ttFont.getGlyphName(x) for x in - struct.unpack((">%dH" % ((e-s)/2)), data[s:e])) - for s,e in zip(oClasses[self.numLinear:self.numClass], - oClasses[self.numLinear+1:self.numClass+1]): - nonLinids = [struct.unpack(">HH", data[x:x+4]) for x in range(s+8, e, 4)] + oClasses = struct.unpack( + (">%dH" % (self.numClass + 1)), data[4 : 6 + 2 * self.numClass] + ) + for s, e in zip(oClasses[: self.numLinear], oClasses[1 : self.numLinear + 1]): + self.linear.append( + ttFont.getGlyphName(x) + for x in struct.unpack((">%dH" % ((e - s) / 2)), data[s:e]) + ) + for s, e in zip( + oClasses[self.numLinear : self.numClass], + oClasses[self.numLinear + 1 : self.numClass + 1], + ): + nonLinids = [ + struct.unpack(">HH", data[x : x + 4]) for x in range(s + 8, e, 4) + ] nonLin = dict([(ttFont.getGlyphName(x[0]), x[1]) for x in nonLinids]) self.nonLinear.append(nonLin) @@ -627,61 +709,68 @@ class Classes(object): oClasses.append(len(data) + offset) self.numClass = len(oClasses) - 1 self.numLinear = len(self.linear) - return sstruct.pack(Silf_classmap_format, self) + \ - struct.pack(((">%dL" if version >= 4.0 else ">%dH") % len(oClasses)), - *oClasses) + data + return ( + sstruct.pack(Silf_classmap_format, self) + + struct.pack( + ((">%dL" if version >= 4.0 else ">%dH") % len(oClasses)), *oClasses + ) + + data + ) def toXML(self, writer, ttFont, version=2.0): - writer.begintag('classes') + writer.begintag("classes") writer.newline() - writer.begintag('linearClasses') + writer.begintag("linearClasses") writer.newline() - for i,l in enumerate(self.linear): - writer.begintag('linear', _index=i) + for i, l in enumerate(self.linear): + writer.begintag("linear", _index=i) writer.newline() wrapline(writer, l) - writer.endtag('linear') + writer.endtag("linear") writer.newline() - writer.endtag('linearClasses') + writer.endtag("linearClasses") writer.newline() - writer.begintag('nonLinearClasses') + 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) + writer.simpletag("map", glyph=inp, index=ind) writer.newline() - writer.endtag('nonLinear') + writer.endtag("nonLinear") writer.newline() - writer.endtag('nonLinearClasses') + writer.endtag("nonLinearClasses") writer.newline() - writer.endtag('classes') + writer.endtag("classes") writer.newline() def fromXML(self, name, attrs, content, ttFont, version=2.0): - if name == 'linearClasses': + if name == "linearClasses": for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue tag, attrs, subcontent = element - if tag == 'linear': + if tag == "linear": l = content_string(subcontent).split() self.linear.append(l) - elif name == 'nonLinearClasses': + elif name == "nonLinearClasses": for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue tag, attrs, subcontent = element - if tag =='nonLinear': + if tag == "nonLinear": l = {} for e in subcontent: - if not isinstance(e, tuple): continue + if not isinstance(e, tuple): + continue tag, attrs, subsubcontent = e - if tag == 'map': - l[attrs['glyph']] = int(safeEval(attrs['index'])) + if tag == "map": + l[attrs["glyph"]] = int(safeEval(attrs["index"])) self.nonLinear.append(l) -class Pass(object): +class Pass(object): def __init__(self): self.colMap = {} self.rules = [] @@ -698,71 +787,109 @@ class Pass(object): (numRange, _, _, _) = struct.unpack(">4H", data[:8]) data = data[8:] for i in range(numRange): - (first, last, col) = struct.unpack(">3H", data[6*i:6*i+6]) - for g in range(first, last+1): + (first, last, col) = struct.unpack(">3H", data[6 * i : 6 * i + 6]) + for g in range(first, last + 1): self.colMap[ttFont.getGlyphName(g)] = col - data = data[6*numRange:] + data = data[6 * numRange :] oRuleMap = struct.unpack_from((">%dH" % (self.numSuccess + 1)), data) - data = data[2+2*self.numSuccess:] + data = data[2 + 2 * self.numSuccess :] rules = struct.unpack_from((">%dH" % oRuleMap[-1]), data) - self.rules = [rules[s:e] for (s,e) in zip(oRuleMap, oRuleMap[1:])] - data = data[2*oRuleMap[-1]:] - (self.minRulePreContext, self.maxRulePreContext) = struct.unpack('BB', data[:2]) + self.rules = [rules[s:e] for (s, e) in zip(oRuleMap, oRuleMap[1:])] + data = data[2 * oRuleMap[-1] :] + (self.minRulePreContext, self.maxRulePreContext) = struct.unpack("BB", data[:2]) numStartStates = self.maxRulePreContext - self.minRulePreContext + 1 - self.startStates = struct.unpack((">%dH" % numStartStates), - data[2:2 + numStartStates * 2]) - data = data[2+numStartStates*2:] - self.ruleSortKeys = struct.unpack((">%dH" % self.numRules), data[:2 * self.numRules]) - data = data[2*self.numRules:] - self.rulePreContexts = struct.unpack(("%dB" % self.numRules), data[:self.numRules]) - data = data[self.numRules:] + self.startStates = struct.unpack( + (">%dH" % numStartStates), data[2 : 2 + numStartStates * 2] + ) + data = data[2 + numStartStates * 2 :] + self.ruleSortKeys = struct.unpack( + (">%dH" % self.numRules), data[: 2 * self.numRules] + ) + data = data[2 * self.numRules :] + self.rulePreContexts = struct.unpack( + ("%dB" % self.numRules), data[: self.numRules] + ) + data = data[self.numRules :] (self.collisionThreshold, pConstraint) = struct.unpack(">BH", data[:3]) - oConstraints = list(struct.unpack((">%dH" % (self.numRules + 1)), - data[3:5 + self.numRules * 2])) - data = data[5 + self.numRules * 2:] - oActions = list(struct.unpack((">%dH" % (self.numRules + 1)), - data[:2 + self.numRules * 2])) - data = data[2 * self.numRules + 2:] + oConstraints = list( + struct.unpack( + (">%dH" % (self.numRules + 1)), data[3 : 5 + self.numRules * 2] + ) + ) + data = data[5 + self.numRules * 2 :] + oActions = list( + struct.unpack((">%dH" % (self.numRules + 1)), data[: 2 + self.numRules * 2]) + ) + data = data[2 * self.numRules + 2 :] for i in range(self.numTransitional): - a = array("H", data[i*self.numColumns*2:(i+1)*self.numColumns*2]) - if sys.byteorder != "big": a.byteswap() + a = array( + "H", data[i * self.numColumns * 2 : (i + 1) * self.numColumns * 2] + ) + if sys.byteorder != "big": + a.byteswap() self.stateTrans.append(a) - data = data[self.numTransitional * self.numColumns * 2 + 1:] + data = data[self.numTransitional * self.numColumns * 2 + 1 :] self.passConstraints = data[:pConstraint] data = data[pConstraint:] - for i in range(len(oConstraints)-2,-1,-1): - if oConstraints[i] == 0 : - oConstraints[i] = oConstraints[i+1] - self.ruleConstraints = [(data[s:e] if (e-s > 1) else b"") for (s,e) in zip(oConstraints, oConstraints[1:])] - data = data[oConstraints[-1]:] - self.actions = [(data[s:e] if (e-s > 1) else "") for (s,e) in zip(oActions, oActions[1:])] - data = data[oActions[-1]:] + for i in range(len(oConstraints) - 2, -1, -1): + if oConstraints[i] == 0: + oConstraints[i] = oConstraints[i + 1] + self.ruleConstraints = [ + (data[s:e] if (e - s > 1) else b"") + for (s, e) in zip(oConstraints, oConstraints[1:]) + ] + data = data[oConstraints[-1] :] + self.actions = [ + (data[s:e] if (e - s > 1) else "") for (s, e) in zip(oActions, oActions[1:]) + ] + data = data[oActions[-1] :] # not using debug def compile(self, ttFont, base, version=2.0): # build it all up backwards - oActions = reduce(lambda a, x: (a[0]+len(x), a[1]+[a[0]]), self.actions + [b""], (0, []))[1] - oConstraints = reduce(lambda a, x: (a[0]+len(x), a[1]+[a[0]]), self.ruleConstraints + [b""], (1, []))[1] + oActions = reduce( + lambda a, x: (a[0] + len(x), a[1] + [a[0]]), self.actions + [b""], (0, []) + )[1] + oConstraints = reduce( + lambda a, x: (a[0] + len(x), a[1] + [a[0]]), + self.ruleConstraints + [b""], + (1, []), + )[1] constraintCode = b"\000" + b"".join(self.ruleConstraints) transes = [] for t in self.stateTrans: - if sys.byteorder != "big": t.byteswap() + if sys.byteorder != "big": + t.byteswap() transes.append(t.tobytes()) - if sys.byteorder != "big": t.byteswap() + if sys.byteorder != "big": + t.byteswap() if not len(transes): self.startStates = [0] - oRuleMap = reduce(lambda a, x: (a[0]+len(x), a[1]+[a[0]]), self.rules+[[]], (0, []))[1] + oRuleMap = reduce( + lambda a, x: (a[0] + len(x), a[1] + [a[0]]), self.rules + [[]], (0, []) + )[1] passRanges = [] gidcolmap = dict([(ttFont.getGlyphID(x[0]), x[1]) for x in self.colMap.items()]) - for e in grUtils.entries(gidcolmap, sameval = True): + for e in grUtils.entries(gidcolmap, sameval=True): if e[1]: - passRanges.append((e[0], e[0]+e[1]-1, e[2][0])) + passRanges.append((e[0], e[0] + e[1] - 1, e[2][0])) self.numRules = len(self.actions) - self.fsmOffset = (sstruct.calcsize(Silf_pass_format) + 8 + len(passRanges) * 6 - + len(oRuleMap) * 2 + 2 * oRuleMap[-1] + 2 - + 2 * len(self.startStates) + 3 * self.numRules + 3 - + 4 * self.numRules + 4) - self.pcCode = self.fsmOffset + 2*self.numTransitional*self.numColumns + 1 + base + self.fsmOffset = ( + sstruct.calcsize(Silf_pass_format) + + 8 + + len(passRanges) * 6 + + len(oRuleMap) * 2 + + 2 * oRuleMap[-1] + + 2 + + 2 * len(self.startStates) + + 3 * self.numRules + + 3 + + 4 * self.numRules + + 4 + ) + self.pcCode = ( + self.fsmOffset + 2 * self.numTransitional * self.numColumns + 1 + base + ) self.rcCode = self.pcCode + len(self.passConstraints) self.aCode = self.rcCode + len(constraintCode) self.oDebug = 0 @@ -771,115 +898,140 @@ class Pass(object): data += grUtils.bininfo(len(passRanges), 6) data += b"".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, []) + flatrules = reduce(lambda a, x: a + x, self.rules, []) data += struct.pack((">%dH" % oRuleMap[-1]), *flatrules) data += struct.pack("BB", self.minRulePreContext, self.maxRulePreContext) data += struct.pack((">%dH" % len(self.startStates)), *self.startStates) data += struct.pack((">%dH" % self.numRules), *self.ruleSortKeys) data += struct.pack(("%dB" % self.numRules), *self.rulePreContexts) data += struct.pack(">BH", self.collisionThreshold, len(self.passConstraints)) - data += struct.pack((">%dH" % (self.numRules+1)), *oConstraints) - data += struct.pack((">%dH" % (self.numRules+1)), *oActions) - return data + b"".join(transes) + struct.pack("B", 0) + \ - self.passConstraints + constraintCode + b"".join(self.actions) + data += struct.pack((">%dH" % (self.numRules + 1)), *oConstraints) + data += struct.pack((">%dH" % (self.numRules + 1)), *oActions) + return ( + data + + b"".join(transes) + + struct.pack("B", 0) + + self.passConstraints + + constraintCode + + b"".join(self.actions) + ) def toXML(self, writer, ttFont, version=2.0): - writesimple('info', self, writer, *pass_attrs_info) - writesimple('fsminfo', self, writer, *pass_attrs_fsm) - writer.begintag('colmap') + writesimple("info", self, writer, *pass_attrs_info) + writesimple("fsminfo", self, writer, *pass_attrs_fsm) + writer.begintag("colmap") writer.newline() - wrapline(writer, ["{}={}".format(*x) for x in sorted(self.colMap.items(), - key=lambda x:ttFont.getGlyphID(x[0]))]) - writer.endtag('colmap') + wrapline( + writer, + [ + "{}={}".format(*x) + for x in sorted( + self.colMap.items(), key=lambda x: ttFont.getGlyphID(x[0]) + ) + ], + ) + writer.endtag("colmap") writer.newline() - writer.begintag('staterulemap') + writer.begintag("staterulemap") writer.newline() for i, r in enumerate(self.rules): - writer.simpletag('state', number = self.numRows - self.numSuccess + i, - rules = " ".join(map(str, r))) + writer.simpletag( + "state", + number=self.numRows - self.numSuccess + i, + rules=" ".join(map(str, r)), + ) writer.newline() - writer.endtag('staterulemap') + writer.endtag("staterulemap") writer.newline() - writer.begintag('rules') + writer.begintag("rules") writer.newline() for i in range(len(self.actions)): - writer.begintag('rule', index=i, precontext=self.rulePreContexts[i], - sortkey=self.ruleSortKeys[i]) + writer.begintag( + "rule", + index=i, + precontext=self.rulePreContexts[i], + sortkey=self.ruleSortKeys[i], + ) writer.newline() if len(self.ruleConstraints[i]): - writecode('constraint', writer, self.ruleConstraints[i]) - writecode('action', writer, self.actions[i]) - writer.endtag('rule') + writecode("constraint", writer, self.ruleConstraints[i]) + writecode("action", writer, self.actions[i]) + writer.endtag("rule") writer.newline() - writer.endtag('rules') + writer.endtag("rules") writer.newline() if len(self.passConstraints): - writecode('passConstraint', writer, self.passConstraints) + writecode("passConstraint", writer, self.passConstraints) if len(self.stateTrans): - writer.begintag('fsm') + writer.begintag("fsm") writer.newline() - writer.begintag('starts') + writer.begintag("starts") writer.write(" ".join(map(str, self.startStates))) - writer.endtag('starts') + 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') + writer.endtag("row") writer.newline() - writer.endtag('fsm') + writer.endtag("fsm") writer.newline() def fromXML(self, name, attrs, content, ttFont, version=2.0): - if name == 'info': + if name == "info": getSimple(self, attrs, *pass_attrs_info) - elif name == 'fsminfo': + elif name == "fsminfo": getSimple(self, attrs, *pass_attrs_fsm) - elif name == 'colmap': + elif name == "colmap": e = content_string(content) for w in e.split(): - x = w.split('=') - if len(x) != 2 or x[0] == '' or x[1] == '': continue + x = w.split("=") + if len(x) != 2 or x[0] == "" or x[1] == "": + continue self.colMap[x[0]] = int(x[1]) - elif name == 'staterulemap': + elif name == "staterulemap": for e in content: - if not isinstance(e, tuple): continue + if not isinstance(e, tuple): + continue tag, a, c = e - if tag == 'state': - self.rules.append([int(x) for x in a['rules'].split(" ")]) - elif name == 'rules': + if tag == "state": + self.rules.append([int(x) for x in a["rules"].split(" ")]) + elif name == "rules": for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue tag, a, c = element - if tag != 'rule': continue - self.rulePreContexts.append(int(a['precontext'])) - self.ruleSortKeys.append(int(a['sortkey'])) + if tag != "rule": + continue + self.rulePreContexts.append(int(a["precontext"])) + self.ruleSortKeys.append(int(a["sortkey"])) con = b"" act = b"" for e in c: - if not isinstance(e, tuple): continue + if not isinstance(e, tuple): + continue tag, a, subc = e - if tag == 'constraint': + if tag == "constraint": con = readcode(subc) - elif tag == 'action': + elif tag == "action": act = readcode(subc) self.actions.append(act) self.ruleConstraints.append(con) - elif name == 'passConstraint': + elif name == "passConstraint": self.passConstraints = readcode(content) - elif name == 'fsm': + elif name == "fsm": for element in content: - if not isinstance(element, tuple): continue + if not isinstance(element, tuple): + continue tag, a, c = element - if tag == 'row': - s = array('H') + if tag == "row": + s = array("H") e = content_string(c) s.extend(map(int, e.split())) self.stateTrans.append(s) - elif tag == 'starts': + elif tag == "starts": s = [] e = content_string(c) s.extend(map(int, e.split())) self.startStates = s - |