LPC1343 Graphics Sub-System: Rendering Text (fonts.c, aafonts.c)
Overview of the two main font-rendering options (bitmap and 2/4-bit anti-aliased fonts)
Text is a fundamental part of any user interface, and the choice of fonts is oe of the most important decisions to make when desiging your UI. Unfortunately, working with resource constrained devices like the LPC1343 (32KB flash, 8KB SRAM) makes the choice even more difficult, since you probably only have enough flash storage space for one or at most two fonts.
There's an obvious tradeoff between the size and quality of the fonts, and the amount of storage space you can afford to dedicate to them. Larger and more readable fonts obviously take more space. To take into account both situations -- where text quality trumps flash storage, or when flash storage is more important to text quality -- two different font-rendering systems are included in the LPC1343 Graphic Sub-System: 1-bit bitmap fonts (fonts.c), and 2-bit or 4-bit anti-aliased fonts (aafonts.c).
Bitmap Fonts (fonts.c)
Bitmap fonts are the smallest, and easiest to work with. They consist on 1 color, and can be efficiently rendered on any surface since there is no need to take into account the background color or contents.
Unfortunately, they can also be hard to read on small screens because they're resolution is limited, and only one color of data is present. It's possible to render small, readable text with bitmap fonts, but italics probably isn't possible, and the fonts may not be as crisp or readable as anti-aliased text (where several shades of gray are used to improve the visual quality of the text).
All bitmap fonts used in the LPC1343 Code Base are based around the open source Dot Factory font converter from Eran Duchan. For convenience sake, the application and source are included in the '/tools/dotfactory' folder of the LPC1343 Code Base.
It's relatively easy to create new fonts from any TTF or OpenType font installed on your system, though a few minor tweeks are required to use them in the LPC1343 Code Base. Simply open up any one of the provided fonts to see what font.c is expecting, or look in the '/tools/dotfactory' folder for details.
A number of functions are included in fonts.c to facilitate drawing strings of text on the display. By default, the following fonts are also included with the LPC1343 Code Base (as of v0.85), all of which are based on freely available open-source font-famliies:
|Font ||Monospace/Variable ||Width ||FONT_INFO |
|Bitstream Vera Mono 9 ||Monospace ||8 ||bitstreamVeraSansMono9ptFontInfo |
|Bitstream Vera Mono 9 Bold ||Monospace ||8 ||bitstreamVeraSansMonoBold9ptFontInfo |
|Bitstream Vera Mono 11 ||Monospace ||9 ||bitstreamVeraSansMono11ptFontInfo |
|Bitstream Vera Mono 11 Bold ||Monospace ||9 ||bitstreamVeraSansMonoBold11ptFontInfo |
|DejaVu Sans 9* ||Variable ||-- ||dejaVuSans9ptFontInfo |
|DejaVu Sans 9 Bold ||Variable ||-- ||dejaVuSansBold9ptFontInfo |
|DejaVu Sans Condensed 9 ||Variable ||-- ||dejaVuSansCondensed9ptFontInfo |
|DejaVu Sans Mono 8 ||Monospace ||8 ||dejaVuSansMono8ptFontInfo |
|DejaVu Sans Mono 8 Bold ||Monospace ||8 ||dejaVuSansMonoBold8ptFontInfo |
*Note: In order to save valuable flash storage space, only DejaVu Sans 9 is used in the LPC1343 Code Base by default. Using any additional fonts will required extra storage space, typically 1.5-2.0 KB per font used.
void fontsDrawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str)
Draws a string of text on the screen using a specially formatted font.
fontsDrawString(0, 90, COLOR_BLACK, &dejaVuSans9ptFontInfo, "DejaVu Sans 9");
fontsDrawString(0, 105, COLOR_BLACK, &dejaVuSans9ptFontInfo, "123456789012345678901234567890");
uint16_t fontsGetStringWidth(const FONT_INFO *fontInfo, char *str)
Calculates the width in pixels of the text when it will be rendered
fontsGetStringWidth(&dejaVuSans9ptFontInfo, "Text in DejaVu Sans 9");
Anti-Aliased Fonts (aafonts.c)
Anti-aliased fonts appear to have a much higher resolution than equivalent bitmap fonts, since they contain several shades of gray between black and white, creating smoother edges. They allow you to render much higher-quality and more readable text, including in italics or using similar fonts that would be very difficult to render using small bitmap fonts.
Unfortunately, the benefits of anti-aliasing come with an price. 2-bit anti-aliased fonts have 4 colors (white, black, and two intermediate shades of gray), taking twice as much flash space as a bitmap font. 4-bit anti-aliased fonts have 16 colors (14 intermediate shades of gray), and take 4 times as much flash space. Generally speaking, the visual benefits of 4-bit antialiasing versus 2-bit are negligible, though, and AA4 is seldome worth the extra flash space. AA4 algorithms are provided for convenience sake or if the need does arise, but on the LPC1343 AA2 is a far more sensible choice.
Aside from fmash space, one of the main restrictions of anti-aliased fonts is that you need to know the background color when you are rendering text, since various shades of the fore-ground color need to be calculated based on the background color (that's what gives those smooth edges). In the case of a solid background of a known color, there is no real computational overhead and the problem is easy to solve since a color lookup table can easily be generated, and text rendering is essentially as fast as with bitmap fonts. When the background is unknown or the color varies significantly, though -- such as rendering text on a bitmap image -- the overhead can be very high since you first need to read the current pixel back from the LCD, which is a very expensive operation. In general, you should always try to use anti-aliased fonts on a known, solid background for best performance.
Unfortunately, there is currently no open-source font converted (that I'm aware of) that's able to generate useful font data, and the anti-aliased fonts included with the LPC1343 are generated partially by a commercial solution, and tweeked into a more useful format by hand. The font format has been kept intentionally very simple, but creating a decent font convertor or modifying and existing one would be a pretty substantial investment in time, so it will have to stay on the ToDo list for the moment.
A number of 'open source' (freely redistributable) fonts are included in the aafonts folder to facilitate drawing strings of text on the display until a better solution can be found in the form of a freely distributable converter. The following fonts are also included with the LPC1343 Code Base (as of v1.1.0), all of which are based on freely distributable font-famliies:
|Font (height is in pixels) ||Mono/Variable || Type ||Width ||aafontsFont_t |
|DejaVu Sans Condensed 14* ||Variable ||AA2 ||-- ||DejaVuSansCondensed14_AA2 |
|DejaVu Sans Condensed 14 Bold ||Variable ||AA2 ||-- ||DejaVuSansCondensedBold14_AA2 |
|DejaVu Sans Mono 10 ||Monospace ||AA2 ||5 ||DejaVuSansMono10_AA2 |
|DejaVu Sans Mono 13 ||Monospace ||AA2 ||7 ||DejaVuSansMono13_AA2 |
|DejaVu Sans Mono 14 ||Monospace ||AA2 ||7 ||DejaVuSansMono14_AA2 |
*Note: In order to save valuable flash storage space, only DejaVu Sans Condensed 14 is used in the LPC1343 Code Base by default.
ToDo: Describe functions and show some examples
Small Fonts (smallfonts.c)
In addition to the two font systems described above, there is also an optional third font-rendering system that can be enabled in projectconfig.h by setting the CFG_TFTLCD_INCLUDESMALLFONTS flag to '1'. This font-rendering system is intended for small, bitmap displays, which are typically low resolution. You usually need to use very small fonts with these displays to fit much information on the screen, and because the pixels are relatively large compared to most large color displays.
If you are using a small TFT or OLED display, though, or need a very small font for your UI, you may still find these smallfonts useful.
ToDo: Add smallfont.c functions and example