#define PSF2_MAGIC0 0x72
#define PSF2_MAGIC1 0xb5
#define PSF2_MAGIC2 0x4a
#define PSF2_MAGIC3 0x86
/* bits used in flags */
#define PSF2_HAS_UNICODE_TABLE 0x01
/* max version recognized so far */
#define PSF2_MAXVERSION 0
/* UTF8 separators */
#define PSF2_SEPARATOR 0xFF
#define PSF2_STARTSEQ 0xFE
struct psf2_header {
unsigned char magic[4];
unsigned int version;
unsigned int headersize; /* offset of bitmaps in file */
unsigned int flags;
unsigned int length; /* number of glyphs */
unsigned int charsize; /* number of bytes for each character */
unsigned int height, width; /* max dimensions of glyphs */
/* charsize = height * ((width + 7) / 8) */
};
The meaning is fairly clear from the field names.
The fonts here are bitmap fonts (not, for example, vector fonts),
and each glyph has a height and a width.
The bitmap for a glyph is stored as height consecutive
pixel rows, where each pixel row consists of width bits
followed by some filler bits in order to fill an integral number
of (8-bit) bytes. Altogether the bitmap of a glyph takes
charsize bytes.
For psf1 the width is constant 8, so that the height equals the charsize.
The number of glyphs in the font equals length.
For psf1 the length is constant 256, unless the PSF1_MODE512 bit
is set in the mode field, in which case it is 512.
The font is followed by a table associating Unicode values with each
glyph in case (for psf1) the PSF1_MODEHASTAB bit is set in
the mode field, or (for psf2) the PSF2_HAS_UNICODE_TABLE
bit is set in the flags field.
The starting offset of the bitmaps in the font file is given by
headersize. (This allows the header to grow, probably
depending on version, without changes in the code.)
The integers in the psf2 header struct are little endian 4-byte integers.
where <uc> is a 2-byte little endian Unicode value (psf1),
or a Unicode value coded in UTF-8 (psf2),
and * denotes zero or more occurrences of the preceding item.
The semantics is as follows.
The leading <uc>* part gives Unicode symbols that are all
represented by this font position. The following sequences
are sequences of Unicode symbols - probably a symbol
together with combining accents - also represented by
this font position.
Example:
At the font position for a capital A-ring glyph, we
may have (psf1):
00C5,212B,FFFE,0041,030A,FFFF
where the Unicode values here are
LATIN CAPITAL LETTER A WITH RING ABOVE
and
ANGSTROM SIGN
and
LATIN CAPITAL LETTER A
and
COMBINING RING ABOVE.
Some font positions may be described by sequences only,
namely when there is no precomposed Unicode value for the glyph.
PSF stands for PC Screen Font.
The psf1 format without Unicode map was designed by
H. Peter Anvin in 1989 or so for his DOS screen font editor
FONTEDIT.EXE. In Oct 1994 he added the Unicode map
and the programs psfaddtable, psfgettable,
psfstriptable to manipulate it - see kbd-0.90.
Andries Brouwer added support for sequences of Unicode values
and the psf2 format in Sep 1999 in order to handle Tibetan -
see kbd-1.00.