olikraus / u8glib

Arduino Monochrom Graphics Library for LCDs and OLEDs
https://github.com/olikraus/u8glib/wiki
Other
1.24k stars 313 forks source link

Fonts have no kerning. #436

Closed alidaf closed 7 years ago

alidaf commented 7 years ago

I've created a new font in 16, 24 and 32 pixel sizes but displaying them on screen is awful due to the lack of kerning. I don't know whether this is an issue with gbdedit, bdf2u8g or just my lack of understanding of the limitations of the u8g font system. The Adafruit format packs the bits so that there is some degree of proportioning the gaps between letters.

olikraus commented 7 years ago

Do you mean kerning or variable-width font? U8g2 supports non-monospaced fonts. The glyph specific width must be specified in the font source (ttf or bdf file.

Specific distance between two specific glyphs (kerning) is partly supported by u8g2. But except for u8g2 i do not know any embedded graphics lib, which supports this.

alidaf commented 7 years ago

It's gbdfed! It's such a horribly non-intuitive program. I can't figure out how to trim the excessive widths after converting TTFs to bdf. Building the fonts from scratch works allows non-monospaced fints and bdf2u8g works but defining the glyphs is a labour of love. It may be worthwhile adding an option to bdf2ug8 to remove width padding or specify the pixel width gaps. I also fell foul of bdf2ug8's requirement to have the 'A' character defined otherwise it will fill all glyphs with 255 when testing the fonts with only a few glyphs defined.

olikraus commented 7 years ago

Your update requests are (at least partly) implemented for u8g2 which has also a new bdf2u8g tool (jet it is called "bdfconv" in u8g2)

Instead of gbdfed I use "fony" for windows. Fony nicely supports variable width glyphs.

As a workaround you could also patch bdf file after ttf conversion before feeding into bdf2u8g.

alidaf commented 7 years ago

Thanks for that. I've been trying to have a think about how to go about it myself by checking for overlap of adjacent letters (actual letters rather than bounding boxes) by incrementally merging them and then reversing one or two pixels. I redid all of the fonts in fony (using Wine) from scratch and there is a huge improvement but L next to T for example, looks really odd because of the space.

olikraus commented 7 years ago

Yes, the L to T issue is there. Indeed there are a lot of other combinations like W and A. So in general a mapping table with n*n entries is required, where n is the number of glyphs. Did some tests here in the past and it consumes a lot of memory. Also removing entries with very low or zero kerning value, the table is still huge. One more problem is the fact, that this information is no there in BDF files at all.

All in all, i decided to remove this feature again from u8g2 (it is not there at all in u8glib), because i think this is a very advanced feature for high powered computer systems, but not something, which is needed for a small embedded controller. Nevertheless you can provide your custom table in u8g2, which means you have full controll on the gylph combinations.

alidaf commented 7 years ago

My first thought was a table but I wasn't sure whether each letter of a string was drawn to the display in turn rather than as a composited image. If the latter, then my thought was to shift the rightmost letter of a pair left, AND it until there is a collision, shift it back right a fixed number of pixels, and then OR the character into the composite image. It's a lot of additional computation and you are right in arguing that it is after all, an embedded controller and there should be a limit to expectation. But, OCD!

olikraus commented 7 years ago

I did exactly this kind of shifting (object collision detection) offline to calculate the missing kerning values. Then i created a (compressed) table of kerning values, but still it was too huge.