Close

A Focus On Software

A project log for PolyKybd (Displays In Your Keycaps)

Freedom at your fingertip.

thpollthpoll 03/28/2023 at 08:200 Comments

Let me talk a little bit about software, since this also takes time - apart from my hardware challenges!

Okay, so next to my QMK keyboard firmware, I need some glyph rendering for my OLED screens. To truly support multiple languages, I have handle characters beyond ASCII-7/8.

Initially, I started to use the Adafruit-GFX Library as base, which provides the rendering of basic ASCII characters (a font has to be converted to pixel data from a .tft or .oft file of choice).

To support characters for Japanese, Korean, Arabic, etc. I had to first extend all std::sting / const char* to std::u16string (I know there are 4 byte characters, but for my use cases, 2 bytes are enough for now), which wasn't a big deal.

Next, I needed to extend my own interface of the keyboard firmware to provide other fonts (pixmaps) for the new character ranges. For instance Japanese Hiragana characters are in the range from 12353 to 12447 (instead of the printable ASCII range from `space` 32 to `tilde` 126). To do that, my font rendering accepts an array of fonts and tries to find the matching character in the range of the first provided font and looks up in the next font if that fails.

To prove that this approach works, I started manually patching the generated font files (.h files), but over time it became a burden and so I decided to update the fontconverter as well.

Also here, the first step was to extend indices from 1 byte to 2 bytes and remove checks that narrowed the output to the ASCII range. For more convenience my fontconverter version also allows multiple ranges, eg from 32-126 and from 138-142 at once. However, due to some restrictions in the font rendering library the entries of characters in-between the ranges will be filled up with zeros. So, if the gap between two ranges is big it might be still better to split that up into two separate ranges (a lot of zero also need some space).

You can find that fonconvert version here: https://github.com/thpoll83/Adafruit-GFX-Library

Let me show you a small example to generate all isolated Korean vowels (I'm using Google's Noto Korean font - you can use any font that has Korean vowels), which I can specify with 3 ranges 0x1161 to 0x1169, 0x116d to 0x116e and 0x1172 to 0x1175:

In the output you can see some zero-ed entries in-between the ranges as described - annotated with 'skip'. You might have noticed the slightly changed parameters, so here is the `usage` output:

I usually evaluate the result right away with this awesome online tool: https://tchapi.github.io/Adafruit-GFX-Font-Customiser/ You can just copy & paste the output and it will visualize the generated pixel font. In addition allows you to modify the font as well. A really useful tool, which thankfully also works despite my changes to the output format:

If everything fits, the generated text goes into a .h file, which is than used by my QMK firmware, which you can find here: https://github.com/thpoll83/qmk_firmware

There wasn't much progress on the firmware recently as I was on a holiday break with my family ;) I hope you enjoyed this software post and see you next time!

Discussions