1|CI Build Status| |Coverage Status| |PyPI| |Gitter Chat|
2
3What is this?
4~~~~~~~~~~~~~
5
6| fontTools is a library for manipulating fonts, written in Python. The
7 project includes the TTX tool, that can convert TrueType and OpenType
8 fonts to and from an XML text format, which is also called TTX. It
9 supports TrueType, OpenType, AFM and to an extent Type 1 and some
10 Mac-specific formats. The project has an `MIT open-source
11 licence <LICENSE>`__.
12| Among other things this means you can use it free of charge.
13
14`User documentation <https://fonttools.readthedocs.io/en/latest/>`_ and
15`developer documentation <https://fonttools.readthedocs.io/en/latest/developer.html>`_
16are available at `Read the Docs <https://fonttools.readthedocs.io/>`_.
17
18Installation
19~~~~~~~~~~~~
20
21FontTools requires `Python <http://www.python.org/download/>`__ 3.8
22or later. We try to follow the same schedule of minimum Python version support as
23NumPy (see `NEP 29 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`__).
24
25The package is listed in the Python Package Index (PyPI), so you can
26install it with `pip <https://pip.pypa.io>`__:
27
28.. code:: sh
29
30 pip install fonttools
31
32If you would like to contribute to its development, you can clone the
33repository from GitHub, install the package in 'editable' mode and
34modify the source code in place. We recommend creating a virtual
35environment, using `virtualenv <https://virtualenv.pypa.io>`__ or
36Python 3 `venv <https://docs.python.org/3/library/venv.html>`__ module.
37
38.. code:: sh
39
40 # download the source code to 'fonttools' folder
41 git clone https://github.com/fonttools/fonttools.git
42 cd fonttools
43
44 # create new virtual environment called e.g. 'fonttools-venv', or anything you like
45 python -m virtualenv fonttools-venv
46
47 # source the `activate` shell script to enter the environment (Unix-like); to exit, just type `deactivate`
48 . fonttools-venv/bin/activate
49
50 # to activate the virtual environment in Windows `cmd.exe`, do
51 fonttools-venv\Scripts\activate.bat
52
53 # install in 'editable' mode
54 pip install -e .
55
56Optional Requirements
57---------------------
58
59The ``fontTools`` package currently has no (required) external dependencies
60besides the modules included in the Python Standard Library.
61However, a few extra dependencies are required by some of its modules, which
62are needed to unlock optional features.
63The ``fonttools`` PyPI distribution also supports so-called "extras", i.e. a
64set of keywords that describe a group of additional dependencies, which can be
65used when installing via pip, or when specifying a requirement.
66For example:
67
68.. code:: sh
69
70 pip install fonttools[ufo,lxml,woff,unicode]
71
72This command will install fonttools, as well as the optional dependencies that
73are required to unlock the extra features named "ufo", etc.
74
75- ``Lib/fontTools/misc/etree.py``
76
77 The module exports a ElementTree-like API for reading/writing XML files, and
78 allows to use as the backend either the built-in ``xml.etree`` module or
79 `lxml <https://lxml.de>`__. The latter is preferred whenever present,
80 as it is generally faster and more secure.
81
82 *Extra:* ``lxml``
83
84- ``Lib/fontTools/ufoLib``
85
86 Package for reading and writing UFO source files; it requires:
87
88 * `fs <https://pypi.org/pypi/fs>`__: (aka ``pyfilesystem2``) filesystem
89 abstraction layer.
90
91 * `enum34 <https://pypi.org/pypi/enum34>`__: backport for the built-in ``enum``
92 module (only required on Python < 3.4).
93
94 *Extra:* ``ufo``
95
96- ``Lib/fontTools/ttLib/woff2.py``
97
98 Module to compress/decompress WOFF 2.0 web fonts; it requires:
99
100 * `brotli <https://pypi.python.org/pypi/Brotli>`__: Python bindings of
101 the Brotli compression library.
102
103 *Extra:* ``woff``
104
105- ``Lib/fontTools/ttLib/sfnt.py``
106
107 To better compress WOFF 1.0 web fonts, the following module can be used
108 instead of the built-in ``zlib`` library:
109
110 * `zopfli <https://pypi.python.org/pypi/zopfli>`__: Python bindings of
111 the Zopfli compression library.
112
113 *Extra:* ``woff``
114
115- ``Lib/fontTools/unicode.py``
116
117 To display the Unicode character names when dumping the ``cmap`` table
118 with ``ttx`` we use the ``unicodedata`` module in the Standard Library.
119 The version included in there varies between different Python versions.
120 To use the latest available data, you can install:
121
122 * `unicodedata2 <https://pypi.python.org/pypi/unicodedata2>`__:
123 ``unicodedata`` backport for Python 3.x updated to the latest Unicode
124 version 15.0.
125
126 *Extra:* ``unicode``
127
128- ``Lib/fontTools/varLib/interpolatable.py``
129
130 Module for finding wrong contour/component order between different masters.
131 It requires one of the following packages in order to solve the so-called
132 "minimum weight perfect matching problem in bipartite graphs", or
133 the Assignment problem:
134
135 * `scipy <https://pypi.python.org/pypi/scipy>`__: the Scientific Library
136 for Python, which internally uses `NumPy <https://pypi.python.org/pypi/numpy>`__
137 arrays and hence is very fast;
138 * `munkres <https://pypi.python.org/pypi/munkres>`__: a pure-Python
139 module that implements the Hungarian or Kuhn-Munkres algorithm.
140
141 To plot the results to a PDF or HTML format, you also need to install:
142
143 * `pycairo <https://pypi.org/project/pycairo/>`__: Python bindings for the
144 Cairo graphics library. Note that wheels are currently only available for
145 Windows, for other platforms see pycairo's `installation instructions
146 <https://pycairo.readthedocs.io/en/latest/getting_started.html>`__.
147
148 *Extra:* ``interpolatable``
149
150- ``Lib/fontTools/varLib/plot.py``
151
152 Module for visualizing DesignSpaceDocument and resulting VariationModel.
153
154 * `matplotlib <https://pypi.org/pypi/matplotlib>`__: 2D plotting library.
155
156 *Extra:* ``plot``
157
158- ``Lib/fontTools/misc/symfont.py``
159
160 Advanced module for symbolic font statistics analysis; it requires:
161
162 * `sympy <https://pypi.python.org/pypi/sympy>`__: the Python library for
163 symbolic mathematics.
164
165 *Extra:* ``symfont``
166
167- ``Lib/fontTools/t1Lib.py``
168
169 To get the file creator and type of Macintosh PostScript Type 1 fonts
170 on Python 3 you need to install the following module, as the old ``MacOS``
171 module is no longer included in Mac Python:
172
173 * `xattr <https://pypi.python.org/pypi/xattr>`__: Python wrapper for
174 extended filesystem attributes (macOS platform only).
175
176 *Extra:* ``type1``
177
178- ``Lib/fontTools/ttLib/removeOverlaps.py``
179
180 Simplify TrueType glyphs by merging overlapping contours and components.
181
182 * `skia-pathops <https://pypi.python.org/pypy/skia-pathops>`__: Python
183 bindings for the Skia library's PathOps module, performing boolean
184 operations on paths (union, intersection, etc.).
185
186 *Extra:* ``pathops``
187
188- ``Lib/fontTools/pens/cocoaPen.py`` and ``Lib/fontTools/pens/quartzPen.py``
189
190 Pens for drawing glyphs with Cocoa ``NSBezierPath`` or ``CGPath`` require:
191
192 * `PyObjC <https://pypi.python.org/pypi/pyobjc>`__: the bridge between
193 Python and the Objective-C runtime (macOS platform only).
194
195- ``Lib/fontTools/pens/qtPen.py``
196
197 Pen for drawing glyphs with Qt's ``QPainterPath``, requires:
198
199 * `PyQt5 <https://pypi.python.org/pypi/PyQt5>`__: Python bindings for
200 the Qt cross platform UI and application toolkit.
201
202- ``Lib/fontTools/pens/reportLabPen.py``
203
204 Pen to drawing glyphs as PNG images, requires:
205
206 * `reportlab <https://pypi.python.org/pypi/reportlab>`__: Python toolkit
207 for generating PDFs and graphics.
208
209- ``Lib/fontTools/pens/freetypePen.py``
210
211 Pen to drawing glyphs with FreeType as raster images, requires:
212
213 * `freetype-py <https://pypi.python.org/pypi/freetype-py>`__: Python binding
214 for the FreeType library.
215
216- ``Lib/fontTools/ttLib/tables/otBase.py``
217
218 Use the Harfbuzz library to serialize GPOS/GSUB using ``hb_repack`` method, requires:
219
220 * `uharfbuzz <https://pypi.python.org/pypi/uharfbuzz>`__: Streamlined Cython
221 bindings for the harfbuzz shaping engine
222
223 *Extra:* ``repacker``
224
225How to make a new release
226~~~~~~~~~~~~~~~~~~~~~~~~~
227
2281) Update ``NEWS.rst`` with all the changes since the last release. Write a
229 changelog entry for each PR, with one or two short sentences summarizing it,
230 as well as links to the PR and relevant issues addressed by the PR. Do not
231 put a new title, the next command will do it for you.
2322) Use semantic versioning to decide whether the new release will be a 'major',
233 'minor' or 'patch' release. It's usually one of the latter two, depending on
234 whether new backward compatible APIs were added, or simply some bugs were fixed.
2353) Run ``python setup.py release`` command from the tip of the ``main`` branch.
236 By default this bumps the third or 'patch' digit only, unless you pass ``--major``
237 or ``--minor`` to bump respectively the first or second digit.
238 This bumps the package version string, extracts the changes since the latest
239 version from ``NEWS.rst``, and uses that text to create an annotated git tag
240 (or a signed git tag if you pass the ``--sign`` option and your git and Github
241 account are configured for `signing commits <https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification/signing-commits>`__
242 using a GPG key).
243 It also commits an additional version bump which opens the main branch for
244 the subsequent developmental cycle
2454) Push both the tag and commit to the upstream repository, by running the command
246 ``git push --follow-tags``. Note: it may push other local tags as well, be
247 careful.
2485) Let the CI build the wheel and source distribution packages and verify both
249 get uploaded to the Python Package Index (PyPI).
2506) [Optional] Go to fonttools `Github Releases <https://github.com/fonttools/fonttools/releases>`__
251 page and create a new release, copy-pasting the content of the git tag
252 message. This way, the release notes are nicely formatted as markdown, and
253 users watching the repo will get an email notification. One day we shall
254 automate that too.
255
256
257Acknowledgements
258~~~~~~~~~~~~~~~~
259
260In alphabetical order:
261
262aschmitz, Olivier Berten, Samyak Bhuta, Erik van Blokland, Petr van Blokland,
263Jelle Bosma, Sascha Brawer, Tom Byrer, Antonio Cavedoni, Frédéric Coiffier,
264Vincent Connare, David Corbett, Simon Cozens, Dave Crossland, Simon Daniels,
265Peter Dekkers, Behdad Esfahbod, Behnam Esfahbod, Hannes Famira, Sam Fishman,
266Matt Fontaine, Takaaki Fuji, Rob Hagemans, Yannis Haralambous, Greg Hitchcock,
267Jeremie Hornus, Khaled Hosny, John Hudson, Denis Moyogo Jacquerye, Jack Jansen,
268Tom Kacvinsky, Jens Kutilek, Antoine Leca, Werner Lemberg, Tal Leming, Peter
269Lofting, Cosimo Lupo, Olli Meier, Masaya Nakamura, Dave Opstad, Laurence Penney,
270Roozbeh Pournader, Garret Rieger, Read Roberts, Colin Rofls, Guido van Rossum,
271Just van Rossum, Andreas Seidel, Georg Seifert, Chris Simpkins, Miguel Sousa,
272Adam Twardoch, Adrien Tétar, Vitaly Volkov, Paul Wise.
273
274Copyrights
275~~~~~~~~~~
276
277| Copyright (c) 1999-2004 Just van Rossum, LettError
278 ([email protected])
279| See `LICENSE <LICENSE>`__ for the full license.
280
281Copyright (c) 2000 BeOpen.com. All Rights Reserved.
282
283Copyright (c) 1995-2001 Corporation for National Research Initiatives.
284All Rights Reserved.
285
286Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All
287Rights Reserved.
288
289Have fun!
290
291.. |CI Build Status| image:: https://github.com/fonttools/fonttools/workflows/Test/badge.svg
292 :target: https://github.com/fonttools/fonttools/actions?query=workflow%3ATest
293.. |Coverage Status| image:: https://codecov.io/gh/fonttools/fonttools/branch/main/graph/badge.svg
294 :target: https://codecov.io/gh/fonttools/fonttools
295.. |PyPI| image:: https://img.shields.io/pypi/v/fonttools.svg
296 :target: https://pypi.org/project/FontTools
297.. |Gitter Chat| image:: https://badges.gitter.im/fonttools-dev/Lobby.svg
298 :alt: Join the chat at https://gitter.im/fonttools-dev/Lobby
299 :target: https://gitter.im/fonttools-dev/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
300