Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
	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)
Exemplo n.º 3
0
	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)
Exemplo n.º 4
0
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.")
Exemplo n.º 5
0
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."
Exemplo n.º 6
0
	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)
Exemplo n.º 7
0
 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"])
Exemplo n.º 8
0
	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 = calendar.timegm(time.strptime(value)) - mac_epoch_diff
		elif name in ("macStyle", "flags"):
			value = binary2num(value)
		else:
			value = safeEval(value)
		setattr(self, name, value)
Exemplo n.º 10
0
	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)
Exemplo n.º 11
0
 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)
Exemplo n.º 12
0
 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))
Exemplo n.º 13
0
 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)
Exemplo n.º 14
0
 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)
Exemplo n.º 15
0
	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)
Exemplo n.º 16
0
 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)
Exemplo n.º 17
0
	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)
Exemplo n.º 18
0
 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"]))
Exemplo n.º 19
0
 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"]))
Exemplo n.º 20
0
	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"]))
Exemplo n.º 21
0
	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"]))
Exemplo n.º 22
0
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)
Exemplo n.º 23
0
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)
Exemplo n.º 24
0
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)
Exemplo n.º 25
0
	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)
Exemplo n.º 26
0
	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)
Exemplo n.º 27
0
	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)
Exemplo n.º 28
0
    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)
Exemplo n.º 29
0
                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"]))
Exemplo n.º 30
0
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)