Contributing to FontForge
Reporting An Issue
Merging into the master branch requires review and approval of the pull request by an active core contributor to the project. The reviewer must fully comprehend the code being modified, and any changes must be strictly non-regressive and non-breaking unless discussed in advance on the mailing list. FontForge is an extremely complex piece of software, and keeping it in top form requires this level of care. Please understand that large pull requests may take a long time to be approved or may be declined, even if well written, due to limited code review resources.
How To Contribute, Step by Step
Contribute directly to the codebase using GitHub's Pull Requests. See Github Guides to learn more, but the basic process is:
- Fork the FontForge repository from GitHub.
- Commit your changes locally using
git, and push them to your personal fork.
- From the main page of your fork, click on the green “Fork” button in order to submit a Pull Request.
- Your pull request will be tested via GitHub Actions to automatically indicate that your changes do not prevent compilation. FontForge is a big program, so it can easily take over 20 minutes to confirm your changes are buildable. Please be patient. More details about CI are below.
- If it reports back that there are problems, you can follow the "Details" link to check the log report for your pull request to see what the problem was.
FontForge supports Python
>= 3.3 and is fully compatible with Python 3 through at least version 3.9.
Some of these guidelines are not followed in the oldest code in the repository, however we want to use them for all new code since 2012 when FontForge transitioned from a lone-genius project to a collaborative community project.
- One statement per line, to make semi-automatic processing and reading of diffs much easier.
- Boolean Variables should use
false, not an integer (reference).
returnstatements should be inline with the indentation level they are being put on; don't put them at the left margin as in much of the existing code (reference).
Beyond these guidelines, try to follow the style used in the file being modified.
People To Ask
Various areas of the codebase have been worked on by different people in recent years, so if you are unfamiliar with the general area you're working in, please feel free to chat with people who have experience in that area:
- Build System: Debian - Frank Trampe (frank-trampe)
- Build System: OS X (Application bundle, Homebrew) - Jeremy Tan (jtanx)
- Build System: Windows - Jeremy Tan (jtanx)
- Feature: UFO import/export - Frank Trampe (frank-trampe)
- Feature: Python interface - Skef Iterum (skef)
- Crashes: Frank Trampe, Adrien Tetar (adrientetar)
Accessing CI Build Archives
After each push request
Appveyor will attempt to build and package
a Windows installer. When that build is successful it can be accessed
by following the
Appveyor "Details" link and choosing the "Artifacts"
Appveyor builds with the
FF_PORTABLE flag, which changes various
initialization and configuration search paths.
CI via Github Actions also builds a Mac OS X bundle and a Linux AppImage. When those builds are successful they can be downloaded from:
We are trialling the use of Crowdin for handling translations. If you'd like to contribute translations for FontForge, please do so here: https://crowdin.com/project/fontforge
These will be pulled in for the next release of FontForge.
For information about building FontForge from source, please refer to INSTALL.md
If you want to edit CID keyed fonts you need the character set descriptions in
You might want to pull down some old unicode bitmap fonts.
- The unifont
- The FreeFont project
- X fixed
- Computer Modern Unicode fonts - Unicode Font Guide for Free/Libre Open Source Operating Systems
Building a Debian source package
A Debian source package consists of a source tarball (with specific metadata) and several accompanying files and allows one to build a product in a neutral build environment.
A source package is specific to the distribution (but not the architecture) that it targets. The most common build target is currently Ubuntu Xenial, a long-term support release with Launchpad build support. A binary package built on and for Xenial (usually) also installs and runs on later versions of Ubuntu.
The first step is to obtain a dist tarball. To generate this from git sources, change into the source directory and run
mkdir build && cd build cmake .. make dist
This will generate an archive with a name similar to
fontforge-20190801.tar.xz. Move/extract this to a working folder of your choice and run
tar axf fontforge-20190801.tar.xz cd fontforge-20190801 Packaging/debian/setup-metadata.sh
This will copy required metadata into the toplevel
debian folder. It will also prompt to generate
debian/changelog, if desired. In this state, the Debian source packages may be created by running:
debuild -S -sa
Upon successful completion, building of the source package will leave several files in the parent directory, with names like this:
fontforge-20190801-0ubuntu1~xenial.dsc fontforge-20190801-0ubuntu1~xenial_source.build fontforge-20190801-0ubuntu1~xenial_source.changes fontforge-20190801-0ubuntu1~xenial.tar.gz
In order to upload to a Launchpad repository for building, one can then run dput on the
.changes file with the target repository as the first argument, like this:
dput ppa:fontforge/fontforge fontforge-20190801-0ubuntu1~xenial_source.changes
This will, upon success, leave a file named something like
fontforge-20190801-0ubuntu1~xenial_source.ppa.upload which blocks duplicate uploads.
Upon validation of the uploaded package, Launchpad will build the package for all supported architectures. One can then copy the binary packages from Xenial to other Ubuntu versions via the Launchpad web interface.
See here for more information about Launchpad.
One can also build a binary package from the source package locally.
Simply extract the
tar.gz file generated from
make deb-src into a new directory, enter the directory, and run
Building a Red Hat source package (.rpm)
Run the following to get a spec file:
This will create a
In order to build the binary package locally, copy the dist archive (as per Debian instructions) to
~/rpmbuild/SOURCES and the spec file to
~/rpmbuild/SPECS. Then run
rpmbuild -ba ~/rpmbuild/SPECS/FontForge.spec.
mkdir -p ~/rpmbuild/SOURCES/ cp TARBALL ~/rpmbuild/SOURCES/ rpmbuild -ba --nodeps SPECFILE
Upon success, this will leave binary packages in
~/rpmbuild/RPMS and source packages in
You may need to install dependencies, typically packaged for Fedora-derived systems as:
rpm-devel rpm-build git ninja-build cmake gcc g++ python3-devel libjpeg-devel libtiff-devel libpng-devel giflib-devel freetype-devel libxml2-devel libuninameslist-devel libspiro-devel pango-devel cairo-devel gtk3-devel
Building a Mac OS X app bundle
There is a target to build an app bundle:
This will create a
FontForge.app in the
osx subdirectory of your build directory.
This relies on
ffosxbuild.sh to make the bundle. It has been tested to work with Homebrew and the GDK backend.