| Author: | Colin D. Bennett <colin@gibibit.com> |
|---|---|
| Date: | 8 January 2009 |
Contents
The goal of this format is to provide a bitmap font format that is simple to use, compact, and cleanly supports Unicode.
There are many existing bitmap font formats that GRUB could use. However, there are aspects of these formats that may make them less than suitable for use in GRUB at this time:
| Font format | Reason format is suboptimal for GRUB |
|---|---|
| BDF | Inefficient storage; uses ASCII to describe properties and hexadecimal numbers in ASCII for the bitmap rows. |
| PCF | Many format variations such as byte order and bitmap padding (rows padded to byte, word, etc.) would result in more complex code to handle the font format. |
A file section consists of a 4-byte name, a 32-bit big-endian length (not including the name or length), and then length more section-type-specific bytes.
The standard file extension for PFF2 font files is .pf2.
Character index. The character index begins with a 32-bit big-endian unsigned integer indicating the total size of the section, not including this size value. For each character, there is an instance of the following entry structure:
A marker that indicates the remainder of the file is data accessed via the character index (CHIX) section. When reading this font file, the rest of the file can be ignored when scanning the sections. The length should be set to -1 (0xFFFFFFFF).
Supported data structures:
Each character definition consists of:
Width. Width of the bitmap in pixels. The bitmap's extents represent the glyph's bounding box. uint16be.
Height. Height of the bitmap in pixels. The bitmap's extents represent the glyph's bounding box. uint16be.
X offset. The number of pixels to shift the bitmap by horizontally before drawing the character. int16be.
Y offset. The number of pixels to shift the bitmap by vertically before drawing the character. int16be.
Device width. The number of pixels to advance horizontally from this character's origin to the origin of the next character. int16be.
Bitmap data. This is encoded as a string of bits. It is organized as a row-major, top-down, left-to-right bitmap. The most significant bit of each byte is taken to be the leftmost or uppermost bit in the byte. For the sake of compact storage, rows are not padded to byte boundaries (i.e., a single byte may contain bits belonging to multiple rows). The last byte of the bitmap is padded with zero bits in the bits positions to the right of the last used bit if the bitmap data does not fill the last byte.
The length of the bitmap data field is (width * height + 7) / 8 using integer arithmetic, which is equivalent to ceil(width * height / 8) using real number arithmetic.
It remains to be determined whether bitmap fonts usually make all glyph bitmaps the same height, or if smaller glyphs are stored with bitmaps having a lesser height. In the latter case, the baseline would have to be used to calculate the location the bitmap should be anchored at on screen.
This contains a set of character definitions which are compressed as a single block within the file. Compressed character definitions will be implemented at a later date.
[TODO: Implement compression/decompression using LZMA.]
An illustration of how the various font metrics apply to characters.
Note: A new font converter, grub-mkfont (which is written in C instead of Java), has recently been created. It will take the place of the Java font converter in the near future.
The GRUB font tool is composed of font viewer and font converter programs. It is a Java program and can be built from source using the Ant tool:
$ cd util/fonttool
util/fonttool $ ant jar
Buildfile: build.xml
compile:
[mkdir] Created dir: /home/cdb/grub/util/fonttool/build/src
[javac] Compiling 15 source files to /home/cdb/grub/util/fonttool/build/src
jar:
[jar] Building jar: /home/cdb/grub/util/fonttool/build/fonttool.jar
BUILD SUCCESSFUL
Total time: 2 seconds
This results in a JAR file in the util/fonttool/build directory that contains the compiled class files.
To run the font viewer, which can view either PFF2 or BDF fonts:
util/fonttool $ java -cp build/fonttool.jar org.gnu.grub.fonttool.Viewer myfile.bdf
To convert a BDF font into PFF2 format, run:
util/fonttool $ java -cp build/fonttool.jar org.gnu.grub.fonttool.Converter --in=font.bdf --out=font.pf2
There is also a script called makepf2.sh in the util/fonttool directory as well which allows easy batch conversion of many BDF fonts to PFF2 format at once.