Skip to content

Releases: fonttools/fonttools

4.62.0

09 Mar 16:56
0aee8a7

Choose a tag to compare

  • [diff] Add new fonttools diff command for comparing font files, imported from the fdiff project and heavily reworked (#1190, #4007, #4009, #4011, #4013, #4019).
  • [feaLib] Fix VariableScalar interpolation bug with non-linear avar mappings. Also decouple VariableScalar from compiled fonts, allowing it to work with designspace data before compilation (#3938, #4054).
  • [feaLib] Fix VariableScalar axis ordering and iterative delta rounding to match fontc behavior (#4053).
  • [feaLib] Merge chained multi subst rules with same context into a single subtable instead of emitting one subtable per glyph (#4016, #4058).
  • [feaLib] Pass location to ConditionsetStatement to fix glyphsLib round-tripping (fontra/fontra-glyphs#130, #4057).
  • [feaLib] Write 0xFFFF instead of 0 for missing nameIDs in cv feature params (#4010, #4012).
  • [cmap] Fix CmapSubtable.__lt__() TypeError on Python 3 when subtables share the same encoding record, and add compile-time validation for unique encoding records (#4035, #4055).
  • [svgLib] Skip non-element XML nodes (comments, processing instructions) when drawing SVG paths (#4042, #4043).
  • [glifLib] Fix regression reading glyph outlines when glyphObject=None (#4030, #4031).
  • [pointPen] Fix SegmentToPointPen edge case: only remove a duplicate final point on closePath() if it is an on-curve point (#4014, #4015).
  • [cffLib] SECURITY Replace eval() with safeEval() in parseBlendList() to prevent arbitrary code execution from crafted TTX files (#4039, #4040).
  • [ttLib] Remove defunct Adobe SING Glyphlet tables (META, SING, GMAP, GPKG) (#4044).
  • [varLib.interpolatable] Various bugfixes: fix swapped nodeTypes assignment, duplicate kink-detector condition, typos, CFF2 vsindex parsing, glyph existence check, and plot helpers (#4046).
  • [varLib.models] Fix getSubModel not forwarding extrapolate/axisRanges; check location uniqueness after stripping zeros (#4047).
  • [varLib] Fix --variable-fonts filter in build_many; remove dead code and fix comments (#4048).
  • [avar] Preserve existing name table in build; keep unbuild return types consistent; validate map CLI coordinates (#4051).
  • [cu2qu/qu2cu] Add input validation: reject non-positive tolerances, validate curve inputs and list lengths (#4052).
  • [colorLib] Raise a clear ColorLibError when base glyphs are missing from glyphMap, instead of a confusing KeyError (#4041).
  • [glyf] Remove unnecessary fvar table dependency (#4017).
  • [fvar/trak] Remove unnecessary name table dependency (#4018).
  • [ufoLib] Relax guideline validation to follow the updated spec (#3537, #3553).
  • [ttFont] Fix saveXML regression with empty table lists, clarify docstring (#4025, #4026, #4056).
  • [setup.py] Link libm for Cython extensions using math functions (#4028, #4029).
  • Add typing annotations for DSIG, DefaultTable, ttProgram (#4033).

4.61.1

12 Dec 17:08

Choose a tag to compare

  • [otlLib] buildCoverage: return empty Coverage instead of None (#4003, #4004).
  • [instancer] bug fix in avar2 full instancing (#4002).
  • [designspaceLib] Preserve empty conditionsets when serializing to XML (#4001).
  • [fontBu ilder] Fix FontBuilder setupOS2() default params globally polluted (#3996, #3997).
  • [ttFont] Add more typing annotations to ttFont, xmlWriter, sfnt, varLib.models and others (#3952, #3826).
  • Explicitly test and declare support for Python 3.14, even though we were already shipping pre-built wheels for it (#3990).

4.60.2

09 Dec 13:18

Choose a tag to compare

  • Backport release Same as 4.61.0 but without "Drop support for EOL Python 3.9" change to allow downstream projects still on Python 3.9 to avail of the security fix for CVE-2025-66034 (#3994, #3999).

4.61.0

28 Nov 17:12

Choose a tag to compare

  • [varLib.main]: SECURITY Only use basename(vf.filename) to prevent path traversal attacks when running fonttools varLib command-line script, or code which invokes fonttools.varLib.main(). Fixes CVE-2025-66034, see: GHSA-768j-98cg-p3fv.
  • [feaLib] Sort BaseLangSysRecords by tag (#3986).
  • Drop support for EOL Python 3.9 (#3982).
  • [instancer] Support --remove-overlaps for fonts with CFF2 table (#3975).
  • [CFF2ToCFF] Add --remove-overlaps option (#3976).
  • [feaLib] Raise an error for rsub with NULL target (#3979).
  • [bezierTools] Fix logic bug in curveCurveIntersections (#3963).
  • [feaLib] Error when condition sets have the same name (#3958).
  • [cu2qu.ufo] skip processing empty glyphs to support sparse kerning masters (#3956).
  • [unicodedata] Update to Unicode 17. Require unicodedata2 >= 17.0.0 when installed with 'unicode' extra.

4.60.1

29 Sep 21:31

Choose a tag to compare

  • [ufoLib] Reverted accidental method name change in UFOReader.getKerningGroupConversionRenameMaps
    that broke compatibility with downstream projects like defcon (#3948, #3947, robotools/defcon#478).
  • [ufoLib] Added test coverage for getKerningGroupConversionRenameMaps method (#3950).
  • [subset] Don't try to subset BASE table; pass it through by default instead (#3949).
  • [subset] Remove empty BaseRecord entries in MarkBasePos lookups (#3897, #3892).
  • [subset] Add pruning for MarkLigPos and MarkMarkPos lookups (#3946).
  • [subset] Remove duplicate features when subsetting (#3945).
  • [Docs] Added documentation for the visitor module (#3944).

4.60.0

17 Sep 12:01

Choose a tag to compare

  • [pointPen] Allow reverseFlipped parameter of DecomposingPointPen to take a ReverseFlipped enum value to control whether/how to reverse contour direction of flipped components, in addition to the existing True/False. This allows to set ReverseFlipped.ON_CURVE_FIRST to ensure that the decomposed outline starts with an on-curve point before being reversed, for better consistency with other segment-oriented contour transformations. The change is backward compatible, and the default behavior hasn't changed (#3934).

  • [filterPen] Added ContourFilterPointPen, base pen for buffered contour operations, and OnCurveStartPointPen filter to ensure contours start with an on-curve point (#3934).

  • [cu2qu] Fixed difference in cython vs pure-python complex division by real number (#3930).

  • [varLib.avar] Refactored and added some new sub-modules and scripts (#3926).

    • varLib.avar.build module to build avar (and a missing fvar) binaries into a possibly empty TTFont,
    • varLib.avar.unbuild module to print a .designspace snippet that would generate the same avar binary,
    • varLib.avar.map module to take TTFont and do the mapping, in user/normalized space,
    • varLib.avar.plan module moved from varLib.avarPlanner.

    The bare fonttools varLib.avar script is deprecated, in favour of fonttools varLib.avar.build (or unbuild).

  • [interpolatable] Clarify linear_sum_assignment backend options and minimal dependency usage (#3927).

  • [post] Speed up build_psNameMapping (#3923).

  • [ufoLib] Added typing annotations to fontTools.ufoLib (#3875).

4.59.2

27 Aug 16:41

Choose a tag to compare

  • [varLib] Clear USE_MY_METRICS component flags when inconsistent across masters (#3912).
  • [varLib.instancer] Avoid negative advance width/height values when instatiating HVAR/VVAR, (unlikely in well-behaved fonts) (#3918).
  • [subset] Fix shaping behaviour when pruning empty mark sets (#3915, harfbuzz/harfbuzz#5499).
  • [cu2qu] Fixed dot() product of perpendicular vectors not always returning exactly 0.0 in all Python implementations (#3911)
  • [varLib.instancer] Implemented fully-instantiating avar2 fonts (#3909).
  • [feaLib] Allow float values in VariableScalar's axis locations (#3906, #3907).
  • [cu2qu] Handle special case in calc_intersect for degenerate cubic curves where 3 to 4 control points are equal (#3904).

4.59.1

14 Aug 16:55

Choose a tag to compare

  • [featureVars] Update OS/2.usMaxContext if possible after addFeatureVariationsRaw (#3894).
  • [vhmtx] raise TTLibError('not enough data...') when hmtx/vmtx are truncated (#3843, #3901).
  • [feaLib] Combine duplicate features that have the same set of lookups regardless of the order in which those lookups are added to the feature (#3895).
  • [varLib] Deprecate varLib.mutator in favor of varLib.instancer. The latter provides equivalent full (static font) instancing in addition to partial VF instancing.
    CLI users should replace fonttools varLib.mutator with fonttools varLib.instancer. API users should migrate to fontTools.varLib.instancer.instantiateVariableFont (#2680).

4.59.0

16 Jul 12:05

Choose a tag to compare

  • Removed hard-dependency on pyfilesystem2 (fs package) from fonttools[ufo] extra. This is replaced by the fontTools.misc.filesystem package, a stdlib-only, drop-in replacement for the subset of the pyfilesystem2's API used by fontTools.ufoLib. The latter should continue to work with the upstream fs (we even test with/without). However, clients who wish to continue using fs can do so by depending on it directly instead of via the fonttools[ufo] extra (#3885, #3620).
  • [xmlWriter] Replace illegal XML characters (e.g. control or non-characters) with "?" when dumping to ttx (#3868, #71).
  • [varLib.hvar] Fixed vertical metrics fields copy/pasta error (#3884).
  • Micro optimizations in ttLib and sstruct modules (#3878, #3879).
  • [unicodedata] Add Garay script to RTL_SCRIPTS (#3882).
  • [roundingPen] Remove unreliable kwarg usage. Argument names aren’t consistent among point pens’ .addComponent() implementations, in particular baseGlyphName vs glyphName (#3880).

4.58.5

03 Jul 14:34

Choose a tag to compare

  • [feaLib] Don't try to combine ligature & multisub rules (#3874).
  • [feaLib/ast] Use weakref proxies to avoid cycles in visitor (#3873).
  • [varLib.instancer] Fixed instancing CFF2 fonts where VarData contains more than 64k items (#3858).