Over a year ago I spent some time working with e-paper displays and I did some research on using custom fonts for displaying text. I ended up writing a small app for preparing such fonts (it actually was an iteration over someone else’s idea). The app would take a predefined image containing font glyphs, and given font width and height in pixels, it would transform it to a source code file.

While this was a working solution, proven many times and even used by some people other than me, using it was a bit cumbersome in the long run. Some of the major pain points were the following:

  • the font image had to be edited in an image editing app (such as GIMP, Photoshop, etc.) prior to converting it to source code,
  • to effectively work with a font image, a proper template image was needed (so that you knew the bounds of a glyph you wanted to edit); people were sometimes contacting me and asking for help in generating a template image with a given font size.

That app was just too complicated for casual use. I then decided to try and come up with an app that’s easier to use and doesn’t depend on external editing software.

What if you could just select a font and export it to source code?

This is FontEdit – the app that does just that: import, preview, edit and export a font for use in embedded systems’ displays.

Here's how you import a font into FontEdit.
Here's how you import a font into FontEdit.

FontEdit can open any general-purpose fixed-width desktop font. You can use custom fonts, but (at least for now) they have to be registered in your operating system. The app automatically imports font glyphs for characters in the ASCII printable range (32…126 or 0x20…0x7e). Once the font is imported, you will see the list of all available glyphs and an edit view where individual glyphs can be fine tuned.

Viewing an imported font.
Viewing an imported font.

Imported font size

Notice the gray rows on the top and bottom of the edit view. The glyph size is decided by the app at the time of import and it’s based on font metrics. Most of the time it’s too tall and none of the imported glyphs use some of the rows at both ends. The app calculates these margins at import time and by default doesn’t include them in the exported source code (to limit the memory footprint of the exported font).

Font Editor

You can edit font glyphs with a minimal editor that’s controlled with a mouse and keyboard. Click and drag the mouse to set pixels (making them black), hold Alt or Ctrl (⌘) to erase. Use touchpad scroll (mouse wheel) with Ctrl (⌘) to zoom the editor canvas.

Editing a Glyph.
Editing a Glyph.

You can also reset the current glyph or the whole font to their initial state (from latest save). The editor supports Undo/Redo for most operations.

Adding custom Glyphs

Besides editing imported glyphs, you can also add new glyphs to a font document – either by copying an existing glyph, starting from scratch with a blank canvas or adding a glyph from a character you put in (useful for adding non-ASCII characters to your font).

Adding a new Glyph.
Adding a new Glyph.

The additional glyphs are appended to the printable ASCII set starting fom ASCII code 127 (0x7f). As non-printable characters, they have to be referenced in your app’s source code by their hex code, e.g.:

printf("Total price: 7.50\x84"); // where 0x84 corresponds to the € symbol
printf("\x80 2020 Dominik Kapusta"); // 0x80 is a © symbol
Custom Glyphs added in the lower half of ASCII table.
Custom Glyphs added in the lower half of ASCII table.

Source code export

The source code representation can be previewed at any time. The font data can be exported to:

  • a C file (also suitable for use with C++),
  • an Arduino-specific C file (using PROGMEM),
  • a Python list or bytes object (both compatible with Python 2.x/3.x and MicroPython).

You can switch between MSB and LSB mode, invert all the bits, and conditionally include line spacings in font definition (not recommended unless you have a very good reason to do it). You can also configure the tab size and the font array name.

Source code preview.
Source code preview.

Saving progress and portability

You can save your work on a font at any time and resume it later. Note that this is not equivalent to exporting the source code – the app saves a binary font document with additional metadata of your font.

The saved document can be transferred to another machine (even across operating systems) where it can be further adjusted. The limitation here is that you won’t be able to add new glyphs using the “keyboard input” method unless the original font is available on the OS you’re working on. For example, if you import Consolas font on Windows and open your document on a Mac (where Consolas is not present), adding a new glyph would be limited to an empty glyph or a copy of an existing glyph.

Ubuntu Mono 20pt on a Waveshare E-Paper display connected to Raspberry Pi.
Ubuntu Mono 20pt on a Waveshare E-Paper display connected to Raspberry Pi.

Get the app

The app is written in C++17 with UI in Qt and I tested it on MacOS, Linux (Ubuntu 18.04 and 19.10), Windows 10 and Raspbian Buster. I put some effort into optimizing performance, and so it works smoothly even on my Raspberry Pi 3B.

The source code is available from GitHub, but there are packages available from GitHub Releases page with binaries for platforms mentioned above. FontEdit is distributed under the conditions of GPL v3.

Although it’s only a first release, it already comes with features of some real value, and I plan to continue working on the app in my spare time to make it even more powerful and versatile. If you happen to use the app, feel free to report bugs and feature requests via GitHub Issues or as a pull request.


FontEdit running on Raspberry Pi 3 with Raspbian Buster
FontEdit running on Raspberry Pi 3 with Raspbian Buster.