A Type 1 font is a PostScript program. Sent to a printer it is plain text, but its second half, the part with the glyph outlines, is encrypted and so is binary. PFB (“printer font binary”) stores that program in the form used on PCs: the text and the binary parts in separate segments, each with a small header saying how long it is.
Segments
A PFB file is a sequence of segments. Each starts with a header:
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 1 | marker | Always 0x80. |
1 | 1 | type | 1 text (ASCII), 2 binary, 3 end of file. |
2 | 4 | length | Number of data bytes that follow, little-endian. Absent for type 3. |
The segment data follows the header directly, and the next header follows the data. A normal font has three data segments and the end marker:
080 01+ length the clear text part: the%!PS-AdobeFont-1.0line, comments, the font dictionary, ending withcurrentfile eexectext…80 02+ length the eexec-encrypted part: the Private dictionary, Subrs and CharStringsbinary…80 01+ length the trailer: 512 ASCII zeros in lines, thencleartomarktext…80 03end of file2 bytes
A file may split a part over several segments of the same type; readers join consecutive segments. Lines in the text segments may end in CR, LF or CR LF (the example below uses CR alone).
PFA and other wrappers
- PFA (“printer font ASCII”) is the same program with no segment
headers, the encrypted part written as lines of hexadecimal digits.
Converting PFB to PFA means dropping the headers and hex-encoding the type 2 data. A
reader can tell the two forms apart from the four bytes after
currentfile eexecand its line end: if they are all hex digits, the encrypted part is in hex. - On the classic Mac OS the same segments were kept as
POSTresources in a printer font file of typeLWFN, each resource starting with a type byte (1 text, 2 binary, 3 or 5 end, 0 comment) and a zero byte.
eexec encryption
The PostScript operator eexec decrypts the rest of the file and runs it.
The cipher is a simple stream cipher on bytes with a 16-bit key
r, started at 55665, and two constants
c1 = 52845 and c2 = 22719.
For each encrypted byte c:
plain = c XOR (r >> 8)
r = ((c + r) × 52845 + 22719) mod 65536
Encryption is the same with the roles swapped: c = plain XOR
(r >> 8), then r is updated from c. The first
four decrypted bytes are random padding and are thrown away; what follows is
PostScript text that defines the Private dictionary and the glyphs, using binary
strings for the charstrings (which are encrypted a second time; see
charstring encryption). The
decrypted text ends with mark currentfile closefile, which stops
eexec.
Trailer
After the encrypted part, the clear text resumes with 512 zeros (usually eight lines
of 64) and cleartomark. The zeros are there for printers that read past
the end of the encrypted data; cleartomark removes everything back to
the mark placed before closefile. Some files add
%%EndResource or %%EOF lines.
Example
TIR_____.PFB, Adobe’s Times Roman (version 001.007, created 20 March
1990) as shipped with Acrobat Reader for Windows, 32,976 bytes:
| File offset | Bytes | Meaning |
|---|---|---|
0x0000 | 80 01 B8 06 00 00 | Text segment of 0x6B8 = 1,720 bytes. |
0x0006 | 25 21 50 53 2D … | %!PS-AdobeFont-1.0: Times-Roman 001.007, then the font dictionary, ending currentfile eexec and a CR at 0x6BD. |
0x06BE | 80 02 F0 77 00 00 | Binary segment of 0x77F0 = 30,704 bytes. |
0x06C4 | 5A A4 F7 12 55 50 … | The eexec-encrypted Private dictionary and charstrings. |
0x7EB4 | 80 01 14 02 00 00 | Text segment of 0x214 = 532 bytes: 512 zeros, line ends and cleartomark. |
0x80CE | 80 03 | End of file, at 32,974 + 2 = 32,976 bytes. |