Building user-defined fonts
To build a custom font is not difficult at all, but before proceeding with the explanations it is necessary to introduce some notions.
First of all, a font is defined as a collection of glyphs. The glyphs are the shapes that are actually drawn on the display when the calculator receives the request to print a character and can be imagined as a rectangular grid of pixels where some of them are lit and others aren't.
The height (in pixels) of this grid is called the size of the font, and it's the same for all the glyphs; the width, on the contrary may vary, or not. If the width of the grid is always the same the font is termed fixed-width otherwise is proportional.
The size of the font must take into account the possibility that some characters are taller than others (e.g. l
versus n
), that some have descenders while others haven't (p
versus o
) and that when multiple lines of text are written to the screen there should be a little separation between the rows to make the text readable.
The logical conclusion is that if the font is planned to be e.g. 10 pixel high, the actual room to draw the glyphs is reduced to the top 8 or 9 rows of the grid, with the bottom lines of pixels empty to either provide the space between the lines of text or the room to draw a descender.
Restrictions on thw width of a glyph are less severe because, as said before, it's not compulsory that all the glyphs share the same width: in fact, the width of a glyph ranges from 1 to 15 pixels; it's common practice to keep the last column of a glyph empty in order to prevent the characters from blending into each other.
The last concept to introduce is that of the translation table. A font can store up to 65536 glyphs (provided that the total width of the glyphs doesn't exceed 4095 pixels) but an Unicode character block can store up to 1048576 code points. The translation table realizes the connection between code points (which identify unequivocally a character) and glyphs (which determine their graphical appearance).
For example, a large part of the 1048576 code points will be unused, therefore all these code points can be mapped to a single glyph (e.g. a little square shape or similar symbol), providing a powerful way to reduce the memory footprint of the unused codes.
A more practical example arises from the consideration that many scripts share many glyphs: for example the capital latin b (code point U+0042
), greek beta (code point U+0392
) and cyrillic ve (code point U+0412
) letters are represented by the glyph B
.
In conclusion, to build a custom font three tools are needed:
- a graphic editor capable of saving images in .bmp format to draw the glyphs;
- a text editor to write the translation table;
- the
bmp2font
tool to create the font object. The source code is available innewrpl/tools/fonts/bmp2font/
while the instructions to compile it are here.
Examination of the source bitmap of an existing font (e.g. Font10_StyleA.bmp
shows that the structure of the bitmap file is very simple: each glyph is juxtaposed to the previous.
A closer examination of the file reveals that the bitmap is actually 11 pixel high rather than 10. The extra bottom row of pixels is used to encode the width of each glyph: under the first glyph there are five black pixels, therefore the width of that glyph is 5 pixels; under the second glyph there are five white pixels thus its width is 5 pixels again, and so on until the end of the bitmap.
The structure of the translation table is even simpler: looking at the file Font10_StyleA.txt
one can see that, comments aside, each glyph in the font corresponds to a line in the file, listing one or more Unicode code points (multiple code points are separated by a comma).
Code point 0
has a special meaning: any code point that doesn't match those present in the translation table will be mapped to the glyph with code point 0
.
Once the font has been drawn and the translation table written it's the time to actually build the font object using the bmp2font
tool. Its syntax is the following:
bmp2font <font-bitmap-file.bmp> <font-text-file.txt> <output[.c or .nrpl]> [name of C variable]
where
font-bitmap-file.bmp
is the bitmap (accepted formats are monochrome and 256 colors);font-text-file.txt
is the translation table;output.*
is the output file: it can be a newRPL object, directly transferrable to the calculator or a definition in C language ready to be included in the source code;name of C variable
is an optional parameter used to name internally the font in case the output ofbmp2font
is a C definition.