def fromXML(self, name, attrs, content, ttFont): value = attrs["value"] if name in ("macStyle", "flags"): value = binary2num(value) else: value = safeEval(value) setattr(self, name, value)
def fromXML(self, name, attrs, content): from fontTools.misc.textTools import binary2num, readHex if attrs.get("raw"): self.setBytecode(readHex(content)) return content = strjoin(content) content = content.split() program = [] end = len(content) i = 0 while i < end: token = content[i] i = i + 1 try: token = int(token) except ValueError: try: token = float(token) except ValueError: program.append(token) if token in ('hintmask', 'cntrmask'): mask = content[i] maskBytes = b"" for j in range(0, len(mask), 8): maskBytes = maskBytes + bytechr(binary2num(mask[j:j+8])) program.append(maskBytes) i = i + 1 else: program.append(token) else: program.append(token) self.setProgram(program)
def setUseTypoMetricsTrue(fontPath, outPath): # Get Font object from path font = TTFont(fontPath) # Get the OS/2 Table os2 = font["OS/2"] # Make sure that we only fix fonts with an OS/2 table version # that is 4 or greater if os2.version >= 4: # Get the binary representation of fsSelection b = num2binary(os2.fsSelection, 16) # Make a new binary representation of fsSelection that sets # the Use Typo Metrics bit to false (0) nb = b[:9] + '1' + b[10:] # Give the font the new fsSelection os2.fsSelection = binary2num(nb) # Save font to new path font.save(outPath) else: print(fontPath + " OS/2 table version is less than 4, nothing to fix.")
def setUseTypoMetricsFalse(fontPath, outDirectory): # Get Font object from path font = TTFont(fontPath) # Make new pathname to save fixed font oldD, f = os.path.split(fontPath) new = os.path.join(outDirectory, f) # Get the OS/2 Table os2 = font["OS/2"] # Make sure that we only fix fonts with an OS/2 table version # that is 4 or greater if os2.version >= 4: # Get the binary representation of fsSelection b = num2binary(os2.fsSelection,16) # Make a new binary representation of fsSelection that sets # the Use Typo Metrics bit to false (0) nb = b[:9] + '0' + b[10:] # Give the font the new fsSelection os2.fsSelection = binary2num(nb) # Save font to new path font.save(new) else: print fontPath + " OS/2 table version is less than 4, nothing to fix."
def fromXML(self, name, attrs, content, ttFont): assert(name == "NamedInstance") self.flags = binary2num(attrs.get("flags", "0")) self.nameID = safeEval(attrs["nameID"]) for tag, elementAttrs, _ in filter(lambda t: type(t) is tuple, content): if tag == "coord": self.coordinates[elementAttrs["axis"]] = safeEval(elementAttrs["value"])
def fromXML(self, name, attrs, content, ttFont): value = attrs["value"] if name in ("created", "modified"): value = calendar.timegm(time.strptime(value)) - mac_epoch_diff elif name in ("macStyle", "flags"): value = binary2num(value) else: value = safeEval(value) setattr(self, name, value)
def fromXML(self, name, attrs, content, ttFont): value = attrs["value"] if name in ("created", "modified"): value = timestampFromString(value) elif name in ("macStyle", "flags"): value = binary2num(value) else: value = safeEval(value) setattr(self, name, value)
def fromXML(self, name, _attrs, content, ttFont): assert(name == "Axis") for tag, _, value in filter(lambda t: type(t) is tuple, content): value = ''.join(value) if tag == "AxisTag": self.axisTag = value elif tag == "Flags": self.flags = binary2num(value) elif tag in ["MinValue", "DefaultValue", "MaxValue", "NameID"]: setattr(self, tag[0].lower() + tag[1:], safeEval(value))
def fromXML(self, name, attrs, content, ttFont): value = attrs["value"] fixes = sstruct.getformat(headFormat)[2] if name in fixes: value = strToFixedToFloat(value, precisionBits=fixes[name]) elif name in ("created", "modified"): value = timestampFromString(value) elif name in ("macStyle", "flags"): value = binary2num(value) else: value = safeEval(value) setattr(self, name, value)
def fromXML(self, xxx_todo_changeme, ttFont): (name, attrs, content) = xxx_todo_changeme value = attrs["value"] if name in ("created", "modified"): value = parse_date(value) - mac_epoch_diff elif name in ("macStyle", "flags"): value = binary2num(value) else: try: value = safeEval(value) except OverflowError: value = int(value) setattr(self, name, value)
def fromXML(self, name, attrs, content, ttFont): if name == "version": setattr(self, name, safeEval(attrs["value"])) elif name == "flags": setattr(self, name, binary2num(attrs["value"])) elif name == "strike": current_strike = Strike() for element in content: if isinstance(element, tuple): name, attrs, content = element current_strike.fromXML(name, attrs, content, ttFont) self.strikes[current_strike.ppem] = current_strike else: from fontTools import ttLib raise ttLib.TTLibError("can't handle '%s' element" % name)
def fromXML(self, name, attrs, content, ttFont): if name =="version": setattr(self, name, safeEval(attrs["value"])) elif name == "flags": setattr(self, name, binary2num(attrs["value"])) elif name == "strike": current_strike = Strike() for element in content: if isinstance(element, tuple): name, attrs, content = element current_strike.fromXML(name, attrs, content, ttFont) self.strikes[current_strike.ppem] = current_strike else: from fontTools import ttLib raise ttLib.TTLibError("can't handle '%s' element" % name)
def fromXML(self, name, attrs, content, ttFont): if name == "panose": self.panose = panose = Panose() for element in content: if isinstance(element, tuple): name, attrs, content = element panose.fromXML(name, attrs, content, ttFont) elif name in ("ulUnicodeRange1", "ulUnicodeRange2", "ulUnicodeRange3", "ulUnicodeRange4", "ulCodePageRange1", "ulCodePageRange2", "fsType", "fsSelection"): setattr(self, name, binary2num(attrs["value"])) elif name == "achVendID": setattr(self, name, safeEval("'''" + attrs["value"] + "'''")) else: setattr(self, name, safeEval(attrs["value"]))
def fromXML(self, xxx_todo_changeme1, ttFont): (name, attrs, content) = xxx_todo_changeme1 if name == "panose": self.panose = panose = Panose() for element in content: if type(element) is tuple: panose.fromXML(element, ttFont) elif name in ("ulUnicodeRange1", "ulUnicodeRange2", "ulUnicodeRange3", "ulUnicodeRange4", "ulCodePageRange1", "ulCodePageRange2", "fsType", "fsSelection"): setattr(self, name, binary2num(attrs["value"])) elif name == "achVendID": setattr(self, name, safeEval("'''" + attrs["value"] + "'''")) else: setattr(self, name, safeEval(attrs["value"]))
def fromXML(self, xxx_todo_changeme1, ttFont): (name, attrs, content) = xxx_todo_changeme1 if name == "panose": self.panose = panose = Panose() for element in content: if type(element) == TupleType: panose.fromXML(element, ttFont) elif name in ("ulUnicodeRange1", "ulUnicodeRange2", "ulUnicodeRange3", "ulUnicodeRange4", "ulCodePageRange1", "ulCodePageRange2", "fsType", "fsSelection"): setattr(self, name, binary2num(attrs["value"])) elif name == "achVendID": setattr(self, name, safeEval("'''" + attrs["value"] + "'''")) else: setattr(self, name, safeEval(attrs["value"]))
def intListToNum(intList, start, length): all = [] bin = "" for i in range(start, start + length): if i in intList: b = "1" else: b = "0" bin = b + bin if not (i + 1) % 8: all.append(bin) bin = "" if bin: all.append(bin) all.reverse() all = " ".join(all) return binary2num(all)
class T2CharString(ByteCodeBase): operandEncoding = t2OperandEncoding operators, opcodes = buildOperatorDict(t2Operators) def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None): if program is None: program = [] self.bytecode = bytecode self.program = program self.private = private self.globalSubrs = globalSubrs def __repr__(self): if self.bytecode is None: return "<%s (source) at %x>" % (self.__class__.__name__, id(self)) else: return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self)) def getIntEncoder(self): return encodeIntT2 def getFixedEncoder(self): return encodeFixed def decompile(self): if not self.needsDecompilation(): return subrs = getattr(self.private, "Subrs", []) decompiler = SimpleT2Decompiler(subrs, self.globalSubrs) decompiler.execute(self) def draw(self, pen): subrs = getattr(self.private, "Subrs", []) extractor = T2OutlineExtractor(pen, subrs, self.globalSubrs, self.private.nominalWidthX, self.private.defaultWidthX) extractor.execute(self) self.width = extractor.width def compile(self): if self.bytecode is not None: return assert self.program, "illegal CharString: decompiled to empty program" assert self.program[-1] in ("endchar", "return", "callsubr", "callgsubr", "seac"), "illegal CharString" bytecode = [] opcodes = self.opcodes program = self.program encodeInt = self.getIntEncoder() encodeFixed = self.getFixedEncoder() i = 0 end = len(program) while i < end: token = program[i] i = i + 1 tp = type(token) if tp == types.StringType: try: bytecode.extend(map(chr, opcodes[token])) except KeyError: raise CharStringCompileError, "illegal operator: %s" % token if token in ('hintmask', 'cntrmask'): bytecode.append(program[i]) # hint mask i = i + 1 elif tp == types.IntType: bytecode.append(encodeInt(token)) elif tp == types.FloatType: bytecode.append(encodeFixed(token)) else: assert 0, "unsupported type: %s" % tp try: bytecode = "".join(bytecode) except TypeError: print bytecode raise self.setBytecode(bytecode) def needsDecompilation(self): return self.bytecode is not None def setProgram(self, program): self.program = program self.bytecode = None def setBytecode(self, bytecode): self.bytecode = bytecode self.program = None def getToken(self, index, len=len, ord=ord, getattr=getattr, type=type, StringType=types.StringType): if self.bytecode is not None: if index >= len(self.bytecode): return None, 0, 0 b0 = ord(self.bytecode[index]) index = index + 1 code = self.operandEncoding[b0] handler = getattr(self, code) token, index = handler(b0, self.bytecode, index) else: if index >= len(self.program): return None, 0, 0 token = self.program[index] index = index + 1 isOperator = type(token) == StringType return token, isOperator, index def getBytes(self, index, nBytes): if self.bytecode is not None: newIndex = index + nBytes bytes = self.bytecode[index:newIndex] index = newIndex else: bytes = self.program[index] index = index + 1 assert len(bytes) == nBytes return bytes, index def do_operator(self, b0, data, index): if b0 == 12: op = (b0, ord(data[index])) index = index+1 else: op = b0 operator = self.operators[op] return operator, index def toXML(self, xmlWriter): from fontTools.misc.textTools import num2binary if self.bytecode is not None: xmlWriter.dumphex(self.bytecode) else: index = 0 args = [] while 1: token, isOperator, index = self.getToken(index) if token is None: break if isOperator: args = map(str, args) if token in ('hintmask', 'cntrmask'): hintMask, isOperator, index = self.getToken(index) bits = [] for byte in hintMask: bits.append(num2binary(ord(byte), 8)) hintMask = string.join(bits, "") line = string.join(args + [token, hintMask], " ") else: line = string.join(args + [token], " ") xmlWriter.write(line) xmlWriter.newline() args = [] else: args.append(token) def fromXML(self, (name, attrs, content)): from fontTools.misc.textTools import binary2num, readHex if attrs.get("raw"): self.setBytecode(readHex(content)) return content = "".join(content) content = content.split() program = [] end = len(content) i = 0 while i < end: token = content[i] i = i + 1 try: token = int(token) except ValueError: try: token = float(token) except ValueError: program.append(token) if token in ('hintmask', 'cntrmask'): mask = content[i] maskBytes = "" for j in range(0, len(mask), 8): maskBytes = maskBytes + chr(binary2num(mask[j:j+8])) program.append(maskBytes) i = i + 1 else: program.append(token) else: program.append(token) self.setProgram(program)
def _assemble(self, skipWhite=_skipWhite, mnemonicDict=mnemonicDict, strip=string.strip, binary2num=binary2num): assembly = self.assembly if type(assembly) == type([]): assembly = string.join(assembly, "") bytecode = [] push = bytecode.append lenAssembly = len(assembly) pos = skipWhite(assembly, 0) while pos < lenAssembly: m = _tokenRE.match(assembly, pos) if m is None: raise tt_instructions_error, "Syntax error in TT program (%s)" % assembly[pos-5:pos+15] dummy, mnemonic, arg, number, comment = m.groups() pos = m.regs[0][1] if comment: continue arg = strip(arg) if mnemonic not in ("NPUSHB", "NPUSHW", "PUSHB", "PUSHW"): op, argBits, name = mnemonicDict[mnemonic] if len(arg) <> argBits: raise tt_instructions_error, "Incorrect number of argument bits (%s[%s])" % (mnemonic, arg) if arg: arg = binary2num(arg) push(op + arg) else: push(op) else: args = [] while pos < lenAssembly: pos = skipWhite(assembly, pos) m = _tokenRE.match(assembly, pos) if m is None: raise tt_instructions_error, "Syntax error in TT program (%s)" % assembly[pos:pos+15] dummy, mnemonic, arg, number, comment = m.groups() if number is None and comment is None: break pos = m.regs[0][1] if comment is not None: continue args.append(int(number)) if max(args) > 255 or min(args) < 0: words = 1 mnemonic = "PUSHW" else: words = 0 mnemonic = "PUSHB" nArgs = len(args) if nArgs <= 8: op, argBits, name = streamMnemonicDict[mnemonic] op = op + nArgs - 1 push(op) elif nArgs < 256: mnemonic = "N" + mnemonic op, argBits, name = streamMnemonicDict[mnemonic] push(op) push(nArgs) else: raise tt_instructions_error, "More than 255 push arguments (%s)" % nArgs if words: for value in args: push((value >> 8) & 0xff) push(value & 0xff) else: for value in args: push(value) pos = skipWhite(assembly, pos) if bytecode: assert max(bytecode) < 256 and min(bytecode) >= 0 self.bytecode = array.array("B", bytecode)
def _assemble(self, skipWhite=_skipWhite, mnemonicDict=mnemonicDict, strip=string.strip, binary2num=binary2num): assembly = self.assembly if type(assembly) == type([]): assembly = string.join(assembly, " ") bytecode = [] push = bytecode.append lenAssembly = len(assembly) pos = skipWhite(assembly, 0) while pos < lenAssembly: m = _tokenRE.match(assembly, pos) if m is None: raise tt_instructions_error, "Syntax error in TT program (%s)" % assembly[pos-5:pos+15] dummy, mnemonic, arg, number, comment = m.groups() pos = m.regs[0][1] if comment: continue arg = strip(arg) if mnemonic not in ("NPUSHB", "NPUSHW", "PUSHB", "PUSHW"): op, argBits, name = mnemonicDict[mnemonic] if len(arg) <> argBits: raise tt_instructions_error, "Incorrect number of argument bits (%s[%s])" % (mnemonic, arg) if arg: arg = binary2num(arg) push(op + arg) else: push(op) else: args = [] while pos < lenAssembly: pos = skipWhite(assembly, pos) m = _tokenRE.match(assembly, pos) if m is None: raise tt_instructions_error, "Syntax error in TT program (%s)" % assembly[pos:pos+15] dummy, mnemonic, arg, number, comment = m.groups() if number is None and comment is None: break pos = m.regs[0][1] if comment is not None: continue args.append(int(number)) if max(args) > 255 or min(args) < 0: words = 1 mnemonic = "PUSHW" else: words = 0 mnemonic = "PUSHB" nArgs = len(args) if nArgs <= 8: op, argBits, name = streamMnemonicDict[mnemonic] op = op + nArgs - 1 push(op) elif nArgs < 256: mnemonic = "N" + mnemonic op, argBits, name = streamMnemonicDict[mnemonic] push(op) push(nArgs) else: raise tt_instructions_error, "More than 255 push arguments (%s)" % nArgs if words: for value in args: push((value >> 8) & 0xff) push(value & 0xff) else: for value in args: push(value) pos = skipWhite(assembly, pos) if bytecode: assert max(bytecode) < 256 and min(bytecode) >= 0 self.bytecode = array.array("B", bytecode)
def _assemble(self): assembly = self.assembly if isinstance(assembly, type([])): assembly = ' '.join(assembly) bytecode = [] push = bytecode.append lenAssembly = len(assembly) pos = _skipWhite(assembly, 0) while pos < lenAssembly: m = _tokenRE.match(assembly, pos) if m is None: raise tt_instructions_error("Syntax error in TT program (%s)" % assembly[pos-5:pos+15]) dummy, mnemonic, arg, number, comment = m.groups() pos = m.regs[0][1] if comment: continue arg = arg.strip() if mnemonic.startswith("INSTR"): # Unknown instruction op = int(mnemonic[5:]) push(op) elif mnemonic not in ("PUSH", "NPUSHB", "NPUSHW", "PUSHB", "PUSHW"): op, argBits = mnemonicDict[mnemonic] if len(arg) != argBits: raise tt_instructions_error("Incorrect number of argument bits (%s[%s])" % (mnemonic, arg)) if arg: arg = binary2num(arg) push(op + arg) else: push(op) else: args = [] pos = _skipWhite(assembly, pos) while pos < lenAssembly: m = _tokenRE.match(assembly, pos) if m is None: raise tt_instructions_error("Syntax error in TT program (%s)" % assembly[pos:pos+15]) dummy, _mnemonic, arg, number, comment = m.groups() if number is None and comment is None: break pos = m.regs[0][1] pos = _skipWhite(assembly, pos) if comment is not None: continue args.append(int(number)) nArgs = len(args) if mnemonic == "PUSH": # Automatically choose the most compact representation nWords = 0 while nArgs: while nWords < nArgs and nWords < 255 and not (0 <= args[nWords] <= 255): nWords += 1 nBytes = 0 while nWords+nBytes < nArgs and nBytes < 255 and 0 <= args[nWords+nBytes] <= 255: nBytes += 1 if nBytes < 2 and nWords + nBytes < 255 and nWords + nBytes != nArgs: # Will write bytes as words nWords += nBytes continue # Write words if nWords: if nWords <= 8: op, argBits = streamMnemonicDict["PUSHW"] op = op + nWords - 1 push(op) else: op, argBits = streamMnemonicDict["NPUSHW"] push(op) push(nWords) for value in args[:nWords]: assert -32768 <= value < 32768, "PUSH value out of range %d" % value push((value >> 8) & 0xff) push(value & 0xff) # Write bytes if nBytes: pass if nBytes <= 8: op, argBits = streamMnemonicDict["PUSHB"] op = op + nBytes - 1 push(op) else: op, argBits = streamMnemonicDict["NPUSHB"] push(op) push(nBytes) for value in args[nWords:nWords+nBytes]: push(value) nTotal = nWords + nBytes args = args[nTotal:] nArgs -= nTotal nWords = 0 else: # Write exactly what we've been asked to words = mnemonic[-1] == "W" op, argBits = streamMnemonicDict[mnemonic] if mnemonic[0] != "N": assert nArgs <= 8, nArgs op = op + nArgs - 1 push(op) else: assert nArgs < 256 push(op) push(nArgs) if words: for value in args: assert -32768 <= value < 32768, "PUSHW value out of range %d" % value push((value >> 8) & 0xff) push(value & 0xff) else: for value in args: assert 0 <= value < 256, "PUSHB value out of range %d" % value push(value) pos = _skipWhite(assembly, pos) if bytecode: assert max(bytecode) < 256 and min(bytecode) >= 0 self.bytecode = array.array("B", bytecode)
def _assemble(self, preserveWidths=False): assembly = self.assembly if isinstance(assembly, type([])): assembly = ' '.join(assembly) bytecode = [] push = bytecode.append lenAssembly = len(assembly) pos = _skipWhite(assembly, 0) while pos < lenAssembly: m = _tokenRE.match(assembly, pos) if m is None: raise tt_instructions_error("Syntax error in TT program (%s)" % assembly[pos - 5:pos + 15]) dummy, mnemonic, arg, number, comment = m.groups() pos = m.regs[0][1] if comment: pos = _skipWhite(assembly, pos) continue arg = arg.strip() if mnemonic.startswith("INSTR"): # Unknown instruction op = int(mnemonic[5:]) push(op) elif mnemonic not in ("PUSH", "NPUSHB", "NPUSHW", "PUSHB", "PUSHW"): op, argBits, name = mnemonicDict[mnemonic] if len(arg) != argBits: raise tt_instructions_error( "Incorrect number of argument bits (%s[%s])" % (mnemonic, arg)) if arg: arg = binary2num(arg) push(op + arg) else: push(op) else: args = [] argIsWord = [] pos = _skipWhite(assembly, pos) while pos < lenAssembly: m = _tokenRE.match(assembly, pos) if m is None: raise tt_instructions_error( "Syntax error in TT program (%s)" % assembly[pos:pos + 15]) dummy, _mnemonic, arg, number, comment = m.groups() if number is None and comment is None: break pos = m.regs[0][1] pos = _skipWhite(assembly, pos) comment_with_m_match = _tokenRE.match(assembly, pos) cwm = comment_with_m_match.groups()[4] if comment is not None: continue args.append(int(number)) argIsWord.append(True if cwm is not None and cwm.strip() == WORD_SUFFIX else False) nArgs = len(args) if mnemonic == "PUSH": # Automatically choose the most compact representation nWords = 0 while nArgs: while nWords < nArgs and nWords < 255 and ( not (0 <= args[nWords] <= 255) or (preserveWidths and argIsWord[nWords])): nWords += 1 nBytes = 0 while nWords + nBytes < nArgs and nBytes < 255 and 0 <= args[ nWords + nBytes] <= 255: nBytes += 1 if nBytes < 2 and nWords + nBytes < 255 and nWords + nBytes != nArgs: # Will write bytes as words nWords += nBytes continue # Write words if nWords: if nWords <= 8: op, argBits, name = streamMnemonicDict["PUSHW"] op = op + nWords - 1 push(op) else: op, argBits, name = streamMnemonicDict[ "NPUSHW"] push(op) push(nWords) for value in args[:nWords]: assert -32768 <= value < 32768, "PUSH value out of range %d" % value push((value >> 8) & 0xff) push(value & 0xff) # Write bytes if nBytes: pass if nBytes <= 8: op, argBits, name = streamMnemonicDict["PUSHB"] op = op + nBytes - 1 push(op) else: op, argBits, name = streamMnemonicDict[ "NPUSHB"] push(op) push(nBytes) for value in args[nWords:nWords + nBytes]: push(value) nTotal = nWords + nBytes args = args[nTotal:] argIsWord = argIsWord[nTotal:] nArgs -= nTotal nWords = 0 else: # Write exactly what we've been asked to words = mnemonic[-1] == "W" op, argBits, name = streamMnemonicDict[mnemonic] if mnemonic[0] != "N": assert nArgs <= 8, nArgs op = op + nArgs - 1 push(op) else: assert nArgs < 256 push(op) push(nArgs) if words: for value in args: assert -32768 <= value < 32768, "PUSHW value out of range %d" % value push((value >> 8) & 0xff) push(value & 0xff) else: for value in args: assert 0 <= value < 256, "PUSHB value out of range %d" % value push(value) pos = _skipWhite(assembly, pos) if bytecode: assert max(bytecode) < 256 and min(bytecode) >= 0 self.bytecode = array.array("B", bytecode)
writer.begintag("panose") writer.newline() value.toXML(writer, ttFont) writer.endtag("panose") elif name in ("ulUnicodeRange1", "ulUnicodeRange2", "ulUnicodeRange3", "ulUnicodeRange4", "ulCodePageRange1", "ulCodePageRange2"): writer.simpletag(name, value=num2binary(value)) elif name in ("fsType", "fsSelection"): writer.simpletag(name, value=num2binary(value, 16)) elif name == "achVendID": writer.simpletag(name, value=repr(value)[1:-1]) else: writer.simpletag(name, value=value) writer.newline() def fromXML(self, (name, attrs, content), ttFont): if name == "panose": self.panose = panose = Panose() for element in content: if type(element) == TupleType: panose.fromXML(element, ttFont) elif name in ("ulUnicodeRange1", "ulUnicodeRange2", "ulUnicodeRange3", "ulUnicodeRange4", "ulCodePageRange1", "ulCodePageRange2", "fsType", "fsSelection"): setattr(self, name, binary2num(attrs["value"])) elif name == "achVendID": setattr(self, name, safeEval("'''" + attrs["value"] + "'''")) else: setattr(self, name, safeEval(attrs["value"]))
class table__h_e_a_d(DefaultTable.DefaultTable): dependencies = ['maxp', 'loca'] def decompile(self, data, ttFont): dummy, rest = sstruct.unpack2(headFormat, data, self) if rest: # this is quite illegal, but there seem to be fonts out there that do this assert rest == "\0\0" self.unitsPerEm = int(self.unitsPerEm) self.flags = int(self.flags) self.strings2dates() def compile(self, ttFont): self.modified = long(time.time() - mac_epoch_diff) self.dates2strings() data = sstruct.pack(headFormat, self) self.strings2dates() return data def strings2dates(self): self.created = bin2long(self.created) self.modified = bin2long(self.modified) def dates2strings(self): self.created = long2bin(self.created) self.modified = long2bin(self.modified) def toXML(self, writer, ttFont): writer.comment( "Most of this table will be recalculated by the compiler") writer.newline() formatstring, names, fixes = sstruct.getformat(headFormat) for name in names: value = getattr(self, name) if name in ("created", "modified"): try: value = time.asctime( time.gmtime(max(0, value + mac_epoch_diff))) except ValueError: value = time.asctime(time.gmtime(0)) if name in ("magicNumber", "checkSumAdjustment"): if value < 0: value = value + 0x100000000L value = hex(value) if value[-1:] == "L": value = value[:-1] elif name in ("macStyle", "flags"): value = num2binary(value, 16) writer.simpletag(name, value=value) writer.newline() def fromXML(self, (name, attrs, content), ttFont): value = attrs["value"] if name in ("created", "modified"): value = parse_date(value) - mac_epoch_diff elif name in ("macStyle", "flags"): value = binary2num(value) else: try: value = safeEval(value) except OverflowError: value = long(value) setattr(self, name, value)