From da875fcb62c801b8d19b3d4d984ad963574fb356 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 2 Mar 2023 21:01:10 +0100 Subject: Adding upstream version 1.6.0. Signed-off-by: Daniel Baumann --- lib/silfont/ipython.py | 135 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 lib/silfont/ipython.py (limited to 'lib/silfont/ipython.py') diff --git a/lib/silfont/ipython.py b/lib/silfont/ipython.py new file mode 100644 index 0000000..150aa97 --- /dev/null +++ b/lib/silfont/ipython.py @@ -0,0 +1,135 @@ +#!/usr/bin/python +'IPython support for fonttools' + +__all__ = ['displayGlyphs', 'loadFont', 'displayText', 'displayRaw'] + +from fontTools import ttLib +from fontTools.pens.basePen import BasePen +from fontTools.misc import arrayTools +from IPython.display import SVG, HTML +from defcon import Font +from ufo2ft import compileTTF + +class SVGPen(BasePen) : + + def __init__(self, glyphSet, scale=1.0) : + super(SVGPen, self).__init__(glyphSet); + self.__commands = [] + self.__scale = scale + + def __str__(self) : + return " ".join(self.__commands) + + def scale(self, pt) : + return ((pt[0] or 0) * self.__scale, (pt[1] or 0) * self.__scale) + + def _moveTo(self, pt): + self.__commands.append("M {0[0]} {0[1]}".format(self.scale(pt))) + + def _lineTo(self, pt): + self.__commands.append("L {0[0]} {0[1]}".format(self.scale(pt))) + + def _curveToOne(self, pt1, pt2, pt3) : + self.__commands.append("C {0[0]} {0[1]} {1[0]} {1[1]} {2[0]} {2[1]}".format(self.scale(pt1), self.scale(pt2), self.scale(pt3))) + + def _closePath(self) : + self.__commands.append("Z") + + def clear(self) : + self.__commands = [] + +def _svgheader(): + return ''' + +''' + +def _bbox(f, gnames, points, scale=1): + gset = f.glyphSet + bbox = (0, 0, 0, 0) + for i, gname in enumerate(gnames): + if hasattr(points, '__len__') and i == len(points): + points.append((bbox[2] / scale, 0)) + pt = points[i] if i < len(points) else (0, 0) + g = gset[gname]._glyph + if g is None or not hasattr(g, 'xMin') : + gbox = (0, 0, 0, 0) + else : + gbox = (g.xMin * scale, g.yMin * scale, g.xMax * scale, g.yMax * scale) + bbox = arrayTools.unionRect(bbox, arrayTools.offsetRect(gbox, pt[0] * scale, pt[1] * scale)) + return bbox + +glyphsetcount = 0 +def _defglyphs(f, gnames, scale=1): + global glyphsetcount + glyphsetcount += 1 + gset = f.glyphSet + p = SVGPen(gset, scale) + res = "\n" + for gname in sorted(set(gnames)): + res += '\n'.format(gname, glyphsetcount) + g = gset[gname] + p.clear() + g.draw(p) + res += '\n\n' + res += "\n" + return res + +def loadFont(fname): + if fname.lower().endswith(".ufo"): + ufo = Font(fname) + f = compileTTF(ufo) + else: + f = ttLib.TTFont(fname) + return f + +def displayGlyphs(f, gnames, points=None, scale=None): + if not hasattr(gnames, '__len__') or isinstance(gnames, basestring): + gnames = [gnames] + if not hasattr(points, '__len__'): + points = [] + if not hasattr(f, 'glyphSet'): + f.glyphSet = f.getGlyphSet() + res = _svgheader() + if points is None: + points = [] + bbox = _bbox(f, gnames, points, scale or 1) + maxh = 100. + height = bbox[3] - (bbox[1] if bbox[1] < 0 else 0) + if scale is None and height > maxh: + scale = maxh / height + bbox = [x * scale for x in bbox] + res += _defglyphs(f, gnames, scale) + res += '\n'.format(-bbox[0], bbox[3]) + res += ' \n'.format( + bbox[0], bbox[1], bbox[2]-bbox[0], bbox[3]) + res += ' \n' + for i, gname in enumerate(gnames): + pt = points[i] if i < len(points) else (0, 0) + res += ' \n'.format(gname, pt[0] * scale, pt[1] * scale, glyphsetcount) + res += ' \n\n' + return SVG(data=res) + #return res + +def displayText(f, text, features = [], lang=None, dir="", script="", shapers="", size=0): + import harfbuzz + glyphs = harfbuzz.shape_text(f, text, features, lang, dir, script, shapers) + gnames = [] + points = [] + x = 0 + y = 0 + for g in glyphs: + gnames.append(f.getGlyphName(g.gid)) + points.append((x+g.offset[0], y+g.offset[1])) + x += g.advance[0] + y += g.advance[1] + if size == 0: + scale = None + else: + upem = f['head'].unitsPerEm + scale = 4. * size / (upem * 3.) + return displayGlyphs(f, gnames, points, scale=scale) + +def displayRaw(text): + # res = ""+text.encode('utf-8')+"" + res = u"

"+text+u"

" + return HTML(data=res) -- cgit v1.2.3