Ejemplo n.º 1
0
def encodeFloat(f):
    # For CFF only, used in cffLib
    if f == 0.0:  # 0.0 == +0.0 == -0.0
        return realZeroBytes
    # Note: 14 decimal digits seems to be the limitation for CFF real numbers
    # in macOS. However, we use 8 here to match the implementation of AFDKO.
    s = "%.8G" % f
    if s[:2] == "0.":
        s = s[1:]
    elif s[:3] == "-0.":
        s = "-" + s[2:]
    nibbles = []
    while s:
        c = s[0]
        s = s[1:]
        if c == "E":
            c2 = s[:1]
            if c2 == "-":
                s = s[1:]
                c = "E-"
            elif c2 == "+":
                s = s[1:]
        nibbles.append(realNibblesDict[c])
    nibbles.append(0xf)
    if len(nibbles) % 2:
        nibbles.append(0xf)
    d = bytechr(30)
    for i in range(0, len(nibbles), 2):
        d = d + bytechr(nibbles[i] << 4 | nibbles[i + 1])
    return d
Ejemplo n.º 2
0
def writePFB(path, data):
    chunks = findEncryptedChunks(data)
    with open(path, "wb") as f:
        for isEncrypted, chunk in chunks:
            if isEncrypted:
                code = 2
            else:
                code = 1
            f.write(bytechr(128) + bytechr(code))
            f.write(longToString(len(chunk)))
            f.write(chunk)
        f.write(bytechr(128) + bytechr(3))
Ejemplo n.º 3
0
 def compile(self, ttFont):
     d = self.__dict__.copy()
     d["nameLength"] = bytechr(len(self.baseGlyphName))
     d["uniqueName"] = self.compilecompileUniqueName(self.uniqueName, 28)
     METAMD5List = eval(self.METAMD5)
     d["METAMD5"] = b""
     for val in METAMD5List:
         d["METAMD5"] += bytechr(val)
     assert (len(d["METAMD5"]) == 16
             ), "Failed to pack 16 byte MD5 hash in SING table"
     data = sstruct.pack(SINGFormat, d)
     data = data + tobytes(self.baseGlyphName)
     return data
Ejemplo n.º 4
0
    def maskByte(self, hHints, vHints):
        # return hintmask bytes for known hints.
        numHHints = len(hHints)
        numVHints = len(vHints)
        maskVal = 0
        byteIndex = 0
        self.byteLength = byteLength = int((7 + numHHints + numVHints) / 8)
        mask = b""
        self.hList.sort()
        for hint in self.hList:
            try:
                i = hHints.index(hint)
            except ValueError:
                # we get here if some hints have been dropped
                # because of the stack limit
                continue
            newbyteIndex = int(i / 8)
            if newbyteIndex != byteIndex:
                mask += bytechr(maskVal)
                byteIndex += 1
                while byteIndex < newbyteIndex:
                    mask += b"\0"
                    byteIndex += 1
                maskVal = 0
            maskVal += 2**(7 - (i % 8))

        self.vList.sort()
        for hint in self.vList:
            try:
                i = numHHints + vHints.index(hint)
            except ValueError:
                # we get here if some hints have been dropped
                # because of the stack limit
                continue
            newbyteIndex = int(i / 8)
            if newbyteIndex != byteIndex:
                mask += bytechr(maskVal)
                byteIndex += 1
                while byteIndex < newbyteIndex:
                    mask += b"\0"
                    byteIndex += 1
                maskVal = 0
            maskVal += 2**(7 - (i % 8))

        if maskVal:
            mask += bytechr(maskVal)

        if len(mask) < byteLength:
            mask += b"\0" * (byteLength - len(mask))
        self.mask = mask
        return mask
Ejemplo n.º 5
0
 def compile(self, ttFont):
     self.version = 0
     numGlyphs = ttFont['maxp'].numGlyphs
     glyphOrder = ttFont.getGlyphOrder()
     self.recordSize = 4 * ((2 + numGlyphs + 3) // 4)
     pad = (self.recordSize - 2 - numGlyphs) * b"\0"
     self.numRecords = len(self.hdmx)
     data = sstruct.pack(hdmxHeaderFormat, self)
     items = sorted(self.hdmx.items())
     for ppem, widths in items:
         data = data + bytechr(ppem) + bytechr(max(widths.values()))
         for glyphID in range(len(glyphOrder)):
             width = widths[glyphOrder[glyphID]]
             data = data + bytechr(width)
         data = data + pad
     return data
Ejemplo 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 = strToFixedToFloat(token, precisionBits=16)
             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)
Ejemplo n.º 7
0
	def encodeDeltaRunAsBytes_(deltas, offset, stream):
		runLength = 0
		pos = offset
		numDeltas = len(deltas)
		while pos < numDeltas and runLength < 64:
			value = deltas[pos]
			if value < -128 or value > 127:
				break
			# Within a byte-encoded run of deltas, a single zero
			# is best stored literally as 0x00 value. However,
			# if are two or more zeroes in a sequence, it is
			# better to start a new run. For example, the sequence
			# of deltas [15, 15, 0, 15, 15] becomes 6 bytes
			# (04 0F 0F 00 0F 0F) when storing the zero value
			# literally, but 7 bytes (01 0F 0F 80 01 0F 0F)
			# when starting a new run.
			if value == 0 and pos+1 < numDeltas and deltas[pos+1] == 0:
				break
			pos += 1
			runLength += 1
		assert runLength >= 1 and runLength <= 64
		stream.write(bytechr(runLength - 1))
		for i in range(offset, pos):
			stream.write(struct.pack('b', otRound(deltas[i])))
		return pos
Ejemplo n.º 8
0
	def encodeDeltaRunAsWords_(deltas, offset, stream):
		runLength = 0
		pos = offset
		numDeltas = len(deltas)
		while pos < numDeltas and runLength < 64:
			value = deltas[pos]
			# Within a word-encoded run of deltas, it is easiest
			# to start a new run (with a different encoding)
			# whenever we encounter a zero value. For example,
			# the sequence [0x6666, 0, 0x7777] needs 7 bytes when
			# storing the zero literally (42 66 66 00 00 77 77),
			# and equally 7 bytes when starting a new run
			# (40 66 66 80 40 77 77).
			if value == 0:
				break

			# Within a word-encoded run of deltas, a single value
			# in the range (-128..127) should be encoded literally
			# because it is more compact. For example, the sequence
			# [0x6666, 2, 0x7777] becomes 7 bytes when storing
			# the value literally (42 66 66 00 02 77 77), but 8 bytes
			# when starting a new run (40 66 66 00 02 40 77 77).
			isByteEncodable = lambda value: value >= -128 and value <= 127
			if isByteEncodable(value) and pos+1 < numDeltas and isByteEncodable(deltas[pos+1]):
				break
			pos += 1
			runLength += 1
		assert runLength >= 1 and runLength <= 64
		stream.write(bytechr(DELTAS_ARE_WORDS | (runLength - 1)))
		for i in range(offset, pos):
			stream.write(struct.pack('>h', otRound(deltas[i])))
		return pos
Ejemplo n.º 9
0
	def maskByte(self, hHints, vHints):
		# return hintmask bytes for known hints.
		numHHints = len(hHints)
		numVHints = len(vHints)
		maskVal = 0
		byteIndex = 0
		self.byteLength = byteLength = int((7 + numHHints + numVHints)/8)
		mask = b""
		self.hList.sort()
		for hint in self.hList:
			try:
				i = hHints.index(hint)
			except ValueError:
				continue	# we get here if some hints have been dropped because of the stack limit
			newbyteIndex = (i//8)
			if newbyteIndex != byteIndex:
				mask += bytechr(maskVal)
				byteIndex +=1
				while byteIndex < newbyteIndex:
					mask += b"\0"
					byteIndex +=1
				maskVal = 0
			maskVal += 2**(7 - (i %8))

		self.vList.sort()
		for hint in self.vList:
			try:
				i = numHHints + vHints.index(hint)
			except ValueError:
				continue	# we get here if some hints have been dropped because of the stack limit
			newbyteIndex = (i//8)
			if newbyteIndex != byteIndex:
				mask += bytechr(maskVal)
				byteIndex +=1
				while byteIndex < newbyteIndex:
					mask += b"\0"
					byteIndex +=1
				maskVal = 0
			maskVal += 2**(7 - (i %8))

		if maskVal:
			mask += bytechr(maskVal)

		if len(mask) < byteLength:
			mask += b"\0"*(byteLength - len(mask))
		self.mask = mask
		return mask
Ejemplo n.º 10
0
    def toUnicode(self, errors='strict'):
        """
		If self.string is a Unicode string, return it; otherwise try decoding the
		bytes in self.string to a Unicode string using the encoding of this
		entry as returned by self.getEncoding(); Note that  self.getEncoding()
		returns 'ascii' if the encoding is unknown to the library.

		Certain heuristics are performed to recover data from bytes that are
		ill-formed in the chosen encoding, or that otherwise look misencoded
		(mostly around bad UTF-16BE encoded bytes, or bytes that look like UTF-16BE
		but marked otherwise).  If the bytes are ill-formed and the heuristics fail,
		the error is handled according to the errors parameter to this function, which is
		passed to the underlying decode() function; by default it throws a
		UnicodeDecodeError exception.

		Note: The mentioned heuristics mean that roundtripping a font to XML and back
		to binary might recover some misencoded data whereas just loading the font
		and saving it back will not change them.
		"""
        def isascii(b):
            return (b >= 0x20 and b <= 0x7E) or b in [0x09, 0x0A, 0x0D]

        encoding = self.getEncoding()
        string = self.string

        if isinstance(
                string,
                bytes) and encoding == 'utf_16_be' and len(string) % 2 == 1:
            # Recover badly encoded UTF-16 strings that have an odd number of bytes:
            # - If the last byte is zero, drop it.  Otherwise,
            # - If all the odd bytes are zero and all the even bytes are ASCII,
            #   prepend one zero byte.  Otherwise,
            # - If first byte is zero and all other bytes are ASCII, insert zero
            #   bytes between consecutive ASCII bytes.
            #
            # (Yes, I've seen all of these in the wild... sigh)
            if byteord(string[-1]) == 0:
                string = string[:-1]
            elif all(
                    byteord(b) == 0 if i % 2 else isascii(byteord(b))
                    for i, b in enumerate(string)):
                string = b'\0' + string
            elif byteord(string[0]) == 0 and all(
                    isascii(byteord(b)) for b in string[1:]):
                string = bytesjoin(b'\0' + bytechr(byteord(b))
                                   for b in string[1:])

        string = tostr(string, encoding=encoding, errors=errors)

        # If decoded strings still looks like UTF-16BE, it suggests a double-encoding.
        # Fix it up.
        if all(
                ord(c) == 0 if i % 2 == 0 else isascii(ord(c))
                for i, c in enumerate(string)):
            # If string claims to be Mac encoding, but looks like UTF-16BE with ASCII text,
            # narrow it down.
            string = ''.join(c for c in string[1::2])

        return string
Ejemplo n.º 11
0
	def compilePoints(points, numPointsInGlyph):
		# If the set consists of all points in the glyph, it gets encoded with
		# a special encoding: a single zero byte.
		if len(points) == numPointsInGlyph:
			return b"\0"

		# In the 'gvar' table, the packing of point numbers is a little surprising.
		# It consists of multiple runs, each being a delta-encoded list of integers.
		# For example, the point set {17, 18, 19, 20, 21, 22, 23} gets encoded as
		# [6, 17, 1, 1, 1, 1, 1, 1]. The first value (6) is the run length minus 1.
		# There are two types of runs, with values being either 8 or 16 bit unsigned
		# integers.
		points = list(points)
		points.sort()
		numPoints = len(points)

		# The binary representation starts with the total number of points in the set,
		# encoded into one or two bytes depending on the value.
		if numPoints < 0x80:
			result = [bytechr(numPoints)]
		else:
			result = [bytechr((numPoints >> 8) | 0x80) + bytechr(numPoints & 0xff)]

		MAX_RUN_LENGTH = 127
		pos = 0
		lastValue = 0
		while pos < numPoints:
			run = io.BytesIO()
			runLength = 0
			useByteEncoding = None
			while pos < numPoints and runLength <= MAX_RUN_LENGTH:
				curValue = points[pos]
				delta = curValue - lastValue
				if useByteEncoding is None:
					useByteEncoding = 0 <= delta <= 0xff
				if useByteEncoding and (delta > 0xff or delta < 0):
					# we need to start a new run (which will not use byte encoding)
					break
				# TODO This never switches back to a byte-encoding from a short-encoding.
				# That's suboptimal.
				if useByteEncoding:
					run.write(bytechr(delta))
				else:
					run.write(bytechr(delta >> 8))
					run.write(bytechr(delta & 0xff))
				lastValue = curValue
				pos += 1
				runLength += 1
			if useByteEncoding:
				runHeader = bytechr(runLength - 1)
			else:
				runHeader = bytechr((runLength - 1) | POINTS_ARE_WORDS)
			result.append(runHeader)
			result.append(run.getvalue())

		return bytesjoin(result)
Ejemplo n.º 12
0
	def toString(self):
		data = bytechr(self.flags)
		if (self.flags & 0x3F) == 0x3F:
			data += struct.pack('>4s', self.tag.tobytes())
		data += packBase128(self.origLength)
		if self.transformed:
			data += packBase128(self.length)
		return data
Ejemplo n.º 13
0
 def encodeInt(value,
               fourByteOp=fourByteOp,
               bytechr=bytechr,
               pack=struct.pack,
               unpack=struct.unpack):
     if -107 <= value <= 107:
         code = bytechr(value + 139)
     elif 108 <= value <= 1131:
         value = value - 108
         code = bytechr((value >> 8) + 247) + bytechr(value & 0xFF)
     elif -1131 <= value <= -108:
         value = -value - 108
         code = bytechr((value >> 8) + 251) + bytechr(value & 0xFF)
     elif fourByteOp is None:
         # T2 only supports 2 byte ints
         if -32768 <= value <= 32767:
             code = bytechr(28) + pack(">h", value)
         else:
             # Backwards compatible hack: due to a previous bug in FontTools,
             # 16.16 fixed numbers were written out as 4-byte ints. When
             # these numbers were small, they were wrongly written back as
             # small ints instead of 4-byte ints, breaking round-tripping.
             # This here workaround doesn't do it any better, since we can't
             # distinguish anymore between small ints that were supposed to
             # be small fixed numbers and small ints that were just small
             # ints. Hence the warning.
             log.warning(
                 "4-byte T2 number got passed to the "
                 "IntType handler. This should happen only when reading in "
                 "old XML files.\n")
             code = bytechr(255) + pack(">l", value)
     else:
         code = fourByteOp + pack(">l", value)
     return code
Ejemplo n.º 14
0
def deHexStr(hexdata):
	"""Convert a hex string to binary data."""
	hexdata = strjoin(hexdata.split())
	if len(hexdata) % 2:
		hexdata = hexdata + "0"
	data = []
	for i in range(0, len(hexdata), 2):
		data.append(bytechr(int(hexdata[i:i+2], 16)))
	return bytesjoin(data)
Ejemplo n.º 15
0
 def test_unsupportedLookupType(self):
     data = bytesjoin([
         MORX_NONCONTEXTUAL_DATA[:67],
         bytechr(66), MORX_NONCONTEXTUAL_DATA[69:]
     ])
     with self.assertRaisesRegex(AssertionError,
                                 r"unsupported 'morx' lookup type 66"):
         morx = newTable('morx')
         morx.decompile(data, FakeFont(['.notdef']))
Ejemplo n.º 16
0
def _reverseBytes(data):
    if len(data) != 1:
        return bytesjoin(map(_reverseBytes, data))
    byte = byteord(data)
    result = 0
    for i in range(8):
        result = result << 1
        result |= byte & 1
        byte = byte >> 1
    return bytechr(result)
Ejemplo n.º 17
0
	def encodeDeltaRunAsZeroes_(deltas, offset, stream):
		runLength = 0
		pos = offset
		numDeltas = len(deltas)
		while pos < numDeltas and runLength < 64 and deltas[pos] == 0:
			pos += 1
			runLength += 1
		assert runLength >= 1 and runLength <= 64
		stream.write(bytechr(DELTAS_ARE_ZERO | (runLength - 1)))
		return pos
Ejemplo n.º 18
0
def _binary2data(binary):
    byteList = []
    for bitLoc in range(0, len(binary), 8):
        byteString = binary[bitLoc:bitLoc + 8]
        curByte = 0
        for curBit in reversed(byteString):
            curByte = curByte << 1
            if curBit == '1':
                curByte |= 1
        byteList.append(bytechr(curByte))
    return bytesjoin(byteList)
Ejemplo n.º 19
0
    def getnexttoken(
            self,
            # localize some stuff, for performance
            len=len,
            ps_special=ps_special,
            stringmatch=stringRE.match,
            hexstringmatch=hexstringRE.match,
            commentmatch=commentRE.match,
            endmatch=endofthingRE.match):

        self.skipwhite()
        if self.pos >= self.len:
            return None, None
        pos = self.pos
        buf = self.buf
        char = bytechr(byteord(buf[pos]))
        if char in ps_special:
            if char in b'{}[]':
                tokentype = 'do_special'
                token = char
            elif char == b'%':
                tokentype = 'do_comment'
                _, nextpos = commentmatch(buf, pos).span()
                token = buf[pos:nextpos]
            elif char == b'(':
                tokentype = 'do_string'
                m = stringmatch(buf, pos)
                if m is None:
                    raise PSTokenError('bad string at character %d' % pos)
                _, nextpos = m.span()
                token = buf[pos:nextpos]
            elif char == b'<':
                tokentype = 'do_hexstring'
                m = hexstringmatch(buf, pos)
                if m is None:
                    raise PSTokenError('bad hexstring at character %d' % pos)
                _, nextpos = m.span()
                token = buf[pos:nextpos]
            else:
                raise PSTokenError('bad token at character %d' % pos)
        else:
            if char == b'/':
                tokentype = 'do_literal'
                m = endmatch(buf, pos + 1)
            else:
                tokentype = ''
                m = endmatch(buf, pos)
            if m is None:
                raise PSTokenError('bad token at character %d' % pos)
            _, nextpos = m.span()
            token = buf[pos:nextpos]
        self.pos = pos + len(token)
        token = tostr(token, encoding=self.encoding)
        return tokentype, token
Ejemplo n.º 20
0
 def test_ReservedCoverageFlags(self):
     # 8A BC DE = TextDirection=Vertical, Reserved=0xABCDE
     # Note that the lower 4 bits of the first byte are already
     # part of the Reserved value. We test the full round-trip
     # to encoding and decoding is quite hairy.
     data = bytesjoin([
         MORX_REARRANGEMENT_DATA[:28],
         bytechr(0x8A),
         bytechr(0xBC),
         bytechr(0xDE), MORX_REARRANGEMENT_DATA[31:]
     ])
     table = newTable('morx')
     table.decompile(data, self.font)
     subtable = table.table.MorphChain[0].MorphSubtable[0]
     self.assertEqual(subtable.Reserved, 0xABCDE)
     xml = getXML(table.toXML)
     self.assertIn('    <Reserved value="0xabcde"/>', xml)
     table2 = newTable('morx')
     for name, attrs, content in parseXML(xml):
         table2.fromXML(name, attrs, content, font=self.font)
     self.assertEqual(hexStr(table2.compile(self.font)[28:31]), "8abcde")
Ejemplo n.º 21
0
def writeLWFN(path, data):
    # Res.FSpCreateResFile was deprecated in OS X 10.5
    Res.FSpCreateResFile(path, "just", "LWFN", 0)
    resRef = Res.FSOpenResFile(path, 2)  # write-only
    try:
        Res.UseResFile(resRef)
        resID = 501
        chunks = findEncryptedChunks(data)
        for isEncrypted, chunk in chunks:
            if isEncrypted:
                code = 2
            else:
                code = 1
            while chunk:
                res = Res.Resource(
                    bytechr(code) + '\0' + chunk[:LWFNCHUNKSIZE - 2])
                res.AddResource('POST', resID, '')
                chunk = chunk[LWFNCHUNKSIZE - 2:]
                resID = resID + 1
        res = Res.Resource(bytechr(5) + '\0')
        res.AddResource('POST', resID, '')
    finally:
        Res.CloseResFile(resRef)
Ejemplo n.º 22
0
    def getRow(self, row, bitDepth=1, metrics=None, reverseBytes=False):
        if metrics is None:
            metrics = self.metrics
        assert 0 <= row and row < metrics.height, "Illegal row access in bitmap"

        # Loop through each byte. This can cover two bytes in the original data or
        # a single byte if things happen to be aligned. The very last entry might
        # not be aligned so take care to trim the binary data to size and pad with
        # zeros in the row data. Bit aligned data is somewhat tricky.
        #
        # Example of data cut. Data cut represented in x's.
        # '|' represents byte boundary.
        # data = ...0XX|XXXXXX00|000... => XXXXXXXX
        #		or
        # data = ...0XX|XXXX0000|000... => XXXXXX00
        #   or
        # data = ...000|XXXXXXXX|000... => XXXXXXXX
        #   or
        # data = ...000|00XXXX00|000... => XXXX0000
        #
        dataList = []
        bitRange = self._getBitRange(row, bitDepth, metrics)
        stepRange = bitRange + (8, )
        for curBit in range(*stepRange):
            endBit = min(curBit + 8, bitRange[1])
            numBits = endBit - curBit
            cutPoint = curBit % 8
            firstByteLoc = curBit // 8
            secondByteLoc = endBit // 8
            if firstByteLoc < secondByteLoc:
                numBitsCut = 8 - cutPoint
            else:
                numBitsCut = endBit - curBit
            curByte = _reverseBytes(self.imageData[firstByteLoc])
            firstHalf = byteord(curByte) >> cutPoint
            firstHalf = ((1 << numBitsCut) - 1) & firstHalf
            newByte = firstHalf
            if firstByteLoc < secondByteLoc and secondByteLoc < len(
                    self.imageData):
                curByte = _reverseBytes(self.imageData[secondByteLoc])
                secondHalf = byteord(curByte) << numBitsCut
                newByte = (firstHalf | secondHalf) & ((1 << numBits) - 1)
            dataList.append(bytechr(newByte))

        # The way the data is kept is opposite the algorithm used.
        data = bytesjoin(dataList)
        if not reverseBytes:
            data = _reverseBytes(data)
        return data
Ejemplo n.º 23
0
    def compile(self, isCFF2=False):
        if self.bytecode is not None:
            return
        opcodes = self.opcodes
        program = self.program

        if isCFF2:
            # If present, remove return and endchar operators.
            if program and program[-1] in ("return", "endchar"):
                program = program[:-1]
        elif program and not isinstance(program[-1], str):
            raise CharStringCompileError(
                "T2CharString or Subr has items on the stack after last operator."
            )

        bytecode = []
        encodeInt = self.getIntEncoder()
        encodeFixed = self.getFixedEncoder()
        i = 0
        end = len(program)
        while i < end:
            token = program[i]
            i = i + 1
            if isinstance(token, str):
                try:
                    bytecode.extend(bytechr(b) for b in 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 isinstance(token, int):
                bytecode.append(encodeInt(token))
            elif isinstance(token, float):
                bytecode.append(encodeFixed(token))
            else:
                assert 0, "unsupported type: %s" % type(token)
        try:
            bytecode = bytesjoin(bytecode)
        except TypeError:
            log.error(bytecode)
            raise
        self.setBytecode(bytecode)
Ejemplo n.º 24
0
def  bezDecrypt(bezDataBuffer):
	r = 11586
	i = 0 # input buffer byte position index
	lenBuffer = len(bezDataBuffer)
	byteCnt = 0 # output buffer byte count.
	newBuffer = ""
	while 1:
		cipher = 0 # restricted to int
		plain = 0 # restricted to int
		j = 2 # used to combine two successive bytes

		# process next two bytes, skipping whitespace.
		while j > 0:
			j -=1
			try:
				while  bezDataBuffer[i].isspace():
					i +=1
				ch = bezDataBuffer[i]
			except IndexError:
				return newBuffer

			if not ch.islower():
				ch = ch.lower()
			if ch.isdigit():
				ch = byteord(ch) - byteord('0')
			else:
				ch = byteord(ch) - byteord('a') + 10
			cipher = (cipher << 4) & 0xFFFF
			cipher = cipher | ch
			i += 1

		plain = cipher ^ (r >> 8)
		r = (cipher + r) * 902381661 + 341529579
		if r  > 0xFFFF:
			r = r & 0xFFFF
		byteCnt +=1
		if (byteCnt > LEN_IV):
			newBuffer += bytechr(plain)
		if i >= lenBuffer:
			break

	return newBuffer
Ejemplo n.º 25
0
    def maskByte(self, hHints, vHints):
        # return hintmask bytes for known hints.
        num_hhints = len(hHints)
        num_vhints = len(vHints)
        self.byteLength = byteLength = int((7 + num_hhints + num_vhints) / 8)
        maskVal = 0
        byteIndex = 0
        mask = b""
        if self.h_list:
            mask, maskVal, byteIndex = self.addMaskBits(
                hHints, self.h_list, 0, mask, maskVal, byteIndex)
        if self.v_list:
            mask, maskVal, byteIndex = self.addMaskBits(
                vHints, self.v_list, num_hhints, mask, maskVal, byteIndex)

        if maskVal:
            mask += bytechr(maskVal)

        if len(mask) < byteLength:
            mask += b"\0" * (byteLength - len(mask))
        self.mask = mask
        return mask
Ejemplo n.º 26
0
def readPFB(path, onlyHeader=False):
    """reads a PFB font file, returns raw data"""
    data = []
    with open(path, "rb") as f:
        while True:
            if f.read(1) != bytechr(128):
                raise T1Error('corrupt PFB file')
            code = byteord(f.read(1))
            if code in [1, 2]:
                chunklen = stringToLong(f.read(4))
                chunk = f.read(chunklen)
                assert len(chunk) == chunklen
                data.append(chunk)
            elif code == 3:
                break
            else:
                raise T1Error('bad chunk code: ' + repr(code))
            if onlyHeader:
                break
    data = bytesjoin(data)
    assertType1(data)
    return data
Ejemplo n.º 27
0
    def addMaskBits(allHints, maskHints, numPriorHints, mask, maskVal,
                    byteIndex):
        # sort in allhints order.
        sort_list = [[allHints.index(hint) + numPriorHints, hint]
                     for hint in maskHints if hint in allHints]
        if not sort_list:
            # we get here if some hints have been dropped # because of
            # the stack limit, so that none of the items in maskHints are
            # not in allHints
            return mask, maskVal, byteIndex

        sort_list.sort()
        (idx_list, maskHints) = zip(*sort_list)
        for i in idx_list:
            newbyteIndex = int(i / 8)
            if newbyteIndex != byteIndex:
                mask += bytechr(maskVal)
                byteIndex += 1
                while byteIndex < newbyteIndex:
                    mask += b"\0"
                    byteIndex += 1
                maskVal = 0
            maskVal += 2**(7 - (i % 8))
        return mask, maskVal, byteIndex
Ejemplo n.º 28
0
 def checkFlags(self,
                flags,
                textDirection,
                processingOrder,
                checkCompile=True):
     data = bytesjoin([
         MORX_REARRANGEMENT_DATA[:28],
         bytechr(flags << 4), MORX_REARRANGEMENT_DATA[29:]
     ])
     xml = []
     for line in MORX_REARRANGEMENT_XML:
         if line.startswith('    <TextDirection '):
             line = '    <TextDirection value="%s"/>' % textDirection
         elif line.startswith('    <ProcessingOrder '):
             line = '    <ProcessingOrder value="%s"/>' % processingOrder
         xml.append(line)
     table1 = newTable('morx')
     table1.decompile(data, self.font)
     self.assertEqual(getXML(table1.toXML), xml)
     if checkCompile:
         table2 = newTable('morx')
         for name, attrs, content in parseXML(xml):
             table2.fromXML(name, attrs, content, font=self.font)
         self.assertEqual(hexStr(table2.compile(self.font)), hexStr(data))
Ejemplo n.º 29
0
def _encryptChar(plain, R):
    plain = byteord(plain)
    cipher = ((plain ^ (R >> 8))) & 0xFF
    R = ((cipher + R) * 52845 + 22719) & 0xFFFF
    return bytechr(cipher), R
Ejemplo n.º 30
0
def _decryptChar(cipher, R):
    cipher = byteord(cipher)
    plain = ((cipher ^ (R >> 8))) & 0xFF
    R = ((cipher + R) * 52845 + 22719) & 0xFFFF
    return bytechr(plain), R
Ejemplo n.º 31
0
def packPStrings(strings):
    data = b""
    for s in strings:
        data = data + bytechr(len(s)) + tobytes(s, encoding="latin1")
    return data
Ejemplo n.º 32
0
def longToString(long):
    s = b""
    for i in range(4):
        s += bytechr((long & (0xff << (i * 8))) >> i * 8)
    return s