I've been looking at the way fonts are handled on the MIT nu-machine (their apm) and here are some ideas gleaned from that. Some may seem fairly obvious, but I thought it would be useful to collect them together. 1. They store fonts in a binary file, which can be read in ('connected'), and used without further processing. This is probably what we would want too, although portability among host processors with different storage maps, and between programming languages, could be an issue. 2. They keep much more information relating to each character than at first appears necessary. Width, height and bit-map per character is the minimum needed for proportionally spaced fonts, but they have horizontal and vertical offset and increment values as well. Width and height define the cell in which the character is to be painted. The offset values relate this cell's absolute position to the pixel cursor, and the increment values are added to the cursor to give the position of the next character. The latter idea is quite interesting, because normally one would just add the cell width to get to the next cursor position - but this is cultural imperialism! Our 5th generation friends would subtract the height; in the middle east the width might be subtracted rather than added. Even in europe we could give an umlaut or accent grave zero increments. The offset values allow space savings in small punctuation characters, but are also used to allow the vertical point of reference to be the baseline of the characters. This gives greater independance between characters - it is possible to increase the length of a descender without moving all the other characters up, for instance. The horizontal offset is used in some italic fonts to make adjacent characters overlap into each other's cells. 3. Their font information is arranged as an array of 128 records followed by the bit-map information (they assume only 128 charcters). Each record gives the size, offset and increment values for one character, and a relative pointer into the bit-maps. These consist of a sequence of 16-bit words, arranged as unbroken horizontal strips. The characters are aligned flush left, and unused bits at the right up to the 16-bit boundary are required to be zero. The upper-left pixel corresponds to bit 2**0 of the 16-bit word pointed at in the descriptor record for a character (this is the reverse of that suitable for our framestore). Regarding the questions Hamish posed in his mail of 7th May: A (a) Align bits at the most significant end of the unit of data. Agreed. (b) The unit of data should be the 16-bit word. Agreed. (c) High-order bit is leftmost pixel, low memory address is top. Agreed. (d) I favour handling 16-bit wide vertical strips in the inner loop, i.e. give computational efficiency priority over naturalness here. B Dimension information. I see difficulties in allowing varying amounts of dimension information. The software interpreting a font must know how much such information is avalable, either through an indicator in the file or by having different classes of font file. This is likely to lead to confusion. Of course, including the maximum amount of information per character in each font would waste space. I favour a table of dimension information, with an index into this table associated with each character. Even the height would be in the table, not stored with the character. The program which builds a font file can be intelligent enough to avoid repetition of identical table entries, so a constant height, constant width font would only need one entry. C Directory. The relative pointer from the directory to the font information should be a full integer. With 16-bits the maximum size square font with 128 characters is 64 by 64 pixels, which is presumably too small for a high resoloution laser printer. In summary, here is my suggestion for font representation: Directory (relative address 0): %short 1st character code in font %short last charcter code in font %integer relative address of dimension table %integer relative address of 1st character %integer relative address of 2nd character . . %integer relative address of last character Dimension table (each entry): %short horizontal size (pixels) %short vertical size %short horizontal offset \ add to cursor to give %short vertical offset / top left pixel of bit map %short horizontal increment %short vertical increment Raster information (each character): %short index into dimension table %short top left bit row \ %short next row down | 'vertical size' shorts . | . | %short bottom left bit row / %short top row of next column if horizontal size > 16 . . %short bottom row of next column etc for (horizontal size + 15) >> 4 columns