From 0d1550febe6a5e1911dc5a417d4c6b3d49a24580 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Aug 2022 12:29:01 -0600 Subject: [PATCH] [ttFont] Split TTGlyphSet code into ttGlyphSet.py --- Lib/fontTools/ttLib/ttFont.py | 107 ++---------------------------- Lib/fontTools/ttLib/ttGlyphSet.py | 104 +++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 103 deletions(-) create mode 100644 Lib/fontTools/ttLib/ttGlyphSet.py diff --git a/Lib/fontTools/ttLib/ttFont.py b/Lib/fontTools/ttLib/ttFont.py index d7f7ef835..7abb8f490 100644 --- a/Lib/fontTools/ttLib/ttFont.py +++ b/Lib/fontTools/ttLib/ttFont.py @@ -4,6 +4,10 @@ from fontTools.misc.configTools import AbstractConfig from fontTools.misc.textTools import Tag, byteord, tostr from fontTools.misc.loggingTools import deprecateArgument from fontTools.ttLib import TTLibError +from fontTools.ttLib.ttGlyphSet import ( + _TTGlyphSet, _TTGlyph, + _TTGlyphCFF, _TTGlyphGlyf, +) from fontTools.ttLib.sfnt import SFNTReader, SFNTWriter from io import BytesIO, StringIO import os @@ -726,109 +730,6 @@ class TTFont(object): return self["cmap"].getBestCmap(cmapPreferences=cmapPreferences) -class _TTGlyphSet(object): - - """Generic dict-like GlyphSet class that pulls metrics from hmtx and - glyph shape from TrueType or CFF. - """ - - def __init__(self, ttFont, glyphs, glyphType): - """Construct a new glyphset. - - Args: - font (TTFont): The font object (used to get metrics). - glyphs (dict): A dictionary mapping glyph names to ``_TTGlyph`` objects. - glyphType (class): Either ``_TTGlyphCFF`` or ``_TTGlyphGlyf``. - """ - self._glyphs = glyphs - self._hmtx = ttFont['hmtx'] - self._vmtx = ttFont['vmtx'] if 'vmtx' in ttFont else None - self._glyphType = glyphType - - def keys(self): - return list(self._glyphs.keys()) - - def has_key(self, glyphName): - return glyphName in self._glyphs - - __contains__ = has_key - - def __getitem__(self, glyphName): - horizontalMetrics = self._hmtx[glyphName] - verticalMetrics = self._vmtx[glyphName] if self._vmtx else None - return self._glyphType( - self, self._glyphs[glyphName], horizontalMetrics, verticalMetrics) - - def __len__(self): - return len(self._glyphs) - - def get(self, glyphName, default=None): - try: - return self[glyphName] - except KeyError: - return default - -class _TTGlyph(object): - - """Wrapper for a TrueType glyph that supports the Pen protocol, meaning - that it has .draw() and .drawPoints() methods that take a pen object as - their only argument. Additionally there are 'width' and 'lsb' attributes, - read from the 'hmtx' table. - - If the font contains a 'vmtx' table, there will also be 'height' and 'tsb' - attributes. - """ - - def __init__(self, glyphset, glyph, horizontalMetrics, verticalMetrics=None): - """Construct a new _TTGlyph. - - Args: - glyphset (_TTGlyphSet): A glyphset object used to resolve components. - glyph (ttLib.tables._g_l_y_f.Glyph): The glyph object. - horizontalMetrics (int, int): The glyph's width and left sidebearing. - """ - self._glyphset = glyphset - self._glyph = glyph - self.width, self.lsb = horizontalMetrics - if verticalMetrics: - self.height, self.tsb = verticalMetrics - else: - self.height, self.tsb = None, None - - def draw(self, pen): - """Draw the glyph onto ``pen``. See fontTools.pens.basePen for details - how that works. - """ - self._glyph.draw(pen) - - def drawPoints(self, pen): - # drawPoints is only implemented for _TTGlyphGlyf at this time. - raise NotImplementedError() - -class _TTGlyphCFF(_TTGlyph): - pass - -class _TTGlyphGlyf(_TTGlyph): - - def draw(self, pen): - """Draw the glyph onto Pen. See fontTools.pens.basePen for details - how that works. - """ - glyfTable = self._glyphset._glyphs - glyph = self._glyph - offset = self.lsb - glyph.xMin if hasattr(glyph, "xMin") else 0 - glyph.draw(pen, glyfTable, offset) - - def drawPoints(self, pen): - """Draw the glyph onto PointPen. See fontTools.pens.pointPen - for details how that works. - """ - glyfTable = self._glyphset._glyphs - glyph = self._glyph - offset = self.lsb - glyph.xMin if hasattr(glyph, "xMin") else 0 - glyph.drawPoints(pen, glyfTable, offset) - - class GlyphOrder(object): """A pseudo table. The glyph order isn't in the font as a separate diff --git a/Lib/fontTools/ttLib/ttGlyphSet.py b/Lib/fontTools/ttLib/ttGlyphSet.py new file mode 100644 index 000000000..48c2a6fdd --- /dev/null +++ b/Lib/fontTools/ttLib/ttGlyphSet.py @@ -0,0 +1,104 @@ + +class _TTGlyphSet(object): + + """Generic dict-like GlyphSet class that pulls metrics from hmtx and + glyph shape from TrueType or CFF. + """ + + def __init__(self, ttFont, glyphs, glyphType): + """Construct a new glyphset. + + Args: + font (TTFont): The font object (used to get metrics). + glyphs (dict): A dictionary mapping glyph names to ``_TTGlyph`` objects. + glyphType (class): Either ``_TTGlyphCFF`` or ``_TTGlyphGlyf``. + """ + self._glyphs = glyphs + self._hmtx = ttFont['hmtx'] + self._vmtx = ttFont['vmtx'] if 'vmtx' in ttFont else None + self._glyphType = glyphType + + def keys(self): + return list(self._glyphs.keys()) + + def has_key(self, glyphName): + return glyphName in self._glyphs + + __contains__ = has_key + + def __getitem__(self, glyphName): + horizontalMetrics = self._hmtx[glyphName] + verticalMetrics = self._vmtx[glyphName] if self._vmtx else None + return self._glyphType( + self, self._glyphs[glyphName], horizontalMetrics, verticalMetrics) + + def __len__(self): + return len(self._glyphs) + + def get(self, glyphName, default=None): + try: + return self[glyphName] + except KeyError: + return default + +class _TTGlyph(object): + + """Wrapper for a TrueType glyph that supports the Pen protocol, meaning + that it has .draw() and .drawPoints() methods that take a pen object as + their only argument. Additionally there are 'width' and 'lsb' attributes, + read from the 'hmtx' table. + + If the font contains a 'vmtx' table, there will also be 'height' and 'tsb' + attributes. + """ + + def __init__(self, glyphset, glyph, horizontalMetrics, verticalMetrics=None): + """Construct a new _TTGlyph. + + Args: + glyphset (_TTGlyphSet): A glyphset object used to resolve components. + glyph (ttLib.tables._g_l_y_f.Glyph): The glyph object. + horizontalMetrics (int, int): The glyph's width and left sidebearing. + """ + self._glyphset = glyphset + self._glyph = glyph + self.width, self.lsb = horizontalMetrics + if verticalMetrics: + self.height, self.tsb = verticalMetrics + else: + self.height, self.tsb = None, None + + def draw(self, pen): + """Draw the glyph onto ``pen``. See fontTools.pens.basePen for details + how that works. + """ + self._glyph.draw(pen) + + def drawPoints(self, pen): + # drawPoints is only implemented for _TTGlyphGlyf at this time. + raise NotImplementedError() + +class _TTGlyphCFF(_TTGlyph): + pass + +class _TTGlyphGlyf(_TTGlyph): + + def draw(self, pen): + """Draw the glyph onto Pen. See fontTools.pens.basePen for details + how that works. + """ + glyfTable = self._glyphset._glyphs + glyph = self._glyph + offset = self.lsb - glyph.xMin if hasattr(glyph, "xMin") else 0 + glyph.draw(pen, glyfTable, offset) + + def drawPoints(self, pen): + """Draw the glyph onto PointPen. See fontTools.pens.pointPen + for details how that works. + """ + glyfTable = self._glyphset._glyphs + glyph = self._glyph + offset = self.lsb - glyph.xMin if hasattr(glyph, "xMin") else 0 + glyph.drawPoints(pen, glyfTable, offset) + +