PC screen font
PC Screen Font ( PSF for short ) is a simple binary file format for bitmap fonts . It is mainly used by the Linux kernel for the text console, but is not restricted to this purpose.
There are two mutually incompatible format versions. The logical structure is the same, but the coding is very different.
Version 1
PSF version 1 had its origins in the file format that H. Peter Anvin used in 1989 in his font editor for MS-DOS. Its capabilities are limited according to the capabilities of the VGA graphics card in text mode:
In this version only fonts with 8 pixels wide characters can be defined. Character sets with 256 or 512 characters are supported.
Files in this format start with a 4-byte header:
PSF1 header Offset size meaning 0 2 Magic Number 36 hex , 04 hex 2 1 Font Mode: Bit field that defines the properties of the character set if the corresponding bit is set:
Bit 0: Font contains 512 characters
Bit 1: Font has Unicode coding table
Bit 2: The coding table contains character sequences3 1 Height of a character (= size of a character in the PSF file)
Version 2
This format can store characters of any size, and the number of characters in the font can now be freely selected.
PSF2 header Offset Data type meaning 0 uint8_t [4] Magic Number 72 hex , B5 hex , 4A hex , 86 hex 4th uint32_t Version. (previously always 0) 8th uint32_t Size of the header (in bytes) 12 uint32_t Flags (currently only bit 0 is defined, which indicates whether the font contains a Unicode table) 16 uint32_t Number of characters in the font 20th uint32_t Size of a character (in bytes) 24 uint32_t Character height (in pixels) 24 uint32_t Character width (in pixels)
The 32-bit values are stored in little endian format.
Character data
The actual character data follow the header. In PSFv1, each byte corresponds to exactly one line with 8 pixels. In PSFv2 the lines are padded from the right with zero bits, if necessary, in order to arrive at a whole number of bytes per line.
example
The font file Uni1-Fixed16.psf supplied with many Linux distributions begins (in hexadecimal notation ) as follows:
Offset | Datenbytes —————————+—————————————————————————————————————————————————— 00000000 | 36 04 03 10 00 00 00 00 3c 42 99 a5 a1 a1 a5 99 00000010 | 42 3c 00 00 00 00 00 00 3c 42 b9 a5 a5 b9 a9 a5 00000020 | 42 3c 00 00 0c 30 00 00 41 41 22 22 14 08 08 08 00000030 | 08 08 00 00 00 00 00 00 18 24 24 42 42 7e 42 42 …
The first two bytes 36 04
are the PSF1 header. The Font Mode byte has the value 03 hex , which means: The font contains a Unicode character table and character sequences. The following byte has the value 10 hex = 16 dec and specifies the height of the characters in pixels and bytes.
This is followed by 16 bytes per character that contain the pixel data:
Zeile | Byte | Pixel ——————+——————+————————————————— 1 | 00 | · · · · · · · · 2 | 00 | · · · · · · · · 3 | 00 | · · · · · · · · 4 | 00 | · · · · · · · · 5 | 3c | · · █ █ █ █ · · 6 | 42 | · █ · · · · █ · 7 | 99 | █ · · █ █ · · █ 8 | a5 | █ · █ · · █ · █ 9 | a1 | █ · █ · · · · █ 10 | a1 | █ · █ · · · · █ 11 | a5 | █ · █ · · █ · █ 12 | 99 | █ · · █ █ · · █ 13 | 42 | · █ · · · · █ · 14 | 3c | · · █ █ █ █ · · 15 | 00 | · · · · · · · · 16 | 00 | · · · · · · · ·
Unicode character table
The Unicode character table specifies for each character in the font which Unicode character or character string it should stand for. This means that unicode characters that look identical (e.g. the Latin A, the Cyrillic А and the Greek alpha) only need to be encoded once in the font.
The font can also contain characters that do not have their own code in Unicode, but can only be represented using a sequence of Unicode characters.
The Unicode values are encoded in PSFv1 format as 16-bit values, so that only characters from the Basic Multilingual Plane are supported. PSFv2 encodes the values in UTF-8 and can therefore also contain characters beyond U + FFFF.