202  INTRODUCTION  GF to PK changes C §1

1* . Introduction. This program reads a file and packs it into a file. files are significantly smaller than files, and they are much easier to interpret. This program is meant to be the bridge between and drivers that read files. Here are some statistics comparing typical input and output file sizes:

Font  Resolution  size  size Reduction factor
cmr10  300  13200 5484  42%
cmr10  360  15342 6496  42%
cmr10  432  18120 7808  43%
cmr10  511  21020 9440  45%
cmr10  622  24880 11492  46%
cmr10  746  29464 13912  47%
cminch  300  48764 22076  45%

It is hoped that the simplicity and small size of the files will make them widely accepted.

The format was designed and implemented by Tomas Rokicki during the summer of 1985. This program borrows a few routines from by Arthur Samuel.

The banner string defined here should be changed whenever gets modified. The preamble comment macro (near the end of the program) should be changed too.

define banner ≡ ´ ␣ ␣ ␣ ␣ ␣ ´ { printed when the program starts }

4* . The binary input comes from gf file, and the output font is written on pk file. All text output is written on Pascal’s standard output file. The term print is used instead of write when this program writes on output , so that all such output could easily be redirected if desired. Since the terminal output is really not very interesting, it is produced only when the command line flag is presented.

define term out ≡ stdout { standard output }

define print (#) ≡

if verbose then write(term out , #)

define print ln(#) ≡

if verbose then write ln(term out , #)

program GFtoPK ; const ⟨ Constants in the outer block 6 ⟩ type ⟨ Types in the outer block 9 ⟩ var ⟨ Globals in the outer block 11 ⟩ procedure initialize; { this procedure gets things started properly }

var i: integer ; { loop index for initializations } begin set paths (GF FILE PATH BIT ); ⟨ Set initial values 12 ⟩; end;

5* . This module is deleted, because it is only useful for a non-local goto, which we can’t use in C.

8* . If the file is badly malformed, the whole process must be aborted; will give up, after issuing an error message about the symptoms that were noticed.

Such errors might be discovered inside of subroutines inside of subroutines, so a procedure called jump out has been introduced. This procedure, which simply transfers control to the label final end at the end of the program, contains the only non-local goto statement in .

define abort (#) ≡ begin verbose ← true; print ln(#); uexit (1); end

define bad gf (#) ≡ abort (´ ␣ ␣ ␣´ , #, ´ ´ )

§9  GF to PK changes C  INPUT AND OUTPUT FOR BINARY FILES 203

37* . Input and output for binary files. We have seen that a file is a sequence of 8-bit bytes. The bytes appear physically in what is called a ‘packed file of 0 . . 255’ in Pascal lingo. The file is also a sequence of 8-bit bytes.

Packing is system dependent, and many Pascal systems fail to implement such files in a sensible way (at least, from the viewpoint of producing good production software). For example, some systems treat all byte-oriented files as text, looking for end-of-line marks and such things. Therefore some system-dependent code is often needed to deal with binary files, even though most of the program in this section of is written in standard Pascal.

We shall stick to simple Pascal in this program, for reasons of clarity, even if such simplicity is sometimes unrealistic. ⟨ Types in the outer block 9 ⟩ +≡

eight bits = 0 . . 255; { unsigned one-byte quantity }

byte file = packed file of eight bits ; { files that contain binary data }

UNIX file name = packed array [1 . . FILENAMESIZE ] of char ;

38* . The program deals with two binary file variables: gf file is the input file that we are translating into format, to be written on pk file. ⟨ Globals in the outer block 11 ⟩ +≡ gf file: byte file; { the stuff we are ing } pk file: byte file; { the stuff we have ed } verbose: boolean; { chatter about the conversion? } pk arg : integer ; { where we may be looking for the name of the pk file } gf name: UNIX file name;

204  INPUT AND OUTPUT FOR BINARY FILES  GF to PK changes C §39

39* . In C, we use the external test read access procedure, which also does path searching based on the user’s environment or the default path. In the course of this routine we also check the command line for the flag, and make other checks to see that it is worth running this program at all.

define usage ≡ abort (´ ␣ ␣ ␣ ␣ ␣ ␣ ´ ) procedure open gf file; { prepares to read packed bytes in gf file }

var j: integer ; begin verbose ← false; pk arg ← 3; if (argc < 2) ∨ (argc > 4) then usage; argv (1, gf name); if gf name[1] = xchr [ ] then

begin if gf name[2] = xchr [ ] then begin verbose ← true; argv (2, gf name); incr (pk arg ) end

else usage; end;

print ln(banner ); if test read access (gf name, GFFILEPATH ) then

begin reset (gf file, gf name) end

else begin print pascal string (gf name); abort (´ ␣ ␣ ␣ ␣ ´ );

end; gf loc ← 0; end;

procedure open pk file; { prepares to write packed bytes in pk file } var j, k: integer ; pk name: UNIX file name; begin if argc = pk arg then argv (argc − 1, pk name) else begin j ← FILENAMESIZE ; k ← 1;

while (j > 1) ∧ (gf name[j] ≠ xchr [ ]) do

decr (j); if gf name[j] = xchr [ ] then incr (j); { to avoid picking up the } print (xchr [ ]); print (xchr [ ␣ ]); while (j < FILENAMESIZE ) ∧ (¬(gf name[j] = xchr [ ]) ∨ (gf name[j] = xchr [ ␣ ])) do

begin pk name[k] ← gf name[j]; print (xchr [xord [gf name[j]]]); incr (j); incr (k)

end; while (j < FILENAMESIZE ) ∧ ¬(gf name[j] = xchr [ ]) do

begin if gf name[j] = xchr [ ␣ ] then abort (´ ␣` ´ ´ ␣ ␣ ´ ); pk name[k] ← gf name[j]; print (xchr [xord [gf name[j]]]); incr (k); incr (j) end;

print (xchr [xord [gf name[j]]]); incr (j); print (xchr [xord [gf name[j]]]); print (xchr [ ␣ ]); print (xchr [ ]); print (xchr [ ]); print (xchr [ ␣ ]); pk name[k] ← xchr [ ]; incr (k); pk name[k] ← xchr [ ]; incr (k); pk name[k] ← xchr [ ␣ ]; for j ← 1 to k do print (xchr [xord [pk name[j]]]); print ln(xchr [ ]) end;

rewrite(pk file, pk name); pk loc ← 0; pk open ← true end; 44* . Output is handled through putbyte which is supplied by web2c.

define pk byte(#) ≡ begin putbyte(#, pk file); incr (pk loc) end

procedure pk halfword (a : integer ); begin if a < 0 then a ← a + 65536; putbyte(a div 256, pk file); putbyte(a mod 256, pk file); pk loc ← pk loc + 2; end;

procedure pk three bytes (a : integer ); begin putbyte(a div 65536 mod 256, pk file); putbyte(a div 256 mod 256, pk file); putbyte(a mod 256, pk file); pk loc ← pk loc + 3; end;

procedure pk word (a : integer ); var b: integer ; begin if a < 0 then

begin a ← a + ´ 10000000000 ; a ← a + ´ 10000000000 ; b ← 128 + a div 16777216; end

else b ← a div 16777216; putbyte(b, pk file); putbyte(a div 65536 mod 256, pk file); putbyte(a div 256 mod 256, pk file); putbyte(a mod 256, pk file); pk loc ← pk loc + 4; end;

procedure pk nyb(a : integer );

begin if bit weight = 16 then begin output byte ← a ∗ 16; bit weight ← 1; end

else begin pk byte(output byte + a); bit weight ← 16;

end; end;

46* . Finally we come to the routines that are used for random access of the gf file. To correctly find and read the postamble of the file, we need two routines, one to find the length of the gf file, and one to position the gf file. We assume that the first byte of the file is numbered zero.

Such routines are, of course, highly system dependent. They are implemented here in terms of two assumed system routines called set pos and cur pos . The call set pos (f, n) moves to item n in file f, unless n is negative or larger than the total number of items in f; in the latter case, set pos (f, n) moves to the end of file f. The call cur pos (f) gives the total number of items in f, if eof (f) is true; we use cur pos only in such a situation.

define find gf length ≡ gf len ← gf length function gf length: integer ;

begin checked fseek (gf file, 0, 2); gf length ← ftell (gf file); end;

206  READING THE GENERIC FONT FILE  GF to PK changes C §48

procedure move to byte(n : integer ); begin checked fseek (gf file, n, 0); end; 51* . Reading the generic font file. There are two major procedures in this program that do all of the work. The first is convert gf file, which interprets the commands and puts row counts into the row array. The second, which we only anticipate at the moment, actually packs the row counts into nybbles and writes them to the packed file.

⟨ Packing procedures 62 ⟩; procedure convert gf file;

var i, j, k: integer ; { general purpose indices } gf com: integer ; { current gf command } ⟨ Locals to convert gf file 58* ⟩ begin open gf file; if gf byte ≠ pre then bad gf (´ ␣ ␣ ␣ ␣ ´ ); if gf byte ≠ gf id byte then bad gf (´ ␣ ␣ ␣ ´ ); ⟨ Find and interpret postamble 60 ⟩; move to byte(2); open pk file; ⟨ Write preamble 81 ⟩; repeat gf com ← gf byte; do the rows ← false;

case gf com of

boc, boc1 : ⟨ Interpret character 54 ⟩;

⟨ Specials and no op cases 53 ⟩; post : ; { we will actually do the work for this one later } othercases bad gf (´ ␣´ , gf com : 1, ´ ␣ ␣ ␣ ´ ) endcases;

until gf com = post ; ⟨ Write postamble 84 ⟩; end;

52* . We need a few easy macros to expand some case statements:

define four cases (#) ≡ #, # + 1, # + 2, # + 3 define sixteen cases (#) ≡ four cases (#), four cases (# + 4), four cases (# + 8), four cases (# + 12) define sixty four cases (#) ≡ sixteen cases (#), sixteen cases (# + 16), sixteen cases (# + 32),

sixteen cases (# + 48)

define thirty seven cases (#) ≡ sixteen cases (#), sixteen cases (# + 16), four cases (# + 32), # + 36 define new row 64 = new row 0 + 64 define new row 128 = new row 64 + 64

§57  GF to PK changes C  READING THE GENERIC FONT FILE 207

57* . Now we have the procedure that decodes the various commands and puts counts into the row array. This would be a trivial procedure, except for the paint 0 command. Because the paint 0 command exists, it is possible to have a sequence like paint 42, paint 0 , paint 38, paint 0 , paint 0 , paint 0 , paint 33, skip 0 . This would be an entirely empty row, but if we left the zeros in the row array, it would be difficult to recognize the row as empty.

This type of situation probably would never occur in practice, but it is defined by the format, so we must be able to handle it. The extra code is really quite simple, just difficult to understand; and it does not cut down the speed appreciably. Our goal is this: to collapse sequences like paint 42, paint 0 , paint 32 to a single count of 74, and to insure that the last count of a row is a black count rather than a white count. A buffer variable extra, and two state flags, on and state, enable us to accomplish this.

The on variable is essentially the paint switch described in the description. If it is true, then we are currently painting black pixels. The extra variable holds a count that is about to be placed into the row array. We hold it in this array until we get a paint command of the opposite color that is greater than 0. If we get a paint 0 command, then the state flag is turned on, indicating that the next count we receive can be added to the extra variable as it is the same color. ⟨ Convert character to packed form 57* ⟩ ≡

begin bad ← false; row ptr ← 2; on ← false; extra ← 0; state ← true; repeat gf com ← gf byte;

case gf com of

⟨ Cases for paint commands 59 ⟩; four cases (skip0 ): begin i ← 0;

for j ← 1 to gf com − skip0 do i ← i ∗ 256 + gf byte; if on = state then put in rows (extra); for j ← 0 to i do put in rows (end of row ); on ← false; extra ← 0; state ← true; end;

sixty four cases (new row 0 ): do the rows ← true; sixty four cases (new row 64 ): do the rows ← true; thirty seven cases (new row 128 ): do the rows ← true;

⟨ Specials and no op cases 53 ⟩; eoc: begin if on = state then put in rows (extra);

if (row ptr > 2) ∧ (row [row ptr − 1] ≠ end of row ) then put in rows (end of row ); put in rows (end of char ); if bad then abort (´ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ´ ); pack and send character ; status [gf ch mod 256 ] ← sent ; if pk loc ≠ pred pk loc then abort (´ ␣ ␣ ␣ ␣ ´ ); end;

othercases bad gf (´ ␣´ , gf com : 1, ´ ␣ ␣ ␣ ␣ ´ ); endcases;

if do the rows then

begin do the rows ← false; if on = state then put in rows (extra); put in rows (end of row ); on ← true; extra ← gf com − new row 0 ; state ← false; end;

until gf com = eoc; end

This code is used in section 54.

58* . A few more locals used above and below: ⟨ Locals to convert gf file 58* ⟩ ≡ do the rows : boolean; on: boolean; { indicates whether we are white or black } state: boolean; { a state variable—is the next count the same race as the one in the extra buffer? } extra: integer ; { where we pool our counts } bad : boolean; { did we run out of space? }

See also section 61. This code is used in section 51*.

§62  GF to PK changes C  CONVERTING THE COUNTS TO PACKED FORMAT 209

82* . Of course, we need an array to hold the comment. ⟨ Globals in the outer block 11 ⟩ +≡ comment : packed array [1 . . comm length + 1] of char ;

83* . ⟨ Set initial values 12 ⟩ +≡ vstrcpy (comment + 1, preamble comment );

86* . Finally, the main program.

begin initialize; convert gf file; ⟨ Check for un-rasterized locaters 85 ⟩; print ln(gf len : 1, ´ ␣ ␣ ␣ ␣´ , pk loc : 1, ´ ␣ ´ ); end.

210  INDEX  GF to PK changes C §89

89* . Index. Pointers to error messages appear here together with the section numbers where each identifier is used.

The following sections were changed by the change file: 1, 4, 5, 8, 37, 38, 39, 44, 46, 51, 52, 57, 58, 82, 83, 86, 89.

a: \underline{42}. abort : \underline{8*} , 39* , 57* . : 60. argc: 39* . argv : 39* . ASCII code: \underline{9}, 11. b: \underline{42}, \underline{44*} . b comp size: 68, \underline{70}. backpointers: 19. bad : 56, 57* , \underline{58*} . : 8* . bad gf : \underline{8*} , 42, 51* , 54, 56, 57* , 60. banner : \underline{1*} , 39* . bit weight : 44* , \underline{45}, 75. black : 15, 16. boc: 14, 16, \underline{17}, 18, 19, 51* , 54. boc1 : 16, \underline{17}, 51* . boolean: 38* , 40, 58* , 70, 77. buff : 64, \underline{65}, 67, 76, 80. : 60. byte file: \underline{37*} , 38* . c: \underline{42}. cc: 32. char : 10, 37* , 82* . char loc: 16, \underline{17}, 19, 60. char loc0 : \underline{16}, \underline{17}, 60. check sum: 18. check sum: 60, 81, \underline{87}. checked fseek : 46* . Chinese characters: 19. chr : 10, 11, 13. comm length: \underline{81}, 82* . comment : 81, \underline{82*} , 83* . comp size: 68, 69, 71, 72, 73, 74, \underline{77}. convert gf file: \underline{51*} , 55, 86* . count : 76, \underline{77}, 80. cs : \underline{18}, 23. cur pos : 46* . d: \underline{42}. d print ln: \underline{2}, 54, 63, 68. debugging: 2. decr : \underline{7}, 30, 39* , 60, 63, 69, 76, 81. del m: \underline{16}. del n: \underline{16}. deriv : 68, 69, \underline{70}. design size: 18. design size: 60, 81, \underline{87}. dm: \underline{16}, 32. do the rows : 51* , 57* , \underline{58*} . ds : \underline{18}, 23. dx : 16, 19, 32, \underline{48}, 60, 71, 72, 73, 74. dy : 16, 19, 32, \underline{48}, 60, 71, 72. dyn f : 28, 29, 30, 31, 32, 35, 36, 48, 62, 68,

69, \underline{70}, 71, 75. eight bits : \underline{37*} , 42. else: 3. end: 3. end of char : 48, \underline{50}, 57* , 63, 64, 66, 68, 75, 76. end of row : 48, \underline{50}, 57* , 63, 64, 66, 67. endcases: \underline{3}. eoc: 14, 16, \underline{17}, 18, 57* . eof : 42, 46* . extra: 57* , \underline{58*} , 59, 63, \underline{65}, 66, 67. false: 39* , 41, 51* , 57* , 59, 67, 76. FILENAMESIZE : 37* , 39* . final end : 8* . find gf length: \underline{46*} , 60. : 51* . first on: 68, \underline{70}, 71. first text char : \underline{10}, 13. flag : 32. flag byte: \underline{70}, 71, 72, 73, 74. four cases : \underline{52*} , 53, 57* . from length: \underline{81}. ftell : 46* . Fuchs, David Raymond: 20. get nyb: 30. gf byte: \underline{42}, 51* , 53, 54, 57* , 59, 60, 81. gf ch: 54, \underline{55}, 60, 71, 72, 73, 74. gf ch mod 256 : 54, \underline{55}, 57* , 71, 72, 73, 74. gf com: \underline{51*} , 53, 54, 57* , 59, 60. gf file: 4* , \underline{38*} , 39* , 40, 41, 42, 46* , 47, 48. GF FILE PATH BIT : 4* . gf id byte: \underline{16}, 51* , 60. gf len: 46* , \underline{47}, 60, 86* . gf length: \underline{46*} . gf loc: 39* , \underline{40}, 42. gf name: \underline{38*} , 39* . gf signed quad : \underline{42}, 53, 54, 60. GFFILEPATH : 39* . GFtoPK : \underline{4*} . h bit : \underline{65}, 67, 76, 80. h mag : 60, \underline{87}. height : 31, 63, 68, \underline{70}, 71, 72, 73, 74. hoff : 32, 34. hppp: \underline{18}, 23, 60, \underline{61}, 81. i: \underline{4*} , \underline{30}, \underline{51*} , \underline{62}, \underline{87}. : 60.

§89  GF to PK changes C  INDEX 211

: 51* . incr : \underline{7}, 30, 39* , 42, 44* , 56, 63, 64, 66, 67, 68,

69, 75, 80, 81. initialize: \underline{4*} , 86* . integer : 4* , 30, 38* , 39* , 40, 42, 44* , 45, 46* , 47, 48,

51* , 55, 58* , 61, 62, 65, 70, 77, 78, 87. : 57* . j: \underline{30}, \underline{39*} , \underline{51*} , \underline{62}. Japanese characters: 19. jump out : 8* . k: \underline{51*} , \underline{62}. Knuth, Donald Ervin: 29. last text char : \underline{10}, 13. line length: \underline{6}. located : \underline{48}, 60, 85. : 60. max m: 16, \underline{18}, 48, 54, \underline{55}, 63. max n: 16, \underline{18}, 48, 54, \underline{55}, 63. max new row : \underline{17}. max row : \underline{6}, 48, 56. max 2 : 75, \underline{77}. min m: 16, \underline{18}, 48, 54, \underline{55}, 63. min n: 16, \underline{18}, 48, 54, \underline{55}, 63. : 85. move to byte: \underline{46*} , 51* , 60. new row : 56. new row 0 : 16, \underline{17}, 52* , 57* . new row 1 : \underline{16}. new row 128 : \underline{52*} , 57* . new row 164 : \underline{16}. new row 64 : \underline{52*} , 57* . : 54. no op: 16, \underline{17}, 19, 53. : 60. on: 57* , \underline{58*} , 59, \underline{70}, 76, 80. open gf file: \underline{39*} , 51* . open pk file: \underline{39*} , 51* . ord : 11. oriental characters: 19. othercases: \underline{3}. others : 3. output : 4* . output byte: 44* , \underline{45}, 75. p bit : 76, \underline{77}, 80. pack and send character : 55, 57* , \underline{62}, 65. paint : 56, 57* . paint switch: \underline{15}, 16, 57* . paint 0 : 16, \underline{17}, 57* , 59. paint1 : 16, \underline{17}, 59. paint2 : \underline{16}. paint3 : \underline{16}. pk arg : \underline{38*} , 39* . pk byte: \underline{44*} , 53, 72, 73, 74, 75, 76, 80, 81, 84. pk file: 4* , \underline{38*} , 39* , 40, 41, 44* , 48, 60. pk halfword : \underline{44*} , 74. pk id : \underline{24}, 81. pk loc: 39* , \underline{40}, 44* , 57* , 72, 73, 74, 84, 86* . pk name: \underline{39*} . pk no op: 23, \underline{24}, 84. pk nyb: \underline{44*} , 75. pk open: 39* , \underline{40}, 41. pk packed num: \underline{30}. pk post : 23, \underline{24}, 84. pk pre: 23, \underline{24}, 81. pk three bytes : \underline{44*} , 73, 74. pk word : \underline{44*} , 53, 72, 81. pk xxx1 : 23, \underline{24}, 53. pk yyy : 23, \underline{24}, 53. pl : 32. post : 14, 16, \underline{17}, 18, 20, 51* , 60. : 60. post loc: 60, \underline{61}. post post : 16, \underline{17}, 18, 20, 60. power : \underline{78}, 79, 80. pre: 14, 16, \underline{17}, 51* . preamble comment : 1* , \underline{81}, 83* . pred pk loc: \underline{55}, 57* , 72, 73, 74. print : \underline{4*} , 39* , 81. print ln: 2, \underline{4*} , 8* , 39* , 60, 81, 85, 86* . print pascal string : 39* . proofing : 19. put count : \underline{64}, 67. put in rows : \underline{56}, 57* , 59. put ptr : 64, \underline{65}. putbyte: 44* . q: \underline{61}. r count : 76, \underline{77}. r i : 76, \underline{77}. r on: 76, \underline{77}. : 57* . read : 42. repeat count : 30. repeat flag : 64, \underline{65}, 66, 76, 80. reset : 39* . rewrite: 39* . Rokicki, Tomas Gerhard Paul: 1* . round : 60. row : 6, \underline{48}, 51* , 55, 56, 57* , 63, 64, 65, 66, 67,

68, 69, 75, 76, 80. row ptr : \underline{55}, 56, 57* , 63, 64, 66, 67. s count : 76, \underline{77}. s i : 76, \underline{77}. s on: 76, \underline{77}. Samuel, Arthur Lee: 1* . scaled : 16, 18, 19, 23. sent : \underline{48}, 57* . set paths : 4* . set pos : 46* . sixteen cases : \underline{52*} . sixty four cases : \underline{52*} , 57* , 59. skip: 56. skip 0 : 57* . skip0 : 16, \underline{17}, 57* . skip1 : 16, \underline{17}. skip2 : \underline{16}. skip3 : \underline{16}. state: 57* , \underline{58*} , 59, 64, 67, \underline{70}, 76, 80. status : \underline{48}, 49, 54, 57* , 60, 85. stdout : 4* . system dependencies: \underline{3}, 8* , 10, 20, 37* , 42, 46* , 88. term out : \underline{4*} . test read access : 39* . text char : \underline{10}, 11. text file: \underline{10}. tfm: 32, 33, 36. tfm width: \underline{48}, 60, 71, 72, 73, 74. thirty seven cases : \underline{52*} , 57* . true: 8* , 39* , 56, 57* , 64, 67, 76. uexit : 8* . undefined commands : \underline{17}. : 51* , 60. : 42. UNIX file name: \underline{37*} , 38* , 39* . usage: \underline{39*} . verbose: 4* , 8* , \underline{38*} , 39* . virgin: \underline{48}, 49, 54, 60. voff : 32, 34. vppp: \underline{18}, 23, 60, \underline{61}, 81. vstrcpy : 83* . white: 16. width: 31, 63, 66, 67, 68, \underline{70}, 71, 72, 73, 74, 76, 80. write: 4* . write ln: 4* . x offset : 63, \underline{70}, 71, 72, 73, 74. xchr : \underline{11}, 12, 13, 39* , 81. xord : \underline{11}, 13, 39* , 81. xxx1 : 16, \underline{17}, 53. xxx2 : \underline{16}. xxx3 : 16. xxx4 : \underline{16}. y offset : 63, \underline{70}, 71, 72, 73, 74. yyy : 16, \underline{17}, 19, 23, 53.

§89  GF to PK changes C  NAMES OF THE SECTIONS 213

⟨ Calculate dyn f and packed size and write character 68 ⟩ Used in section 62.

⟨ Cases for paint commands 59 ⟩ Used in section 57*.

⟨ Check for un-rasterized locaters 85 ⟩ Used in section 86*. ⟨ Constants in the outer block 6 ⟩ Used in section 4*. ⟨ Convert character to packed form 57* ⟩ Used in section 54. ⟨ Convert row-list to glyph-list 64 ⟩ Used in section 62. ⟨ Find and interpret postamble 60 ⟩ Used in section 51*.

⟨ Globals in the outer block 11, 38*, 40, 45, 47, 48, 55, 78, 82*, 87 ⟩ Used in section 4*.

⟨ Interpret character 54 ⟩ Used in section 51*.

⟨ Locals to convert gf file 58*, 61 ⟩ Used in section 51*. ⟨ Locals to pack and send character 65, 70, 77 ⟩ Used in section 62.

⟨ Packing procedures 62 ⟩ Used in section 51*. ⟨ Process count for best dyn f value 69 ⟩ Used in section 68. ⟨ Reformat count list 67 ⟩ Used in section 64. ⟨ Scan for bounding box 63 ⟩ Used in section 62.

⟨ Send bit map 76 ⟩ Used in section 68.

⟨ Send compressed format 75 ⟩ Used in section 68. ⟨ Send one row by bits 80 ⟩ Used in section 76.

⟨ Set initial values 12, 13, 41, 49, 79, 83* ⟩ Used in section 4*.

⟨ Skip over repeated rows 66 ⟩ Used in section 64.

⟨ Specials and no op cases 53 ⟩ Used in sections 51*, 57*, and 60. ⟨ Types in the outer block 9, 10, 37* ⟩ Used in section 4*.

⟨ Write character preamble 71 ⟩ Used in section 68. ⟨ Write long character preamble 72 ⟩ Used in section 71. ⟨ Write one-byte short character preamble 73 ⟩ Used in section 71.

⟨ Write postamble 84 ⟩ Used in section 51*. ⟨ Write preamble 81 ⟩ Used in section 51*.

⟨ Write two-byte short character preamble 74 ⟩ Used in section 71.

The GFtoPK processor

(Version 2.3, 29 July 1990)

Section Page

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 202 The character set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 203 Generic font file format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 203 Packed file format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 203 Input and output for binary files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 203 Plan of attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 206 Reading the generic font file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 206 Converting the counts to packed format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 209 System-dependent changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 210 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 210

The preparation of this report was supported in part by the National Science Foundation under grants IST-8201926, MCS-8300984, and CCR-8610181, and by the System Development Foundation. ‘TEX’ is a trademark of the American Mathematical Society. ‘ ’ is a trademark of Addison-Wesley Publishing Company.