Skip to content

FontLibC Library: Creating Fonts

drdnar edited this page May 3, 2019 · 5 revisions

Fonts for use with FontLibC can be made with any program that can produce Windows 3.x .FNT resource files.

Editor Software

Fony is probably the most-used FNT editor available. It can open both .FNT and .FON files.

mkwinfont provides some Python code for converting a text-based format to and .FON files; it should be trivial for someone with basic Python skills to change to code to skip the .FON packaging stage and directly produce a .FNT resource file. Useful if for some reason you think graphics are best done without the aid of any kind of graphics editor.

VSoft's FontEdit is mostly just the original FontEdit included with the Windows SDK for Windows 3.x, but compiled for 32-bit Windows. A notable addition, however, is the ability to import TrueType fonts, though I haven't tested it. It cannot, however, open .FON files; the FNT resource(s) embedded in a .FON file must be extracted before FontEdit can open the font(s).

MFE is DrDnar's own bitmap font editor. It can export .FNT files. It has the useful feature of allowing fully custom mapping from Unicode to your font's 8-bit code page, which makes creating mock-ups with the preview function easier.

Using Fonts in Your Project

Once your .FNT file has been created, use the convfont utility included with the SDK to convert the .FNT resource file into a format usable in your project.

There are two main ways of including a font in your project:

  • directly in your program binary; or,
  • in separate font pack appvar.

Embedding a Font Directly in Your Program

Embedding a font directly in your program ensures the font will always be available, but it prevents it from being used by any other program, and bloats your program. However, it is also the easiest way to access a custom font.

Place your .FNT font files in your source code directory. Then, create a myfonts.h source code file:

/* Declare globally-accessible pointers to the font data. */
extern const fontlib_font_t *my_font_1;
extern const fontlib_font_t *my_font_2;
. . .

Then create a myfonts.c file:

/* This contains the raw data for the font. */
static const uint8_t my_font_1_data[] = {
	#include "myfont1.inc"
};
/* However, C89 does not allow us to typecast a byte array into a
fontlib_font_t pointer directly, so we have to use a second statement to do it,
though helpfully we can at least do it in the global scope. */
const fontlib_font_t *my_font_1 = (fontlib_font_t *)my_font_1_data;

static const uint8_t my_font_2_data[] = {
	#include "myfont2.inc"
};
const fontlib_font_t *my_font_2 = (fontlib_font_t *)my_font_2_data;

Now you should be wondering where the myfont1.inc file comes from. This file will get generated by your makefile, which will need to be modified to append the following:

# This is a roundabout way to tell make that myfonts.c depends on the .inc files.
# It does it by saying the compiled object code depends on the .inc files.
$(OBJDIR)/myfonts.src: $(SRCDIR)/myfont1.inc $(SRCDIR)/myfont2.inc

# Convert a .fnt file into a .inc file
$(SRCDIR)/myfont1.inc: $(SRCDIR)/myfont1.fnt
	convfont -o carray -f $(SRCDIR)/myfont1.fnt $(SRCDIR)/myfont1.inc

$(SRCDIR)/myfont2.inc: $(SRCDIR)/myfont2.fnt
	convfont -o carray -f $(SRCDIR)/myfont2.fnt $(SRCDIR)/myfont2.inc

Finally, somewhere else in your program, you can use fontlib_SetFont():

void main() {
    . . . 
    fontlib_SetFont(my_font_1, 0);
    . . . 
}

Making a Font Pack

Font packs are an alternative to directly embedding a font in your program binary. They allow multiple related fonts to be packaged together, and FontLibC can select a font from the font pack given a requested size and style. The fonts in a font pack can be used by other programs, reducing the size of your program and saving valuable space on-calculator. They can also be archived, freeing up limited RAM.

A font pack should contain related fonts, namely different sizes and styles of a typeface. It is legal for a font pack to contain only one font. Metadata fields in a font pack, such as the description, should be short.

Font packs are easiest to make as a separate project. Create a new folder, place your .fnt files in it, and then create a makefile with the following contents:

# Put each of your .fnt files on this next line.
# Look at the documentation for convfont for more information on font properties
temp.bin: font1.fnt font2.fnt font3.fnt
	convfont -o fontpack -N "Font Name" -P "ASCII" -V "Some version or date" -A "Your Name" \
	-D "A SHORT description of your font" \
	-f font1.fnt -a 1 -b 1 -w bold -s sans-serif -s upright -s proportional \
	-f font2.fnt -a 2 -b 2 -w normal -s serif -s italic \
	-f font3.fnt -a 0 -b 3 -w light -s monospaced \
	temp.bin

# Don't forget to change font_pack_file_name on both these lines.
# Set PACKNAME to the on-calculator appvar name you want
font_pack_file_name.8xv: temp.bin
	convhex -a -v -n PACKNAME temp.bin font_pack_file_name.8xv

all: font_pack_file_name.8xv
You can’t perform that action at this time.