diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2023-11-30 09:51:41 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2023-11-30 10:16:12 +0300 |
commit | d3b4d830e105623b4cc96655c4dbb2d73f825989 (patch) | |
tree | df2a42a8615d7c1bc9d7fd682c8c8f992a17b681 /contrib | |
parent | 468826fff1465595d80da778532b253674e1e1c3 (diff) | |
download | ydb-d3b4d830e105623b4cc96655c4dbb2d73f825989.tar.gz |
Update contrib/python/fonttools to 4.44.3
Diffstat (limited to 'contrib')
11 files changed, 110 insertions, 10 deletions
diff --git a/contrib/python/fonttools/.dist-info/METADATA b/contrib/python/fonttools/.dist-info/METADATA index dfdbe2c0d9..1e4df6685a 100644 --- a/contrib/python/fonttools/.dist-info/METADATA +++ b/contrib/python/fonttools/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fonttools -Version: 4.44.1 +Version: 4.44.3 Summary: Tools to manipulate font files Home-page: http://github.com/fonttools/fonttools Author: Just van Rossum @@ -366,6 +366,20 @@ Have fun! Changelog ~~~~~~~~~ +4.44.3 (released 2023-11-15) +---------------------------- + +- [subset] Only prune codepage ranges for OS/2.version >= 1, ignore otherwise (#3334). +- [instancer] Ensure hhea vertical metrics stay in sync with OS/2 ones after instancing + MVAR table containing 'hasc', 'hdsc' or 'hlgp' tags (#3297). + +4.44.2 (released 2023-11-14) +---------------------------- + +- [glyf] Have ``Glyph.recalcBounds`` skip empty components (base glyph with no contours) + when computing the bounding box of composite glyphs. This simply restores the existing + behavior before some changes were introduced in fonttools 4.44.0 (#3333). + 4.44.1 (released 2023-11-14) ---------------------------- diff --git a/contrib/python/fonttools/fontTools/__init__.py b/contrib/python/fonttools/fontTools/__init__.py index cf93bad01f..2381f4105e 100644 --- a/contrib/python/fonttools/fontTools/__init__.py +++ b/contrib/python/fonttools/fontTools/__init__.py @@ -3,6 +3,6 @@ from fontTools.misc.loggingTools import configLogger log = logging.getLogger(__name__) -version = __version__ = "4.44.1" +version = __version__ = "4.44.3" __all__ = ["version", "log", "configLogger"] diff --git a/contrib/python/fonttools/fontTools/pens/svgPathPen.py b/contrib/python/fonttools/fontTools/pens/svgPathPen.py index ae6ebfbd53..53b3683f2d 100644 --- a/contrib/python/fonttools/fontTools/pens/svgPathPen.py +++ b/contrib/python/fonttools/fontTools/pens/svgPathPen.py @@ -246,7 +246,7 @@ def main(args=None): for tag_v in options.variations.split(): fields = tag_v.split("=") tag = fields[0].strip() - v = int(fields[1]) + v = float(fields[1]) location[tag] = v hhea = font["hhea"] diff --git a/contrib/python/fonttools/fontTools/subset/__init__.py b/contrib/python/fonttools/fontTools/subset/__init__.py index d9da900fe1..9b1758435c 100644 --- a/contrib/python/fonttools/fontTools/subset/__init__.py +++ b/contrib/python/fonttools/fontTools/subset/__init__.py @@ -3455,7 +3455,9 @@ class Subsetter(object): log.info( "%s Unicode ranges pruned: %s", tag, sorted(new_uniranges) ) - if self.options.prune_codepage_ranges: + if self.options.prune_codepage_ranges and font[tag].version >= 1: + # codepage range fields were added with OS/2 format 1 + # https://learn.microsoft.com/en-us/typography/opentype/spec/os2#version-1 old_codepages = font[tag].getCodePageRanges() new_codepages = font[tag].recalcCodePageRanges(font, pruneOnly=True) if old_codepages != new_codepages: diff --git a/contrib/python/fonttools/fontTools/subset/cff.py b/contrib/python/fonttools/fontTools/subset/cff.py index dd79f6db37..03fc565b31 100644 --- a/contrib/python/fonttools/fontTools/subset/cff.py +++ b/contrib/python/fonttools/fontTools/subset/cff.py @@ -502,7 +502,7 @@ def remove_unused_subroutines(self): # Renumber glyph charstrings for g in font.charset: c, _ = cs.getItemAndSelector(g) - subrs = getattr(c.private, "Subrs", []) + subrs = getattr(c.private, "Subrs", None) c.subset_subroutines(subrs, font.GlobalSubrs) # Renumber subroutines themselves @@ -511,7 +511,7 @@ def remove_unused_subroutines(self): if not hasattr(font, "FDArray") and hasattr(font.Private, "Subrs"): local_subrs = font.Private.Subrs else: - local_subrs = [] + local_subrs = None else: local_subrs = subrs diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/O_S_2f_2.py b/contrib/python/fonttools/fontTools/ttLib/tables/O_S_2f_2.py index b4126b835b..edff91f58d 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/O_S_2f_2.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/O_S_2f_2.py @@ -343,6 +343,8 @@ class table_O_S_2f_2(DefaultTable.DefaultTable): def getCodePageRanges(self): """Return the set of 'ulCodePageRange*' bits currently enabled.""" bits = set() + if self.version < 1: + return bits ul1, ul2 = self.ulCodePageRange1, self.ulCodePageRange2 for i in range(32): if ul1 & (1 << i): @@ -361,6 +363,8 @@ class table_O_S_2f_2(DefaultTable.DefaultTable): ul2 |= 1 << (bit - 32) else: raise ValueError(f"expected 0 <= int <= 63, found: {bit:r}") + if self.version < 1: + self.version = 1 self.ulCodePageRange1, self.ulCodePageRange2 = ul1, ul2 def recalcCodePageRanges(self, ttFont, pruneOnly=False): diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/_g_l_y_f.py b/contrib/python/fonttools/fontTools/ttLib/tables/_g_l_y_f.py index bff0d92c32..683912be97 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/_g_l_y_f.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/_g_l_y_f.py @@ -1211,6 +1211,9 @@ class Glyph(object): g.recalcBounds(glyfTable, boundsDone=boundsDone) if boundsDone is not None: boundsDone.add(glyphName) + # empty components shouldn't update the bounds of the parent glyph + if g.numberOfContours == 0: + continue x, y = compo.x, compo.y bounds = updateBounds(bounds, (g.xMin + x, g.yMin + y)) diff --git a/contrib/python/fonttools/fontTools/varLib/instancer/__init__.py b/contrib/python/fonttools/fontTools/varLib/instancer/__init__.py index cde1d39f6f..a887e5d38f 100644 --- a/contrib/python/fonttools/fontTools/varLib/instancer/__init__.py +++ b/contrib/python/fonttools/fontTools/varLib/instancer/__init__.py @@ -105,6 +105,7 @@ from fontTools.misc.cliTools import makeOutputFileName from fontTools.varLib.instancer import solver import collections import dataclasses +from contextlib import contextmanager from copy import deepcopy from enum import IntEnum import logging @@ -694,6 +695,43 @@ def setMvarDeltas(varfont, deltas): ) +@contextmanager +def verticalMetricsKeptInSync(varfont): + """Ensure hhea vertical metrics stay in sync with OS/2 ones after instancing. + + When applying MVAR deltas to the OS/2 table, if the ascender, descender and + line gap change but they were the same as the respective hhea metrics in the + original font, this context manager ensures that hhea metrcs also get updated + accordingly. + The MVAR spec only has tags for the OS/2 metrics, but it is common in fonts + to have the hhea metrics be equal to those for compat reasons. + + https://learn.microsoft.com/en-us/typography/opentype/spec/mvar + https://googlefonts.github.io/gf-guide/metrics.html#7-hhea-and-typo-metrics-should-be-equal + https://github.com/fonttools/fonttools/issues/3297 + """ + current_os2_vmetrics = [ + getattr(varfont["OS/2"], attr) + for attr in ("sTypoAscender", "sTypoDescender", "sTypoLineGap") + ] + metrics_are_synced = current_os2_vmetrics == [ + getattr(varfont["hhea"], attr) for attr in ("ascender", "descender", "lineGap") + ] + + yield metrics_are_synced + + if metrics_are_synced: + new_os2_vmetrics = [ + getattr(varfont["OS/2"], attr) + for attr in ("sTypoAscender", "sTypoDescender", "sTypoLineGap") + ] + if current_os2_vmetrics != new_os2_vmetrics: + for attr, value in zip( + ("ascender", "descender", "lineGap"), new_os2_vmetrics + ): + setattr(varfont["hhea"], attr, value) + + def instantiateMVAR(varfont, axisLimits): log.info("Instantiating MVAR table") @@ -701,7 +739,9 @@ def instantiateMVAR(varfont, axisLimits): fvarAxes = varfont["fvar"].axes varStore = mvar.VarStore defaultDeltas = instantiateItemVariationStore(varStore, fvarAxes, axisLimits) - setMvarDeltas(varfont, defaultDeltas) + + with verticalMetricsKeptInSync(varfont): + setMvarDeltas(varfont, defaultDeltas) if varStore.VarRegionList.Region: varIndexMapping = varStore.optimize() diff --git a/contrib/python/fonttools/fontTools/varLib/interpolatable.py b/contrib/python/fonttools/fontTools/varLib/interpolatable.py index c3f01f46e0..05ed3f768e 100644 --- a/contrib/python/fonttools/fontTools/varLib/interpolatable.py +++ b/contrib/python/fonttools/fontTools/varLib/interpolatable.py @@ -11,10 +11,14 @@ from fontTools.pens.pointPen import AbstractPointPen, SegmentToPointPen from fontTools.pens.recordingPen import RecordingPen from fontTools.pens.statisticsPen import StatisticsPen from fontTools.pens.momentsPen import OpenContourError +from fontTools.varLib.models import piecewiseLinearMap from collections import defaultdict import math import itertools import sys +import logging + +log = logging.getLogger("fontTools.varLib.interpolatable") def _rot_list(l, k): @@ -429,9 +433,14 @@ def main(args=None): nargs="+", help="Input a single variable font / DesignSpace / Glyphs file, or multiple TTF/UFO files", ) + parser.add_argument("-v", "--verbose", action="store_true", help="Run verbosely.") args = parser.parse_args(args) + from fontTools import configLogger + + configLogger(level=("INFO" if args.verbose else "ERROR")) + glyphs = args.glyphs.split() if args.glyphs else None from os.path import basename @@ -460,6 +469,24 @@ def main(args=None): font = TTFont(args.inputs[0]) if "gvar" in font: # Is variable font + + axisMapping = {} + fvar = font["fvar"] + for axis in fvar.axes: + axisMapping[axis.axisTag] = { + -1: axis.minValue, + 0: axis.defaultValue, + 1: axis.maxValue, + } + if "avar" in font: + avar = font["avar"] + for axisTag, segments in avar.segments.items(): + fvarMapping = axisMapping[axisTag].copy() + for location, value in segments.items(): + axisMapping[axisTag][value] = piecewiseLinearMap( + location, fvarMapping + ) + gvar = font["gvar"] glyf = font["glyf"] # Gather all glyphs at their "master" locations @@ -486,10 +513,18 @@ def main(args=None): glyphname, glyphsets[locTuple], ttGlyphSets[locTuple], glyf ) - names = ["()"] + names = ["''"] fonts = [font.getGlyphSet()] for locTuple in sorted(glyphsets.keys(), key=lambda v: (len(v), v)): - names.append(str(locTuple)) + name = ( + "'" + + " ".join( + "%s=%s" % (k, piecewiseLinearMap(v, axisMapping[k])) + for k, v in locTuple + ) + + "'" + ) + names.append(name) fonts.append(glyphsets[locTuple]) args.ignore_missing = True args.inputs = [] @@ -525,6 +560,7 @@ def main(args=None): for gn in diff: glyphset[gn] = None + log.info("Running on %d glyphsets", len(glyphsets)) problems_gen = test_gen( glyphsets, glyphs=glyphs, names=names, ignore_missing=args.ignore_missing ) diff --git a/contrib/python/fonttools/fontTools/varLib/models.py b/contrib/python/fonttools/fontTools/varLib/models.py index 5bd66dba15..33deabe043 100644 --- a/contrib/python/fonttools/fontTools/varLib/models.py +++ b/contrib/python/fonttools/fontTools/varLib/models.py @@ -4,6 +4,7 @@ __all__ = [ "normalizeValue", "normalizeLocation", "supportScalar", + "piecewiseLinearMap", "VariationModel", ] diff --git a/contrib/python/fonttools/ya.make b/contrib/python/fonttools/ya.make index 1a702d48c6..9f3e3eecde 100644 --- a/contrib/python/fonttools/ya.make +++ b/contrib/python/fonttools/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(4.44.1) +VERSION(4.44.3) LICENSE(MIT) |