Pavel Marceluch

Prague public transport font files

After my visit of LinuxDays 2024 in Prague, I was sure of one thing: I need to own a tram flip-dot display. So I got one immediately the next day!

I’ve been working on a custom driver ever since. I also tried to reverse-engineer the font files used by these displays. And I have succeeded! I got to the .fnt files by finding HEX files on the internet. HEX files contain everything the information system needs, like the destinations, line numbers, stops, and most importantly, the font used to render this information on the flip-dot displays. I also found the gBuse.exe program which can edit these HEX files. It can also export just the fonts into an .fnt file, which is very convenient, since the HEX files are a total mess and I have not been able to reverse them just yet.

Let’s take a look at one of these font files:


Font data

Each font of the family starts with three bytes.
0xE0 0x04 0xD5
The first byte is the font ID starting from 0xE0 counting up.
The other two bytes are the length of the font (in this example the font is 1237 bytes long).


Character data

Let’s see how each letter is stored in the font. For example the uppercase letter B:
This is the data that we are interested in: 0x4280A3F80248024801B00

Let’s turn it into binary so we can better understand whats going on.

The first byte is saying that this character corresponds to number 66.
The second and third bytes mean that the image is 8 bytes long and each column is 10 pixels high.
We can then read the next 8 bytes. Pick 10 pixels and discard the remainder of each byte.
The image is saved column by column from left to right.

I remapped all characters to unicode for easier indexing. This is the font ID 5 from the newest version I could get my hands on.
Ironically, these were not ripped from a .fnt file, but from a public PDF with a python script ripping the PDF into pieces. I can’t write python so I had one of my friends do it for me. Thanks Alex!


End of file look up table

After every image is read, there is still some data left in the file. This seems to be a look up table into the Windows 1250 encoding. If you use the character number from each image, you can find out which symbol it corresponds to.

Let’s take the letter Š. In the .fnt file, it is saved under 0x9B (155). In the lookup table, the entry corresponding to 155 is 0x8A, which is the letter Š in the Windows 1250 encoding.


Icons

The fonts don’t contain only characters though. They also contain many symbols and icons used by the trams. These are sometimes mapped to characters like “{“ so that they can be easily written into the destinations.
Here are some of the icons I extracted from the font files. I renamed them my self so that I can easily index them, but I am not sure with the purpose of some of them.

If you have a photo of an actual tram or a bus with any of these symbols, please let me know!


You can download a zip of the converted PDF fonts and all icons right here. Icons are named by me, characters are remapped to Unicode.

Tags: