single |
|CI Build Status| |Coverage Status| |PyPI| |Gitter Chat|
What is this?
~~~~~~~~~~~~~
| fontTools is a library for manipulating fonts, written in Python. The
project includes the TTX tool, that can convert TrueType and OpenType
fonts to and from an XML text format, which is also called TTX. It
supports TrueType, OpenType, AFM and to an extent Type 1 and some
Mac-specific formats. The project has an `MIT open-source
license `__.
| Among other things this means you can use it free of charge.
[User documentation] and
[developer documentation]
are available at [Read the Docs].
Installation
~~~~~~~~~~~~
FontTools requires [Python] 3.9
or later. We try to follow the same schedule of minimum Python version
support as
NumPy (see [NEP 29]).
The package is listed in the Python Package Index (PyPI), so you can
install it with [pip]:
Changelog
~~~~~~~~~
4.59.0 (released 2025-07-16)
----------------------------
- 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).
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 (released 2025-07-03)
----------------------------
- [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).
4.58.4 (released 2025-06-13)
----------------------------
- [feaLib] Allow for empty MarkFilter & MarkAttach sets (#3856).
4.58.3 (released 2025-06-13)
----------------------------
- [feaLib] Fixed iterable check for Python 3.13.4 and newer (#3854, #3855).
4.58.2 (released 2025-06-06)
----------------------------
- [ttLib.reorderGlyphs] Handle CFF2 when reordering glyphs (#3852)
- [subset] Copy name IDs in use before scrapping or scrambling them for
webfonts (#3853)
4.58.1 (released 2025-05-28)
----------------------------
- [varLib] Make sure that fvar named instances only reuse name ID 2 or 17
if they are at the default location across all axes, to match OT spec
requirement (#3831).
- [feaLib] Improve single substitution promotion to multiple/ligature
substitutions, fixing a few bugs as well (#3849).
- [loggingTools] Make ``Timer._time`` a static method that doesn't take
self, makes it easier to override (#3836).
- [featureVars] Use None for empty ConditionSet, which translates to a null
offset in the compiled table (#3850).
- [feaLib] Raise an error on conflicting ligature substitution rules
instead of silently taking the last one (#3835).
- Add typing annotations to T2CharStringPen (#3837).
- [feaLib] Add single substitutions that were promoted to multiple or
ligature substitutions to aalt feature (#3847).
- [featureVars] Create a default LangSys in a ScriptRecord if missing when
|