def test_decode_utf8(self): class DebugXMLReader(XMLReader): def __init__(self, fileOrPath, ttFont, progress=None): super(DebugXMLReader, self).__init__( fileOrPath, ttFont, progress) self.contents = [] def _endElementHandler(self, name): if self.stackSize == 3: name, attrs, content = self.root self.contents.append(content) super(DebugXMLReader, self)._endElementHandler(name) expected = 'fôôbär' data = '''\ <?xml version="1.0" encoding="UTF-8"?> <ttFont> <name> <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> %s </namerecord> </name> </ttFont> ''' % expected with BytesIO(data.encode('utf-8')) as tmp: reader = DebugXMLReader(tmp, TTFont()) reader.read() content = strjoin(reader.contents[0]).strip() self.assertEqual(expected, content)
def _writeBitwiseImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont): metrics = bitmapObject.exportMetrics del bitmapObject.exportMetrics bitDepth = bitmapObject.exportBitDepth del bitmapObject.exportBitDepth # A dict for mapping binary to more readable/artistic ASCII characters. binaryConv = {'0': '.', '1': '@'} writer.begintag('bitwiseimagedata', bitDepth=bitDepth, width=metrics.width, height=metrics.height) writer.newline() for curRow in range(metrics.height): rowData = bitmapObject.getRow(curRow, bitDepth=1, metrics=metrics, reverseBytes=True) rowData = _data2binary(rowData, metrics.width) # Make the output a readable ASCII art form. rowData = strjoin(map(binaryConv.get, rowData)) writer.simpletag('row', value=rowData) writer.newline() writer.endtag('bitwiseimagedata') writer.newline()
def fromXML(self, name, attrs, content, ttFont): if name == "hexdata": self.data[attrs["tag"]] = readHex(content) elif name == "text" and attrs["tag"] in ["dlng", "slng"]: self.data[attrs["tag"]] = strjoin(content).strip() else: raise TTLibError("can't handle '%s' element" % name)
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)
def binary2num(bin): bin = strjoin(bin.split()) l = 0 for digit in bin: l = l << 1 if digit != "0": l = l | 0x1 return l
def fromXML(self, name, attrs, content, ttFont): if name == "assembly": self.fromAssembly(strjoin(content)) self._assemble() del self.assembly else: assert name == "bytecode" self.fromBytecode(readHex(content))
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)
def b64encode(b): s = base64.b64encode(b) # Line-break at 76 chars. items = [] while s: items.append(tostr(s[:76])) items.append('\n') s = s[76:] return strjoin(items)
def escape8bit(data): """Input is Unicode string.""" def escapechar(c): n = ord(c) if 32 <= n <= 127 and c not in "<&>": return c else: return "&#" + repr(n) + ";" return strjoin(map(escapechar, data.decode('latin-1')))
def fromXML(self, name, attrs, content, ttFont): if not hasattr(self, "glyphPrograms"): self.glyphPrograms = {} self.extraPrograms = {} lines = strjoin(content).replace("\r", "\n").split("\n") text = '\r'.join(lines[1:-1]) if name == "glyphProgram": self.glyphPrograms[attrs["name"]] = text elif name == "extraProgram": self.extraPrograms[attrs["name"]] = text
def toXML(self, writer, ttFont): data = tostr(self.data) # removing null bytes. XXX needed?? data = data.split('\0') data = strjoin(data) writer.begintag("source") writer.newline() writer.write_noindent(data) writer.newline() writer.endtag("source") writer.newline()
def fromXML(self, name, attrs, content, ttFont): self.nameID = safeEval(attrs["nameID"]) self.platformID = safeEval(attrs["platformID"]) self.platEncID = safeEval(attrs["platEncID"]) self.langID = safeEval(attrs["langID"]) s = strjoin(content).strip() encoding = self.getEncoding() if self.encodingIsUnicodeCompatible() or safeEval( attrs.get("unicode", "False")): self.string = s.encode(encoding) else: # This is the inverse of write8bit... self.string = s.encode("latin1")
def _data2binary(data, numBits): binaryList = [] for curByte in data: value = byteord(curByte) numBitsCut = min(8, numBits) for i in range(numBitsCut): if value & 0x1: binaryList.append('1') else: binaryList.append('0') value = value >> 1 numBits -= numBitsCut return strjoin(binaryList)
def fromXML(self, name, attrs, content, ttFont): if name == "svgDoc": if not hasattr(self, "docList"): self.docList = [] doc = strjoin(content) doc = doc.strip() startGID = int(attrs["startGlyphID"]) endGID = int(attrs["endGlyphID"]) self.docList.append( [doc, startGID, endGID] ) elif name == "colorPalettes": self.colorPalettes = ColorPalettes() self.colorPalettes.fromXML(name, attrs, content, ttFont) if self.colorPalettes.numColorParams == 0: self.colorPalettes = None else: log.warning("Unknown %s %s", name, content)
def fromXML(self, name, attrs, content, ttFont): if name != "hdmxData": return content = strjoin(content) lines = content.split(";") topRow = lines[0].split() assert topRow[0] == "ppem:", "illegal hdmx format" ppems = list(map(int, topRow[1:])) self.hdmx = hdmx = {} for ppem in ppems: hdmx[ppem] = {} lines = (line.split() for line in lines[1:]) for line in lines: if not line: continue assert line[0][-1] == ":", "illegal hdmx format" glyphName = line[0][:-1] if "\\" in glyphName: from fontTools.misc.textTools import safeEval glyphName = safeEval('"""' + glyphName + '"""') line = list(map(int, line[1:])) assert len(line) == len(ppems), "illegal hdmx format" for i in range(len(ppems)): hdmx[ppems[i]][glyphName] = line[i]
def _readBitwiseImageData(bitmapObject, name, attrs, content, ttFont): bitDepth = safeEval(attrs['bitDepth']) metrics = SmallGlyphMetrics() metrics.width = safeEval(attrs['width']) metrics.height = safeEval(attrs['height']) # A dict for mapping from ASCII to binary. All characters are considered # a '1' except space, period and '0' which maps to '0'. binaryConv = {' ': '0', '.': '0', '0': '0'} dataRows = [] for element in content: if not isinstance(element, tuple): continue name, attr, content = element if name == 'row': mapParams = zip(attr['value'], itertools.repeat('1')) rowData = strjoin(itertools.starmap(binaryConv.get, mapParams)) dataRows.append(_binary2data(rowData)) bitmapObject.setRows(dataRows, bitDepth=bitDepth, metrics=metrics, reverseBytes=True)
def toXML(self, xmlWriter, ttFont=None): from fontTools.misc.textTools import num2binary if self.bytecode is not None: xmlWriter.dumphex(self.bytecode) else: index = 0 args = [] while True: token, isOperator, index = self.getToken(index) if token is None: break if isOperator: if token in ('hintmask', 'cntrmask'): hintMask, isOperator, index = self.getToken(index) bits = [] for byte in hintMask: bits.append(num2binary(byteord(byte), 8)) hintMask = strjoin(bits) line = ' '.join(args + [token, hintMask]) else: line = ' '.join(args + [token]) xmlWriter.write(line) xmlWriter.newline() args = [] else: if isinstance(token, float): token = floatToFixedToStr(token, precisionBits=16) else: token = str(token) args.append(token) if args: # NOTE: only CFF2 charstrings/subrs can have numeric arguments on # the stack after the last operator. Compiling this would fail if # this is part of CFF 1.0 table. line = ' '.join(args) xmlWriter.write(line)
def _reverseString(s): s = list(s) s.reverse() return strjoin(s)
def fromXML(self, name, attrs, content, ttFont): self.ulFormat = safeEval(attrs["format"]) self.usReserved1 = safeEval(attrs.get("reserved1", "0")) self.usReserved2 = safeEval(attrs.get("reserved2", "0")) self.pkcs7 = base64.b64decode( tobytes(strjoin(filter(pem_spam, content))))
def readHex(content): """Convert a list of hex strings to binary data.""" return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, str)))
def fromXML(self, name, attrs, content, ttFont): lines = strjoin(content).split("\n") self.data = tobytes("\n".join(lines[1:-1]))