diff options
author | Haibo Huang <hhb@google.com> | 2019-06-04 17:54:35 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-06-04 17:54:35 -0700 |
commit | 12c4f3c6a907631b844818c5205e116790c088b9 (patch) | |
tree | bf49f60791568d4b7b626c1f45960f35e53ed78e | |
parent | 3df2f1b457ebb56ee28ddc85f5c9d324e94de662 (diff) | |
parent | 4c8220a6a278f97eb1b758cd0909ca26122725d6 (diff) | |
download | fonttools-12c4f3c6a907631b844818c5205e116790c088b9.tar.gz |
Upgrade fonttools to 3.42.0
am: 4c8220a6a2
Change-Id: Ia4b80e3ae1b157f2bf26d7baf7de29a0d43f7be7
32 files changed, 345 insertions, 166 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index f4b2933c..9701df65 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -33,7 +33,7 @@ install: - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" # upgrade pip and setuptools to avoid out-of-date warnings - - "python -m pip install --disable-pip-version-check --user --upgrade pip setuptools" + - "python -m pip install --disable-pip-version-check --user --upgrade pip setuptools virtualenv" # install the dependencies to run the tests - "python -m pip install tox" diff --git a/Lib/fontTools/__init__.py b/Lib/fontTools/__init__.py index ad773e89..6a066d73 100644 --- a/Lib/fontTools/__init__.py +++ b/Lib/fontTools/__init__.py @@ -5,6 +5,6 @@ from fontTools.misc.loggingTools import configLogger log = logging.getLogger(__name__) -version = __version__ = "3.41.2" +version = __version__ = "3.42.0" __all__ = ["version", "log", "configLogger"] diff --git a/Lib/fontTools/fontBuilder.py b/Lib/fontTools/fontBuilder.py index ef14b045..2498730c 100644 --- a/Lib/fontTools/fontBuilder.py +++ b/Lib/fontTools/fontBuilder.py @@ -712,25 +712,14 @@ class FontBuilder(object): self._initTableWithValues("maxp", defaults, {}) def setupDummyDSIG(self): - """This adds a dummy DSIG table to the font to make some MS applications + """This adds an empty DSIG table to the font to make some MS applications happy. This does not properly sign the font. """ - from .ttLib.tables.D_S_I_G_ import SignatureRecord - - sig = SignatureRecord() - sig.ulLength = 20 - sig.cbSignature = 12 - sig.usReserved2 = 0 - sig.usReserved1 = 0 - sig.pkcs7 = b'\xd3M4\xd3M5\xd3M4\xd3M4' - sig.ulFormat = 1 - sig.ulOffset = 20 - values = dict( ulVersion = 1, - usFlag = 1, - usNumSigs = 1, - signatureRecords = [sig], + usFlag = 0, + usNumSigs = 0, + signatureRecords = [], ) self._initTableWithValues("DSIG", {}, values) diff --git a/Lib/fontTools/subset/__init__.py b/Lib/fontTools/subset/__init__.py index efa06c4c..8cf82c12 100644 --- a/Lib/fontTools/subset/__init__.py +++ b/Lib/fontTools/subset/__init__.py @@ -388,6 +388,9 @@ def _uniq_sort(l): def _dict_subset(d, glyphs): return {g:d[g] for g in glyphs} +def _list_subset(l, indices): + count = len(l) + return [l[i] for i in indices if i < count] @_add_method(otTables.Coverage) def intersect(self, glyphs): @@ -482,7 +485,7 @@ def subset_glyphs(self, s): @_add_method(otTables.LigatureSubst) def closure_glyphs(self, s, cur_glyphs): s.glyphs.update(*([seq.LigGlyph for seq in seqs - if all(c in s.glyphs for c in seq.Component)] + if all(c in s.glyphs for c in seq.Component)] for g,seqs in self.ligatures.items() if g in cur_glyphs)) @@ -513,11 +516,11 @@ def closure_glyphs(self, s, cur_glyphs): def subset_glyphs(self, s): if self.Format == 1: indices = self.Coverage.subset(s.glyphs) - self.Substitute = [self.Substitute[i] for i in indices] + self.Substitute = _list_subset(self.Substitute, indices) # Now drop rules generating glyphs we don't want indices = [i for i,sub in enumerate(self.Substitute) if sub in s.glyphs] - self.Substitute = [self.Substitute[i] for i in indices] + self.Substitute = _list_subset(self.Substitute, indices) self.Coverage.remap(indices) self.GlyphCount = len(self.Substitute) return bool(self.GlyphCount and @@ -560,7 +563,7 @@ def subset_glyphs(self, s): # Remove empty pairsets indices = [i for i,p in enumerate(self.PairSet) if p.PairValueCount] self.Coverage.remap(indices) - self.PairSet = [self.PairSet[i] for i in indices] + self.PairSet = _list_subset(self.PairSet, indices) self.PairSetCount = len(self.PairSet) return bool(self.PairSetCount) elif self.Format == 2: @@ -615,10 +618,10 @@ def prune_post_subset(self, font, options): def subset_glyphs(self, s): if self.Format == 1: mark_indices = self.MarkCoverage.subset(s.glyphs) - self.MarkArray.MarkRecord = [self.MarkArray.MarkRecord[i] for i in mark_indices] + self.MarkArray.MarkRecord = _list_subset(self.MarkArray.MarkRecord, mark_indices) self.MarkArray.MarkCount = len(self.MarkArray.MarkRecord) base_indices = self.BaseCoverage.subset(s.glyphs) - self.BaseArray.BaseRecord = [self.BaseArray.BaseRecord[i] for i in base_indices] + self.BaseArray.BaseRecord = _list_subset(self.BaseArray.BaseRecord, base_indices) self.BaseArray.BaseCount = len(self.BaseArray.BaseRecord) # Prune empty classes class_indices = _uniq_sort(v.Class for v in self.MarkArray.MarkRecord) @@ -626,10 +629,10 @@ def subset_glyphs(self, s): for m in self.MarkArray.MarkRecord: m.Class = class_indices.index(m.Class) for b in self.BaseArray.BaseRecord: - b.BaseAnchor = [b.BaseAnchor[i] for i in class_indices] + b.BaseAnchor = _list_subset(b.BaseAnchor, class_indices) return bool(self.ClassCount and - self.MarkArray.MarkCount and - self.BaseArray.BaseCount) + self.MarkArray.MarkCount and + self.BaseArray.BaseCount) else: assert 0, "unknown format: %s" % self.Format @@ -649,10 +652,10 @@ def prune_post_subset(self, font, options): def subset_glyphs(self, s): if self.Format == 1: mark_indices = self.MarkCoverage.subset(s.glyphs) - self.MarkArray.MarkRecord = [self.MarkArray.MarkRecord[i] for i in mark_indices] + self.MarkArray.MarkRecord = _list_subset(self.MarkArray.MarkRecord, mark_indices) self.MarkArray.MarkCount = len(self.MarkArray.MarkRecord) ligature_indices = self.LigatureCoverage.subset(s.glyphs) - self.LigatureArray.LigatureAttach = [self.LigatureArray.LigatureAttach[i] for i in ligature_indices] + self.LigatureArray.LigatureAttach = _list_subset(self.LigatureArray.LigatureAttach, ligature_indices) self.LigatureArray.LigatureCount = len(self.LigatureArray.LigatureAttach) # Prune empty classes class_indices = _uniq_sort(v.Class for v in self.MarkArray.MarkRecord) @@ -661,10 +664,10 @@ def subset_glyphs(self, s): m.Class = class_indices.index(m.Class) for l in self.LigatureArray.LigatureAttach: for c in l.ComponentRecord: - c.LigatureAnchor = [c.LigatureAnchor[i] for i in class_indices] + c.LigatureAnchor = _list_subset(c.LigatureAnchor, class_indices) return bool(self.ClassCount and - self.MarkArray.MarkCount and - self.LigatureArray.LigatureCount) + self.MarkArray.MarkCount and + self.LigatureArray.LigatureCount) else: assert 0, "unknown format: %s" % self.Format @@ -685,10 +688,10 @@ def prune_post_subset(self, font, options): def subset_glyphs(self, s): if self.Format == 1: mark1_indices = self.Mark1Coverage.subset(s.glyphs) - self.Mark1Array.MarkRecord = [self.Mark1Array.MarkRecord[i] for i in mark1_indices] + self.Mark1Array.MarkRecord = _list_subset(self.Mark1Array.MarkRecord, mark1_indices) self.Mark1Array.MarkCount = len(self.Mark1Array.MarkRecord) mark2_indices = self.Mark2Coverage.subset(s.glyphs) - self.Mark2Array.Mark2Record = [self.Mark2Array.Mark2Record[i] for i in mark2_indices] + self.Mark2Array.Mark2Record = _list_subset(self.Mark2Array.Mark2Record, mark2_indices) self.Mark2Array.MarkCount = len(self.Mark2Array.Mark2Record) # Prune empty classes class_indices = _uniq_sort(v.Class for v in self.Mark1Array.MarkRecord) @@ -696,10 +699,10 @@ def subset_glyphs(self, s): for m in self.Mark1Array.MarkRecord: m.Class = class_indices.index(m.Class) for b in self.Mark2Array.Mark2Record: - b.Mark2Anchor = [b.Mark2Anchor[i] for i in class_indices] + b.Mark2Anchor = _list_subset(b.Mark2Anchor, class_indices) return bool(self.ClassCount and - self.Mark1Array.MarkCount and - self.Mark2Array.MarkCount) + self.Mark1Array.MarkCount and + self.Mark2Array.MarkCount) else: assert 0, "unknown format: %s" % self.Format @@ -1013,7 +1016,7 @@ def subset_glyphs(self, s): # Prune empty rulesets indices = [i for i,rs in enumerate(rss) if rs and getattr(rs, c.Rule)] self.Coverage.remap(indices) - rss = [rss[i] for i in indices] + rss = _list_subset(rss, indices) setattr(self, c.RuleSet, rss) setattr(self, c.RuleSetCount, len(rss)) return bool(rss) @@ -1278,7 +1281,7 @@ def collect_lookups(self, feature_indices): @_add_method(otTables.FeatureList) def subset_features(self, feature_indices): self.ensureDecompiled() - self.FeatureRecord = [self.FeatureRecord[i] for i in feature_indices] + self.FeatureRecord = _list_subset(self.FeatureRecord, feature_indices) self.FeatureCount = len(self.FeatureRecord) return bool(self.FeatureCount) @@ -1619,7 +1622,7 @@ def subset_glyphs(self, s): table = self.table if table.LigCaretList: indices = table.LigCaretList.Coverage.subset(glyphs) - table.LigCaretList.LigGlyph = [table.LigCaretList.LigGlyph[i] for i in indices] + table.LigCaretList.LigGlyph = _list_subset(table.LigCaretList.LigGlyph, indices) table.LigCaretList.LigGlyphCount = len(table.LigCaretList.LigGlyph) if table.MarkAttachClassDef: table.MarkAttachClassDef.classDefs = \ @@ -1989,21 +1992,21 @@ def closure_glyphs(self, s): @_add_method(otTables.MathItalicsCorrectionInfo) def subset_glyphs(self, s): indices = self.Coverage.subset(s.glyphs) - self.ItalicsCorrection = [self.ItalicsCorrection[i] for i in indices] + self.ItalicsCorrection = _list_subset(self.ItalicsCorrection, indices) self.ItalicsCorrectionCount = len(self.ItalicsCorrection) return bool(self.ItalicsCorrectionCount) @_add_method(otTables.MathTopAccentAttachment) def subset_glyphs(self, s): indices = self.TopAccentCoverage.subset(s.glyphs) - self.TopAccentAttachment = [self.TopAccentAttachment[i] for i in indices] + self.TopAccentAttachment = _list_subset(self.TopAccentAttachment, indices) self.TopAccentAttachmentCount = len(self.TopAccentAttachment) return bool(self.TopAccentAttachmentCount) @_add_method(otTables.MathKernInfo) def subset_glyphs(self, s): indices = self.MathKernCoverage.subset(s.glyphs) - self.MathKernInfoRecords = [self.MathKernInfoRecords[i] for i in indices] + self.MathKernInfoRecords = _list_subset(self.MathKernInfoRecords, indices) self.MathKernCount = len(self.MathKernInfoRecords) return bool(self.MathKernCount) @@ -2023,12 +2026,12 @@ def subset_glyphs(self, s): def subset_glyphs(self, s): if self.VertGlyphCoverage: indices = self.VertGlyphCoverage.subset(s.glyphs) - self.VertGlyphConstruction = [self.VertGlyphConstruction[i] for i in indices] + self.VertGlyphConstruction = _list_subset(self.VertGlyphConstruction, indices) self.VertGlyphCount = len(self.VertGlyphConstruction) if self.HorizGlyphCoverage: indices = self.HorizGlyphCoverage.subset(s.glyphs) - self.HorizGlyphConstruction = [self.HorizGlyphConstruction[i] for i in indices] + self.HorizGlyphConstruction = _list_subset(self.HorizGlyphConstruction, indices) self.HorizGlyphCount = len(self.HorizGlyphConstruction) return True @@ -2239,6 +2242,12 @@ def prune_pre_subset(self, font, options): return True # Required table +@_add_method(ttLib.getTableClass('head')) +def prune_post_subset(self, font, options): + # Force re-compiling head table, to update any recalculated values. + return True + + # TODO(behdad) OS/2 ulCodePageRange? # TODO(behdad) Drop AAT tables. # TODO(behdad) Drop unneeded GSUB/GPOS Script/LangSys entries. @@ -2572,17 +2581,19 @@ class Subsetter(object): self.glyphs_retained = frozenset(self.glyphs) - self.glyphs_emptied = frozenset() - if self.options.retain_gids: - self.glyphs_emptied = realGlyphs - self.glyphs_retained - # TODO Drop empty glyphs at the end of GlyphOrder vector. - order = font.getReverseGlyphMap() self.reverseOrigGlyphMap = {g:order[g] for g in self.glyphs_retained} - self.reverseEmptiedGlyphMap = {g:order[g] for g in self.glyphs_emptied} + self.last_retained_order = max(self.reverseOrigGlyphMap.values()) self.last_retained_glyph = font.getGlyphOrder()[self.last_retained_order] + self.glyphs_emptied = frozenset() + if self.options.retain_gids: + self.glyphs_emptied = {g for g in realGlyphs - self.glyphs_retained if order[g] <= self.last_retained_order} + + self.reverseEmptiedGlyphMap = {g:order[g] for g in self.glyphs_emptied} + + log.info("Retaining %d glyphs", len(self.glyphs_retained)) del self.glyphs @@ -2610,12 +2621,16 @@ class Subsetter(object): log.warning("%s NOT subset; don't know how to subset; dropped", tag) del font[tag] - if not self.options.retain_gids: - with timer("subset GlyphOrder"): - glyphOrder = font.getGlyphOrder() + with timer("subset GlyphOrder"): + glyphOrder = font.getGlyphOrder() + if not self.options.retain_gids: glyphOrder = [g for g in glyphOrder if g in self.glyphs_retained] - font.setGlyphOrder(glyphOrder) - font._buildReverseGlyphOrderDict() + else: + glyphOrder = [g for g in glyphOrder if font.getGlyphID(g) <= self.last_retained_order] + + font.setGlyphOrder(glyphOrder) + font._buildReverseGlyphOrderDict() + def _prune_post_subset(self, font): for tag in font.keys(): diff --git a/Lib/fontTools/subset/cff.py b/Lib/fontTools/subset/cff.py index fc29f182..7db6d880 100644 --- a/Lib/fontTools/subset/cff.py +++ b/Lib/fontTools/subset/cff.py @@ -113,42 +113,46 @@ def subset_glyphs(self, s): font = cff[fontname] cs = font.CharStrings + glyphs = s.glyphs.union(s.glyphs_emptied) + + # Load all glyphs + for g in font.charset: + if g not in glyphs: continue + c, _ = cs.getItemAndSelector(g) + + if cs.charStringsAreIndexed: + indices = [i for i,g in enumerate(font.charset) if g in glyphs] + csi = cs.charStringsIndex + csi.items = [csi.items[i] for i in indices] + del csi.file, csi.offsets + if hasattr(font, "FDSelect"): + sel = font.FDSelect + # XXX We want to set sel.format to None, such that the + # most compact format is selected. However, OTS was + # broken and couldn't parse a FDSelect format 0 that + # happened before CharStrings. As such, always force + # format 3 until we fix cffLib to always generate + # FDSelect after CharStrings. + # https://github.com/khaledhosny/ots/pull/31 + #sel.format = None + sel.format = 3 + sel.gidArray = [sel.gidArray[i] for i in indices] + cs.charStrings = {g:indices.index(v) + for g,v in cs.charStrings.items() + if g in glyphs} + else: + cs.charStrings = {g:v + for g,v in cs.charStrings.items() + if g in glyphs} + font.charset = [g for g in font.charset if g in glyphs] + font.numGlyphs = len(font.charset) + + if s.options.retain_gids: isCFF2 = cff.major > 1 for g in s.glyphs_emptied: _empty_charstring(font, g, isCFF2=isCFF2, ignoreWidth=True) - else: - # Load all glyphs - for g in font.charset: - if g not in s.glyphs: continue - c, _ = cs.getItemAndSelector(g) - - if cs.charStringsAreIndexed: - indices = [i for i,g in enumerate(font.charset) if g in s.glyphs] - csi = cs.charStringsIndex - csi.items = [csi.items[i] for i in indices] - del csi.file, csi.offsets - if hasattr(font, "FDSelect"): - sel = font.FDSelect - # XXX We want to set sel.format to None, such that the - # most compact format is selected. However, OTS was - # broken and couldn't parse a FDSelect format 0 that - # happened before CharStrings. As such, always force - # format 3 until we fix cffLib to always generate - # FDSelect after CharStrings. - # https://github.com/khaledhosny/ots/pull/31 - #sel.format = None - sel.format = 3 - sel.gidArray = [sel.gidArray[i] for i in indices] - cs.charStrings = {g:indices.index(v) - for g,v in cs.charStrings.items() - if g in s.glyphs} - else: - cs.charStrings = {g:v - for g,v in cs.charStrings.items() - if g in s.glyphs} - font.charset = [g for g in font.charset if g in s.glyphs] - font.numGlyphs = len(font.charset) + return True # any(cff[fontname].numGlyphs for fontname in cff.keys()) diff --git a/Lib/fontTools/ttLib/tables/O_S_2f_2.py b/Lib/fontTools/ttLib/tables/O_S_2f_2.py index 3e2c30c9..107d8590 100644 --- a/Lib/fontTools/ttLib/tables/O_S_2f_2.py +++ b/Lib/fontTools/ttLib/tables/O_S_2f_2.py @@ -43,7 +43,7 @@ OS2_format_0 = """ xAvgCharWidth: h # average character width usWeightClass: H # degree of thickness of strokes usWidthClass: H # aspect ratio - fsType: h # type flags + fsType: H # type flags ySubscriptXSize: h # subscript horizontal font size ySubscriptYSize: h # subscript vertical font size ySubscriptXOffset: h # subscript x offset diff --git a/Lib/fontTools/varLib/__init__.py b/Lib/fontTools/varLib/__init__.py index db567062..891e92c5 100644 --- a/Lib/fontTools/varLib/__init__.py +++ b/Lib/fontTools/varLib/__init__.py @@ -1046,10 +1046,21 @@ def main(args=None): 'name. The default value is "%(default)s".' ) ) + logging_group = parser.add_mutually_exclusive_group(required=False) + logging_group.add_argument( + "-v", "--verbose", + action="store_true", + help="Run more verbosely.") + logging_group.add_argument( + "-q", "--quiet", + action="store_true", + help="Turn verbosity off.") options = parser.parse_args(args) - # TODO: allow user to configure logging via command-line options - configLogger(level="INFO") + configLogger(level=( + "DEBUG" if options.verbose else + "ERROR" if options.quiet else + "INFO")) designspace_filename = options.designspace finder = MasterFinder(options.master_finder) diff --git a/Lib/fontTools/varLib/merger.py b/Lib/fontTools/varLib/merger.py index 688790c5..b4b17059 100644 --- a/Lib/fontTools/varLib/merger.py +++ b/Lib/fontTools/varLib/merger.py @@ -119,10 +119,10 @@ def merge(merger, self, lst): assert allNone(lst), (lst) return + lst = [l.classDefs for l in lst] self.classDefs = {} # We only care about the .classDefs self = self.classDefs - lst = [l.classDefs for l in lst] allKeys = set() allKeys.update(*[l.keys() for l in lst]) diff --git a/Lib/fontTools/varLib/models.py b/Lib/fontTools/varLib/models.py index 9a990b7b..9d969d73 100644 --- a/Lib/fontTools/varLib/models.py +++ b/Lib/fontTools/varLib/models.py @@ -25,7 +25,10 @@ def allEqual(lst, mapper=None): if not lst: return True it = iter(lst) - first = next(it) + try: + first = next(it) + except StopIteration: + return True return allEqualTo(first, it, mapper=mapper) def subList(truth, lst): diff --git a/Lib/fonttools.egg-info/PKG-INFO b/Lib/fonttools.egg-info/PKG-INFO index d64332fc..b302ec90 100644 --- a/Lib/fonttools.egg-info/PKG-INFO +++ b/Lib/fonttools.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fonttools -Version: 3.41.2 +Version: 3.42.0 Summary: Tools to manipulate font files Home-page: http://github.com/fonttools/fonttools Author: Just van Rossum @@ -238,8 +238,8 @@ Description: |Travis Build Status| |Appveyor Build status| |Coverage Status| |Py To use the latest available data, you can install: * `unicodedata2 <https://pypi.python.org/pypi/unicodedata2>`__: - ``unicodedata`` backport for Python 2.7 and 3.5 updated to the latest - Unicode version 9.0. Note this is not necessary if you use Python 3.6 + ``unicodedata`` backport for Python 2.7 and 3.x updated to the latest + Unicode version 12.0. Note this is not necessary if you use Python 3.8 as the latter already comes with an up-to-date ``unicodedata``. *Extra:* ``unicode`` @@ -415,6 +415,20 @@ Description: |Travis Build Status| |Appveyor Build status| |Coverage Status| |Py Changelog ~~~~~~~~~ + 3.42.0 (released 2019-05-28) + ---------------------------- + + - [OS/2] Fixed sign of ``fsType``: it should be ``uint16``, not ``int16`` (#1619). + - [subset] Skip out-of-range class values in mark attachment (#1478). + - [fontBuilder] Add an empty ``DSIG`` table with ``setupDummyDSIG`` method (#1621). + - [varLib.merger] Fixed bug whereby ``GDEF.GlyphClassDef`` were being dropped + when generating instance via ``varLib.mutator`` (#1614). + - [varLib] Added command-line options ``-v`` and ``-q`` to configure logging (#1613). + - [subset] Update font extents in head table (#1612). + - [subset] Make --retain-gids truncate empty glyphs after the last non-empty glyph + (#1611). + - [requirements] Updated ``unicodedata2`` backport for Unicode 12.0. + 3.41.2 (released 2019-05-13) ---------------------------- @@ -1742,13 +1756,13 @@ Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Text Processing :: Fonts Classifier: Topic :: Multimedia :: Graphics Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion -Provides-Extra: lxml Provides-Extra: all -Provides-Extra: woff +Provides-Extra: symfont +Provides-Extra: graphite Provides-Extra: unicode Provides-Extra: interpolatable +Provides-Extra: lxml +Provides-Extra: ufo +Provides-Extra: woff Provides-Extra: plot Provides-Extra: type1 -Provides-Extra: ufo -Provides-Extra: symfont -Provides-Extra: graphite diff --git a/Lib/fonttools.egg-info/requires.txt b/Lib/fonttools.egg-info/requires.txt index c94f1394..46d1d131 100644 --- a/Lib/fonttools.egg-info/requires.txt +++ b/Lib/fonttools.egg-info/requires.txt @@ -20,8 +20,8 @@ enum34>=1.1.6 singledispatch>=3.4.0.3 typing>=3.6.4 -[all:python_version < "3.7" and platform_python_implementation != "PyPy"] -unicodedata2>=11.0.0 +[all:python_version < "3.8" and platform_python_implementation != "PyPy"] +unicodedata2>=12.0.0 [all:sys_platform == "darwin"] xattr @@ -63,8 +63,8 @@ enum34>=1.1.6 [unicode] -[unicode:python_version < "3.7" and platform_python_implementation != "PyPy"] -unicodedata2>=11.0.0 +[unicode:python_version < "3.8" and platform_python_implementation != "PyPy"] +unicodedata2>=12.0.0 [woff] zopfli>=0.1.4 @@ -7,12 +7,12 @@ third_party { } url { type: ARCHIVE - value: "https://github.com/fonttools/fonttools/releases/download/3.41.2/fonttools-3.41.2.zip" + value: "https://github.com/fonttools/fonttools/releases/download/3.42.0/fonttools-3.42.0.zip" } - version: "3.41.2" + version: "3.42.0" last_upgrade_date { year: 2019 month: 5 - day: 13 + day: 31 } } @@ -1,3 +1,17 @@ +3.42.0 (released 2019-05-28) +---------------------------- + +- [OS/2] Fixed sign of ``fsType``: it should be ``uint16``, not ``int16`` (#1619). +- [subset] Skip out-of-range class values in mark attachment (#1478). +- [fontBuilder] Add an empty ``DSIG`` table with ``setupDummyDSIG`` method (#1621). +- [varLib.merger] Fixed bug whereby ``GDEF.GlyphClassDef`` were being dropped + when generating instance via ``varLib.mutator`` (#1614). +- [varLib] Added command-line options ``-v`` and ``-q`` to configure logging (#1613). +- [subset] Update font extents in head table (#1612). +- [subset] Make --retain-gids truncate empty glyphs after the last non-empty glyph + (#1611). +- [requirements] Updated ``unicodedata2`` backport for Unicode 12.0. + 3.41.2 (released 2019-05-13) ---------------------------- @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fonttools -Version: 3.41.2 +Version: 3.42.0 Summary: Tools to manipulate font files Home-page: http://github.com/fonttools/fonttools Author: Just van Rossum @@ -238,8 +238,8 @@ Description: |Travis Build Status| |Appveyor Build status| |Coverage Status| |Py To use the latest available data, you can install: * `unicodedata2 <https://pypi.python.org/pypi/unicodedata2>`__: - ``unicodedata`` backport for Python 2.7 and 3.5 updated to the latest - Unicode version 9.0. Note this is not necessary if you use Python 3.6 + ``unicodedata`` backport for Python 2.7 and 3.x updated to the latest + Unicode version 12.0. Note this is not necessary if you use Python 3.8 as the latter already comes with an up-to-date ``unicodedata``. *Extra:* ``unicode`` @@ -415,6 +415,20 @@ Description: |Travis Build Status| |Appveyor Build status| |Coverage Status| |Py Changelog ~~~~~~~~~ + 3.42.0 (released 2019-05-28) + ---------------------------- + + - [OS/2] Fixed sign of ``fsType``: it should be ``uint16``, not ``int16`` (#1619). + - [subset] Skip out-of-range class values in mark attachment (#1478). + - [fontBuilder] Add an empty ``DSIG`` table with ``setupDummyDSIG`` method (#1621). + - [varLib.merger] Fixed bug whereby ``GDEF.GlyphClassDef`` were being dropped + when generating instance via ``varLib.mutator`` (#1614). + - [varLib] Added command-line options ``-v`` and ``-q`` to configure logging (#1613). + - [subset] Update font extents in head table (#1612). + - [subset] Make --retain-gids truncate empty glyphs after the last non-empty glyph + (#1611). + - [requirements] Updated ``unicodedata2`` backport for Unicode 12.0. + 3.41.2 (released 2019-05-13) ---------------------------- @@ -1742,13 +1756,13 @@ Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Text Processing :: Fonts Classifier: Topic :: Multimedia :: Graphics Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion -Provides-Extra: lxml Provides-Extra: all -Provides-Extra: woff +Provides-Extra: symfont +Provides-Extra: graphite Provides-Extra: unicode Provides-Extra: interpolatable +Provides-Extra: lxml +Provides-Extra: ufo +Provides-Extra: woff Provides-Extra: plot Provides-Extra: type1 -Provides-Extra: ufo -Provides-Extra: symfont -Provides-Extra: graphite @@ -228,8 +228,8 @@ are required to unlock the extra features named "ufo", etc. To use the latest available data, you can install: * `unicodedata2 <https://pypi.python.org/pypi/unicodedata2>`__: - ``unicodedata`` backport for Python 2.7 and 3.5 updated to the latest - Unicode version 9.0. Note this is not necessary if you use Python 3.6 + ``unicodedata`` backport for Python 2.7 and 3.x updated to the latest + Unicode version 12.0. Note this is not necessary if you use Python 3.8 as the latter already comes with an up-to-date ``unicodedata``. *Extra:* ``unicode`` diff --git a/Tests/fontBuilder/data/test.otf.ttx b/Tests/fontBuilder/data/test.otf.ttx index 76ebb177..8fdd38f8 100644 --- a/Tests/fontBuilder/data/test.otf.ttx +++ b/Tests/fontBuilder/data/test.otf.ttx @@ -293,12 +293,7 @@ <DSIG> <!-- note that the Digital Signature will be invalid after recompilation! --> - <tableHeader flag="0x1" numSigs="1" version="1"/> - <SignatureRecord format="1"> ------BEGIN PKCS7----- -0000000100000000 ------END PKCS7----- - </SignatureRecord> + <tableHeader flag="0x0" numSigs="0" version="1"/> </DSIG> </ttFont> diff --git a/Tests/fontBuilder/data/test.ttf.ttx b/Tests/fontBuilder/data/test.ttf.ttx index 28e179e0..584815ef 100644 --- a/Tests/fontBuilder/data/test.ttf.ttx +++ b/Tests/fontBuilder/data/test.ttf.ttx @@ -298,12 +298,7 @@ <DSIG> <!-- note that the Digital Signature will be invalid after recompilation! --> - <tableHeader flag="0x1" numSigs="1" version="1"/> - <SignatureRecord format="1"> ------BEGIN PKCS7----- -0000000100000000 ------END PKCS7----- - </SignatureRecord> + <tableHeader flag="0x0" numSigs="0" version="1"/> </DSIG> </ttFont> diff --git a/Tests/fontBuilder/data/test_var.ttf.ttx b/Tests/fontBuilder/data/test_var.ttf.ttx index 54ddfb06..382d29e1 100644 --- a/Tests/fontBuilder/data/test_var.ttf.ttx +++ b/Tests/fontBuilder/data/test_var.ttf.ttx @@ -365,12 +365,7 @@ <DSIG> <!-- note that the Digital Signature will be invalid after recompilation! --> - <tableHeader flag="0x1" numSigs="1" version="1"/> - <SignatureRecord format="1"> ------BEGIN PKCS7----- -0000000100000000 ------END PKCS7----- - </SignatureRecord> + <tableHeader flag="0x0" numSigs="0" version="1"/> </DSIG> </ttFont> diff --git a/Tests/subset/data/expect_HVVAR_retain_gids.ttx b/Tests/subset/data/expect_HVVAR_retain_gids.ttx index da2eaf4f..8e51ca7f 100644 --- a/Tests/subset/data/expect_HVVAR_retain_gids.ttx +++ b/Tests/subset/data/expect_HVVAR_retain_gids.ttx @@ -8,7 +8,6 @@ <GlyphID id="2" name="B"/> <GlyphID id="3" name="glyph00003"/> <GlyphID id="4" name="D"/> - <GlyphID id="5" name="glyph00005"/> </GlyphOrder> <HVAR> @@ -63,7 +62,6 @@ <Map glyph="D" outer="0" inner="3"/> <Map glyph="glyph00001" outer="0" inner="0"/> <Map glyph="glyph00003" outer="0" inner="0"/> - <Map glyph="glyph00005" outer="0" inner="3"/> </LsbMap> <RsbMap> <Map glyph=".notdef" outer="0" inner="1"/> @@ -71,7 +69,6 @@ <Map glyph="D" outer="1" inner="1"/> <Map glyph="glyph00001" outer="0" inner="0"/> <Map glyph="glyph00003" outer="0" inner="0"/> - <Map glyph="glyph00005" outer="1" inner="1"/> </RsbMap> </HVAR> @@ -132,7 +129,6 @@ <Map glyph="D" outer="1" inner="1"/> <Map glyph="glyph00001" outer="0" inner="0"/> <Map glyph="glyph00003" outer="0" inner="0"/> - <Map glyph="glyph00005" outer="1" inner="1"/> </AdvHeightMap> <VOrgMap> <Map glyph=".notdef" outer="1" inner="2"/> @@ -140,7 +136,6 @@ <Map glyph="D" outer="1" inner="3"/> <Map glyph="glyph00001" outer="0" inner="0"/> <Map glyph="glyph00003" outer="0" inner="0"/> - <Map glyph="glyph00005" outer="1" inner="3"/> </VOrgMap> </VVAR> diff --git a/Tests/subset/subset_test.py b/Tests/subset/subset_test.py index eb632dc0..956197a3 100644 --- a/Tests/subset/subset_test.py +++ b/Tests/subset/subset_test.py @@ -465,6 +465,46 @@ class SubsetTest(unittest.TestCase): subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_notdef_width_cid.ttx"), ["CFF "]) + def test_recalc_bounds_ttf(self): + ttxpath = self.getpath("TestTTF-Regular.ttx") + font = TTFont() + font.importXML(ttxpath) + head = font['head'] + bounds = [head.xMin, head.yMin, head.xMax, head.yMax] + + _, fontpath = self.compile_font(ttxpath, ".ttf") + subsetpath = self.temp_path(".ttf") + + # by default, the subsetter does not recalculate the bounding box + subset.main([fontpath, "--output-file=%s" % subsetpath, "*"]) + head = TTFont(subsetpath)['head'] + self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax]) + + subset.main([fontpath, "--recalc-bounds", "--output-file=%s" % subsetpath, "*"]) + head = TTFont(subsetpath)['head'] + bounds = [132, 304, 365, 567] + self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax]) + + def test_recalc_bounds_otf(self): + ttxpath = self.getpath("TestOTF-Regular.ttx") + font = TTFont() + font.importXML(ttxpath) + head = font['head'] + bounds = [head.xMin, head.yMin, head.xMax, head.yMax] + + _, fontpath = self.compile_font(ttxpath, ".otf") + subsetpath = self.temp_path(".otf") + + # by default, the subsetter does not recalculate the bounding box + subset.main([fontpath, "--output-file=%s" % subsetpath, "*"]) + head = TTFont(subsetpath)['head'] + self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax]) + + subset.main([fontpath, "--recalc-bounds", "--output-file=%s" % subsetpath, "*"]) + head = TTFont(subsetpath)['head'] + bounds = [132, 304, 365, 567] + self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax]) + def test_recalc_timestamp_ttf(self): ttxpath = self.getpath("TestTTF-Regular.ttx") font = TTFont() @@ -530,20 +570,20 @@ class SubsetTest(unittest.TestCase): "--retain-gids", "--output-file=%s" % subsetpath, "--glyph-names", - "A", + "B", ] ) subsetfont = TTFont(subsetpath) - self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder()) + self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder()[0:3]) hmtx = subsetfont["hmtx"] - self.assertEqual(hmtx["A"], (500, 132)) - self.assertEqual(hmtx["B"], (0, 0)) + self.assertEqual(hmtx["A"], ( 0, 0)) + self.assertEqual(hmtx["B"], (400, 132)) glyf = subsetfont["glyf"] - self.assertGreater(glyf["A"].numberOfContours, 0) - self.assertEqual(glyf["B"].numberOfContours, 0) + self.assertEqual(glyf["A"].numberOfContours, 0) + self.assertGreater(glyf["B"].numberOfContours, 0) def test_retain_gids_cff(self): _, fontpath = self.compile_font(self.getpath("TestOTF-Regular.ttx"), ".otf") @@ -551,11 +591,13 @@ class SubsetTest(unittest.TestCase): self.assertEqual(font["hmtx"]["A"], (500, 132)) self.assertEqual(font["hmtx"]["B"], (400, 132)) + self.assertEqual(font["hmtx"]["C"], (500, 0)) font["CFF "].cff[0].decompileAllCharStrings() cs = font["CFF "].cff[0].CharStrings self.assertGreater(len(cs["A"].program), 0) self.assertGreater(len(cs["B"].program), 0) + self.assertGreater(len(cs["C"].program), 0) subsetpath = self.temp_path(".otf") subset.main( @@ -564,21 +606,22 @@ class SubsetTest(unittest.TestCase): "--retain-gids", "--output-file=%s" % subsetpath, "--glyph-names", - "A", + "B", ] ) subsetfont = TTFont(subsetpath) - self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder()) + self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder()[0:3]) hmtx = subsetfont["hmtx"] - self.assertEqual(hmtx["A"], (500, 132)) - self.assertEqual(hmtx["B"], (0, 0)) + self.assertEqual(hmtx["A"], (0, 0)) + self.assertEqual(hmtx["B"], (400, 132)) subsetfont["CFF "].cff[0].decompileAllCharStrings() cs = subsetfont["CFF "].cff[0].CharStrings - self.assertGreater(len(cs["A"].program), 0) - self.assertEqual(cs["B"].program, ["endchar"]) + + self.assertEqual(cs["A"].program, ["endchar"]) + self.assertGreater(len(cs["B"].program), 0) def test_retain_gids_cff2(self): ttx_path = self.getpath("../../varLib/data/master_ttx_varfont_otf/TestCFF2VF.ttx") @@ -598,21 +641,21 @@ class SubsetTest(unittest.TestCase): fontpath, "--retain-gids", "--output-file=%s" % subsetpath, - "A", + "T", ] ) subsetfont = TTFont(subsetpath) - self.assertEqual(len(subsetfont.getGlyphOrder()), len(font.getGlyphOrder())) + self.assertEqual(len(subsetfont.getGlyphOrder()), len(font.getGlyphOrder()[0:3])) hmtx = subsetfont["hmtx"] - self.assertEqual(hmtx["A"], (600, 31)) - self.assertEqual(hmtx["glyph00002"], (0, 0)) + self.assertEqual(hmtx["glyph00001"], ( 0, 0)) + self.assertEqual(hmtx["T"], (600, 41)) subsetfont["CFF2"].cff[0].decompileAllCharStrings() cs = subsetfont["CFF2"].cff[0].CharStrings - self.assertGreater(len(cs["A"].program), 0) - self.assertEqual(cs["glyph00002"].program, []) + self.assertEqual(cs["glyph00001"].program, []) + self.assertGreater(len(cs["T"].program), 0) def test_HVAR_VVAR(self): _, fontpath = self.compile_font(self.getpath("TestHVVAR.ttx"), ".ttf") diff --git a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master0.ttx b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master0.ttx index f14f89d3..6054e4bd 100644 --- a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master0.ttx +++ b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master0.ttx @@ -517,4 +517,14 @@ </extraNames> </post> + <GDEF> + <Version value="0x00010003"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + </ttFont> diff --git a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master1.ttx b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master1.ttx index 8d5bace5..afd61de9 100644 --- a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master1.ttx +++ b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master1.ttx @@ -517,4 +517,14 @@ </extraNames> </post> + <GDEF> + <Version value="0x00010003"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + </ttFont> diff --git a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master2.ttx b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master2.ttx index 3e20faca..0ed2f4ac 100644 --- a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master2.ttx +++ b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master2.ttx @@ -501,4 +501,14 @@ </extraNames> </post> + <GDEF> + <Version value="0x00010003"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + </ttFont> diff --git a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master3.ttx b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master3.ttx index e1d0375d..5666541e 100644 --- a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master3.ttx +++ b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master3.ttx @@ -501,4 +501,14 @@ </extraNames> </post> + <GDEF> + <Version value="0x00010003"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + </ttFont> diff --git a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master4.ttx b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master4.ttx index c0946fd1..87381873 100644 --- a/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master4.ttx +++ b/Tests/varLib/data/master_ttx_interpolatable_ttf/TestFamily-Master4.ttx @@ -501,4 +501,14 @@ </extraNames> </post> + <GDEF> + <Version value="0x00010003"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + </ttFont> diff --git a/Tests/varLib/data/test_results/Build.ttx b/Tests/varLib/data/test_results/Build.ttx index 1bc1880b..6e9c6e37 100644 --- a/Tests/varLib/data/test_results/Build.ttx +++ b/Tests/varLib/data/test_results/Build.ttx @@ -1,6 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> <ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.17"> + <GDEF> + <Version value="0x00010003"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + <HVAR> <Version value="0x00010000"/> <VarStore Format="1"> diff --git a/Tests/varLib/data/test_results/BuildMain.ttx b/Tests/varLib/data/test_results/BuildMain.ttx index 6875c712..7150a579 100644 --- a/Tests/varLib/data/test_results/BuildMain.ttx +++ b/Tests/varLib/data/test_results/BuildMain.ttx @@ -613,6 +613,16 @@ </extraNames> </post> + <GDEF> + <Version value="0x00010003"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + <HVAR> <Version value="0x00010000"/> <VarStore Format="1"> diff --git a/Tests/varLib/data/test_results/InterpolateLayoutMain.ttx b/Tests/varLib/data/test_results/InterpolateLayoutMain.ttx index 0c0af325..6a0635d0 100644 --- a/Tests/varLib/data/test_results/InterpolateLayoutMain.ttx +++ b/Tests/varLib/data/test_results/InterpolateLayoutMain.ttx @@ -496,4 +496,14 @@ </extraNames> </post> + <GDEF> + <Version value="0x00010003"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + </ttFont> diff --git a/Tests/varLib/data/test_results/Mutator.ttx b/Tests/varLib/data/test_results/Mutator.ttx index fac0997a..75a0879e 100644 --- a/Tests/varLib/data/test_results/Mutator.ttx +++ b/Tests/varLib/data/test_results/Mutator.ttx @@ -496,4 +496,14 @@ </extraNames> </post> + <GDEF> + <Version value="0x00010000"/> + <GlyphClassDef Format="2"> + <ClassDef glyph="uni0024" class="1"/> + <ClassDef glyph="uni0024.nostroke" class="1"/> + <ClassDef glyph="uni0041" class="1"/> + <ClassDef glyph="uni0061" class="1"/> + </GlyphClassDef> + </GDEF> + </ttFont> diff --git a/requirements.txt b/requirements.txt index f26fe104..bdfd52ba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,8 +2,10 @@ # extension 'brotlipy' on PyPy brotli==1.0.7; platform_python_implementation != "PyPy" brotlipy==0.7.0; platform_python_implementation == "PyPy" -unicodedata2==11.0.0; python_version < '3.7' and platform_python_implementation != "PyPy" -scipy==1.2.1; platform_python_implementation != "PyPy" -munkres==1.0.12; platform_python_implementation == "PyPy" # pyup: ignore +unicodedata2==12.0.0; python_version < '3.8' and platform_python_implementation != "PyPy" +scipy==1.2.1; platform_python_implementation != "PyPy" and python_version < '3.5' # pyup: ignore +scipy==1.3.0; platform_python_implementation != "PyPy" and python_version >= '3.5' +munkres==1.0.12; platform_python_implementation == "PyPy" and python_version < '3.5' # pyup: ignore +munkres==1.1.2; platform_python_implementation == "PyPy" and python_version >= '3.5' zopfli==0.1.6 fs==2.4.5 @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.41.2 +current_version = 3.42.0 commit = True tag = False tag_name = {new_version} @@ -57,10 +57,10 @@ extras_require = { # which varies between python versions and may be outdated. "unicode": [ # the unicodedata2 extension module doesn't work on PyPy. - # Python 3.7 already has Unicode 11, so the backport is not needed. + # Python 3.8 already has Unicode 12, so the backport is not needed. ( - "unicodedata2 >= 11.0.0; " - "python_version < '3.7' and platform_python_implementation != 'PyPy'" + "unicodedata2 >= 12.0.0; " + "python_version < '3.8' and platform_python_implementation != 'PyPy'" ), ], # for graphite type tables in ttLib/tables (Silf, Glat, Gloc) @@ -352,7 +352,7 @@ def find_data_files(manpath="share/man"): setup( name="fonttools", - version="3.41.2", + version="3.42.0", description="Tools to manipulate font files", author="Just van Rossum", author_email="just@letterror.com", |