3
\$\begingroup\$

I'm looking for a small variable width font that can be used on small LCD screens (in this case a 128x64 pixel screen). I'd like it to have a height of 8 pixels or less, so that the characters will be displayed on one line of the screen. I've tried using programs such as "The Dot Factory" and "GLCD Font Creator", but it seems they are ill-suited for such small fonts.

\$\endgroup\$
  • 1
    \$\begingroup\$ I don't want to discourage you, but there's a lot more to variable width fonts than the bitmaps. If you don't apply kerning they usually don't look much better than fixed width fonts, which are a million times easier to work with than kerned fonts. \$\endgroup\$ – stevenvh Jul 31 '12 at 16:01
  • \$\begingroup\$ The minimum horizontal pitch for a nicely-legible fixed-width font is six. Variable-width fonts can offer comparable legibility with an average pitch of five or even four. At such sizes, the goal isn't so much to make things look gorgeous, so much as it is to fit the content on the screen legibly. If nothing else, allow M's and W's to have six-pixel pitch without requiring all the other characters to do so as well (indeed, I've sometimes seen code which stores four pixels of font data for every character, and adds a hard-coded right column and blank column for "M" and "W"). \$\endgroup\$ – supercat Jul 31 '12 at 16:30
9
\$\begingroup\$

I do want to encourage you. Ahh, this brings back so many happy memories of my childhod, learning to program. This was before the days of the internet of course, so practically everything had to be invented on the fly. One of the things I figured out how to do was handle tiny bitmapped fonts. Then I realised that, if I gave each character as much space as an M needed, then the 'i' would look kind of lost in there. So I had to invent kerning, and how to implement it. It's actually quite easy, so don't let any people put you off.

You didn't say what kind of format you want the font it, so I won't go into that area. Firstly, choose a font. There's a bunch of nice ones on DaFont.

I'd start with a single image containing the font.

Tiny font

Here I have drawn 8x8mm grey squares behind each character, just to show you the spacing. There's no need to have them there really. Each character is left justified. Next, you write a program to import the image, and search through each 8x8 square to find the width of the character. This program converts each character into the binary format that most suits your application, and also stores the width of each character along with the data. When you come to render the characters on the LCD screen, you'll be able to use the width data to position each character right next to the previous one (+1 pixel for a little space).

This kind of very basic kerning is really all you need when you're working with fonts of this size. It's certainly all you need for that particular font, where all of the characters are pretty square.

In fact, you'll be hard pushed to even find a tiny font that needs real kerning. There were none on the first 14 pages of that DaFont link above. Finally, on page 15, I found the ISL Onyx font.

ISL Onyx Font

How to do real kerning on a tiny font? This time, when your program scans each character, it will need to measure the distance between the character and the left and right edges, for each row of pixels:

Kerning a tiny font

If there's a blank line, then just make the values about half the width of the font, or use the highest value from the non-blank lines.

Now, rendering takes a little longer. When you place each character, you need to compare the first character's right hand column of numbers with the next character's left hand column of numbers.

Add the two columns, and subtract 2. (2 = minimum distance between characters) This gives us the column of numbers in red.

Kerning a tiny font

Find the smallest number in the column and negate it. This number tells us how many pixels to the right we need to place the next character. In this case, zero. We can place the V right up against the A, and there will still be two pixels between them.

What about two As?

Kerning a tiny font

This time, the smallest number is -2, meaning that we should place the next A two pixels further to the right to leave two pixels between them.


Storage requirements

How many bytes is all of this going to take up? Assuming all of the characters fit within 8x8 pixels, you'll need 8 bytes to store the pixels themselves. Simple kerning adds one byte per character. Complex kerning only adds 8 bytes. Why 8? Well all of the numbers you need to store are less than 16, so only require 4 bits of storage. Therefore you can store both kerning values for each row in a single byte.

If you had 64 characters you'd need 512 bytes for no kerning, 576 bytes for simple kerning, and 1024 bytes for complex kerning.

\$\endgroup\$
  • \$\begingroup\$ +1, some good stuff! Reminds me of when I went through a similar learning experience \$\endgroup\$ – justing Jul 31 '12 at 21:16
  • \$\begingroup\$ @justin - Thanks! There's lots more good stuff on my very old web site: The good-looking textured light-sourced bouncy fun smart and stretchy page. \$\endgroup\$ – Rocketmagnet Jul 31 '12 at 21:18
  • \$\begingroup\$ +1! I've done it in the past, more than once, and with multicolors font too, for those (assembly-written!) particle text animation demos... :D \$\endgroup\$ – Axeman Aug 1 '12 at 8:27
  • \$\begingroup\$ The kerning approach given will cause characters to touch if an an overhang would sit on the row above the top of the next character. While it's possible to improve it, I would suggest that in general kerning such small fonts is a waste of time. Allowing most characters to be narrower than "M" and "W" will increase the quantity of legible text that can fit in a given space; kerning generally won't save much more space. Further, over-aggressive kerning (e.g. shoving a an apostrophe over an "L") may be worse for legibility than no kerning. \$\endgroup\$ – supercat Aug 1 '12 at 17:03
  • \$\begingroup\$ @supercat - I don't think it would allow them to touch. Must also disagree about the space saving. I've used italic fonts where the 'i' is 1 pixel, and the 'M' is 10 pixels wide! Kerning is absolutely necessary here, and in fonts that need it, is noticeably nicer to look at. For example, my old Nokia phone does it for text messaging. \$\endgroup\$ – Rocketmagnet Aug 1 '12 at 17:18
2
\$\begingroup\$

When I worked with the NETMF platform, there was a tools in the SDK (tfconvert) to create a font for the platform starting from any font installed on the PC. I've used it to create a couple of tiny prpoprtional fonts (6-8 pixel height) that worked really well on the 128x64 pixel OLED display on my board. There was also a nice GUI to control every parameter of the conversion. I don't know if the format is documented, and if you can use it, but you can give it a look.

NETMF SDK is free to download from microsoft.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.