peterhinch / micropython-font-to-py

A Python 3 utility to convert fonts to Python source capable of being frozen as bytecode
MIT License
385 stars 69 forks source link

Character spacing is poor #20

Closed ironss closed 4 years ago

ironss commented 4 years ago

All character bitmaps are left-aligned: the left-most pixel is at the left-edge of the bitmap. All of the blank space (if any) is at the right-hand edge of the bitmap. Characters such as 'A', 'V' and 'Y' do not have any blank space at either edge. As a result, these characters collide with other characters with vertical left-edge ('B', 'E', '[', '|').

The code ignores the bitmap_left parameter, which indicates how much blank space there should be on the left-side of the bitmap.

Commit https://github.com/ironss/micropython-font-to-py/commit/44ce092045f228981f8511616e72da047714acdb adds code to move the generated bitmap to where it should be.

peterhinch commented 4 years ago

[EDIT] I have pushed an update including the bugfix and your suggested changes. I have acknowledged your contribution in the doc.

Thank you for this useful fix.

ironss commented 4 years ago

I have found that this introduces 2 new issues depending on the font and the character size.

These effects are intended to give better character spacing. This is sometime called 'kerning', but that word really means the changed character spacing between specific character-pairs, not the general spacing for a single character.

DejaVu Sans capital-J at sizes 20, 24 and 32 (and probably most other sizes) has a negative bitmap_left parameter. This means that the bottom of the J protrudes into the preceding character space. The problem is that the generated bitmap has the offending pixels on the end of the row above where they should be.

DejaVu Sans capital-K at sizes 20, 24 and 32 (probably most other sizes) has bitmap wider than left+advance. The bottom leg of the K protrudes into the next character space. This problem is that the generated bitmap has the offending pixels on the start of the next row down.

There are three alternatives:

I suggest the last option.

I have a fix for the negative-bitmap_left (https://github.com/ironss/micropython-font-to-py/commit/b572029bea7d08687710adf7b0cadcf6c76ad575) but am still working on the bitmap-wider-than-advance.

I suspect that the whole character-width calculation (around line 335--340) will need to change.

To see these effects, add some debug output (https://github.com/ironss/micropython-font-to-py/commit/6606f31b069c8c92b0fcdd9f0803d1d4b9bf77d8, where each occurrence of command-line option -v increases debug verbosity), then run

and look at characters J and K.

peterhinch commented 4 years ago

The last option sounds simplest.

ironss commented 4 years ago

I created a new issue, and implemented a fix https://github.com/ironss/micropython-font-to-py/commit/e73da4cbbd669148d486b0717c793a5415ce32a2 that creates correct bitmaps for (at least) DejaVu San J, K and R at various sizes.