def writeGlyphToString(glyphName, glyphObject=None, drawPointsFunc=None, writer=None): """Return .glif data for a glyph as a UTF-8 encoded string. The 'glyphObject' argument can be any kind of object (even None); the writeGlyphToString() method will attempt to get the following attributes from it: "width" the advance with of the glyph "unicodes" a list of unicode values for this glyph "note" a string "lib" a dictionary containing custom data All attributes are optional: if 'glyphObject' doesn't have the attribute, it will simply be skipped. To write outline data to the .glif file, writeGlyphToString() needs a function (any callable object actually) that will take one argument: an object that conforms to the PointPen protocol. The function will be called by writeGlyphToString(); it has to call the proper PointPen methods to transfer the outline to the .glif file. """ if writer is None: try: from xmlWriter import XMLWriter except ImportError: # try the other location from fontTools.misc.xmlWriter import XMLWriter aFile = StringIO() writer = XMLWriter(aFile, encoding="UTF-8") else: aFile = None writer.begintag("glyph", [("name", glyphName), ("format", "1")]) writer.newline() width = getattr(glyphObject, "width", None) if width is not None: if not isinstance(width, (int, float)): raise GlifLibError, "width attribute must be int or float" writer.simpletag("advance", width=repr(width)) writer.newline() unicodes = getattr(glyphObject, "unicodes", None) if unicodes: if isinstance(unicodes, int): unicodes = [unicodes] for code in unicodes: if not isinstance(code, int): raise GlifLibError, "unicode values must be int" hexCode = hex(code)[2:].upper() if len(hexCode) < 4: hexCode = "0" * (4 - len(hexCode)) + hexCode writer.simpletag("unicode", hex=hexCode) writer.newline() note = getattr(glyphObject, "note", None) if note is not None: if not isinstance(note, (str, unicode)): raise GlifLibError, "note attribute must be str or unicode" note = note.encode('utf-8') writer.begintag("note") writer.newline() for line in note.splitlines(): writer.write(line.strip()) writer.newline() writer.endtag("note") writer.newline() if drawPointsFunc is not None: writer.begintag("outline") writer.newline() pen = GLIFPointPen(writer) drawPointsFunc(pen) writer.endtag("outline") writer.newline() lib = getattr(glyphObject, "lib", None) if lib: from robofab.plistlib import PlistWriter if not isinstance(lib, dict): lib = dict(lib) writer.begintag("lib") writer.newline() plistWriter = PlistWriter(writer.file, indentLevel=writer.indentlevel, indent=writer.indentwhite, writeHeader=False) plistWriter.writeValue(lib) writer.endtag("lib") writer.newline() writer.endtag("glyph") writer.newline() if aFile is not None: return aFile.getvalue() else: return None