Today I’m writing about a new project that I’ve started to create a font, called “Thermal Sans Mono”. I’m hoping to make this into a set of specialized free bitmap fonts for use on thermal receipt printers and printer emulators.
Here is what it looks like so far:
In this blog post I’ll talk a bit about why I needed a new font, how it’s derived from GNU Unifont, and what I’m planning to do with it.
Background
Firstly, I am solving a technical problem, not a design problem.
Printing non-ASCII characters on receipts can get a bit complex, especially if you have a lot of different printers to support. Each thermal receipt printer has a different set of available “code pages” of glyphs, which makes localisation a real adventure.
Using the escpos-printer-db project, we can currently create software which accepts UTF-8 text, and switches between the available code pages to render text for a specific printer. I’m now looking at how we can encode characters that are not not in any available code page.
For example, in this code from the python-escpos
library, the ?
subsitution character still has to be printed for some characters:
encoding = self.encoder.find_suitable_encoding(text[0])
if not encoding:
self._handle_character_failed(text[0])
Rather than send a ?
character, I think we could retrieve a glyph from a suitable font and send it as a bitmap instead. I previously wrote about a technique to cache glyphs from GNU Unifont in printer memory, but these glyphs don’t have the correct size or weight to be displayed alongside the glyphs that the printer has rendered itself.
Of course we can’t do this yet, because there is no suitable bitmap font.
How it’s made
The closest font to what we need is GNU Unifont, which is thankfully freely licensed. A Unifont glyph is typically 8×16 with a thin line and a lot of whitespace, while I need to print in 12×24, with thick lines and no whitespace.
To control as many variables as possible, I decided to pre-render a transformed version of GNU Unifont. This involved tracing the original glyph and re-drawing it with new parameters.
The first step is to use a purpose-built algorithm to trace the lines from the glyph:
The points are then re-drawn onto a new canvas with a thicker outline, and a lot less whitespace.
When this canvas is scaled back to 12×24, we have our glyph.
This glyph is now the correct size and weight for use on most thermal receipt printers.
Roadmap
Currently, I have only processed the ASCII characters. As a GNU Unifont derivative, we should (with some effort) be able to include many more glyphs in the future.
As a starting goal, I am aiming to make the font complete enough to include as a fallback font in the escpos-php
printing library.
Download
I’ve made my initial work work on “Thermal Sans Mono” available as a bitmap font PCF and BDF format on GitHub. You can find these in the “Releases” section of the GitHub project.
As always, bugs, comments and suggestions are appreciated.
Hiya,
Is it by anyway available as an opentype or TrueType (otf or ttf) formats? I tried the to unzip the GZ file I found on your GitHub page; yet it requires a password.
Let me know if it’s available – I want to test using it for a personal / non-commercial project.
Thanks
@Omar – Each of the “releases” on GitHub contains a .tar.gz file, which contains Thermal Sans Mono 24 and Thermal Sans Mono 17 in BDF and PCF formats. These are both bitmap font formats.
TTF/OTF are outline/vector font formats. A web search turns up tools which can convert bitmap font files into outline font files, though I’m unlikely to provide these files as part of the project, since the font is not designed for that usage.