1% This program by D. E. Knuth is not copyrighted and can be used freely.
2% Version 0 was completed on April 23, 1984.
3% Version 0.1 added char_code output (May 4).
4% Version 0.2 included rules and dots in the boundary calculations (May 25).
5% Version 0.3 added label type "/" (May 27).
6% Version 0.4 (by Arthur Samuel) improved the dot labeling routine (July 23).
7% Version 0.5 added the slant font for rules (September 2).
8% Version 0.6 changed label types and allowed invisible dots (September 28).
9% Version 1.0 switched to new GF format (December 8).
10% Version 1.1 switched to newer GF format (February 2, 1985).
11% Version 1.2 added the offset operations of MF version 0.8 (April 1, 1985).
12% Version 1.3 allowed online entry of gray font, etc. (April 22, 1985).
13% Version 1.4 allowed "almost" horizontal or vertical rules (May 20, 1985).
14% Version 1.5 corrected a bug in the diagonal slant routine (June 18, 1985).
15% Version 1.6 corrected a bug if labels exist but no dots (September 13, 1985).
16% Version 1.7 changed from am to cm fonts; fam became ext (October 5, 1985).
17% Version 2.0 was tuned up for the METAFONTware report (April, 1989).
18% Version 3.0 uses 8-bit codes and extended ligatures (October, 1989).
19
20% Here is TeX material that gets inserted after \input webmac
21\def\hang{\hangindent 3em\indent\ignorespaces}
22\font\ninerm=cmr9
23\let\mc=\ninerm % medium caps for names like SAIL
24\def\PASCAL{Pascal}
25\font\logo=manfnt % font used for the METAFONT logo
26\def\MF{{\logo META}\-{\logo FONT}}
27\let\swap=\leftrightarrow
28
29\def\(#1){} % this is used to make section names sort themselves better
30\def\9#1{} % this is used for sort keys in the index
31
32\def\title{GF$\,$\lowercase{to}$\,$DVI}
33\def\contentspagenumber{301}
34\def\topofcontents{\null
35  \def\titlepage{F} % include headline on the contents page
36  \def\rheader{\mainfont\hfil \contentspagenumber}
37  \vfill
38  \centerline{\titlefont The {\ttitlefont GFtoDVI} processor}
39  \vskip 15pt
40  \centerline{(Version 3.0, October 1989)}
41  \vfill}
42\def\botofcontents{\vfill
43  \centerline{\hsize 5in\baselineskip9pt
44    \vbox{\ninerm\noindent
45    The preparation of this report
46    was supported in part by the National Science
47    Foundation under grants IST-8201926, MCS-8300984, and
48    CCR-8610181,
49    and by the System Development Foundation. `\TeX' is a
50    trademark of the American Mathematical Society.
51    `{\logo hijklmnj}\kern1pt' is a trademark of Addison-Wesley
52    Publishing Company.}}}
53\pageno=\contentspagenumber \advance\pageno by 1
54
55@* Introduction.
56The \.{GFtoDVI} utility program reads binary generic font (``\.{GF}'')
57files that are produced by font compilers such as \MF, and converts them
58into device-independent (``\.{DVI}'') files that can be printed to give
59annotated hardcopy proofs of the character shapes. The annotations are
60specified by the comparatively simple conventions of plain \MF; i.e.,
61there are mechanisms for labeling chosen points and for superimposing
62horizontal or vertical rules on the enlarged character shapes.
63
64The purpose of \.{GFtoDVI} is simply to make proof copies; it does not
65exhaustively test the validity of a \.{GF} file, nor do its algorithms
66much resemble the algorithms that are typically used to prepare font
67descriptions for commercial typesetting equipment. Another program,
68\.{GFtype}, is available for validity checking; \.{GFtype} also serves
69as a model of programs that convert fonts from \.{GF} format to some
70other coding scheme.
71
72The |banner| string defined here should be changed whenever \.{GFtoDVI}
73gets modified.
74
75@d banner=='This is GFtoDVI, Version 3.0' {printed when the program starts}
76
77@ This program is written in standard \PASCAL, except where it is necessary
78to use extensions; for example, \.{GFtoDVI} must read files whose names
79are dynamically specified, and such a task would be impossible in pure \PASCAL.
80All places where nonstandard constructions are used have been listed in
81the index under ``system dependencies.''
82@!@^system dependencies@>
83
84Another exception to standard \PASCAL\ occurs in the
85use of default branches in |case| statements; the conventions
86of \.{TANGLE}, \.{WEAVE}, etc., have been followed.
87
88@d othercases == others: {default for cases not listed explicitly}
89@d endcases == @+end {follows the default case in an extended |case| statement}
90@f othercases == else
91@f endcases == end
92
93@ The main input and output files are not mentioned in the program header,
94because their external names
95will be determined at run time (e.g., by interpreting the
96command line that invokes this program). Error messages and other remarks
97are written on the |output| file, which the user may
98choose to assign to the terminal if the system permits it.
99@^system dependencies@>
100
101The term |print| is used instead of |write| when this program writes on
102the |output| file, so that all such output can be easily deflected.
103
104@d print(#)==write(#)
105@d print_ln(#)==write_ln(#)
106@d print_nl(#)==@+begin write_ln; write(#);@+end
107
108@p program GF_to_DVI(@!output);
109label @<Labels in the outer block@>@/
110const @<Constants in the outer block@>@/
111type @<Types in the outer block@>@/
112var @<Globals in the outer block@>@/
113procedure initialize; {this procedure gets things started properly}
114  var @!i,@!j,@!m,@!n:integer; {loop indices for initializations}
115  begin print_ln(banner);@/
116  @<Set initial values@>@/
117  end;
118
119@ If the program has to stop prematurely, it goes to the
120`|final_end|'.
121
122@d final_end=9999 {label for the end of it all}
123
124@<Labels...@>=final_end;
125
126@ The following parameters can be changed at compile time to extend or
127reduce \.{GFtoDVI}'s capacity.
128
129@<Constants...@>=
130@!max_labels=2000; {maximum number of labels and dots and rules per character}
131@!pool_size=10000; {maximum total length of labels and other strings}
132@!max_strings=1100; {maximum number of labels and other strings}
133@!terminal_line_length=150; {maximum number of characters input in a single
134  line of input from the terminal}
135@!file_name_size=50; {a file name shouldn't be longer than this}
136@!font_mem_size=2000; {space for font metric data}
137@!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8}
138@!widest_row=8192; {maximum number of pixels per row}
139@!lig_lookahead=20; {size of stack used when inserting ligature characters}
140
141@ Labels are given symbolic names by the following definitions, so that
142occasional |goto| statements will be meaningful. We insert the label
143`|exit|:' just before the `\ignorespaces|end|\unskip' of a procedure in
144which we have used the `|return|' statement defined below; the label
145`|reswitch|' is occasionally used just prior to a |case|
146statement in which some cases change the conditions and we wish to branch
147to the newly applicable case.  Loops that are set up with the |loop|
148construction defined below are commonly exited by going to `|done|' or to
149`|found|' or to `|not_found|', and they are sometimes repeated by going to
150`|continue|'.
151
152Incidentally, this program never declares a label that isn't actually used,
153because some fussy \PASCAL\ compilers will complain about redundant labels.
154
155@d exit=10 {go here to leave a procedure}
156@d reswitch=21 {go here to start a case statement again}
157@d continue=22 {go here to resume a loop}
158@d done=30 {go here to exit a loop}
159@d done1=31 {like |done|, when there is more than one loop}
160@d found=40 {go here when you've found it}
161@d not_found=45 {go here when you've found nothing}
162
163@ Here are some macros for common programming idioms.
164
165@d incr(#) == #:=#+1 {increase a variable by unity}
166@d decr(#) == #:=#-1 {decrease a variable by unity}
167@d loop == @+ while true do@+ {repeat over and over until a |goto| happens}
168@f loop == xclause
169  {\.{WEB}'s |xclause| acts like `\ignorespaces|while true do|\unskip'}
170@d do_nothing == {empty statement}
171@d return == goto exit {terminate a procedure call}
172@f return == nil {\.{WEB} will henceforth say |return| instead of \\{return}}
173
174@ If the \.{GF} file is badly malformed, the whole process must be aborted;
175\.{GFtoDVI} will give up, after issuing an error message about the symptoms
176that were noticed.
177
178Such errors might be discovered inside of subroutines inside of subroutines,
179so a procedure called |jump_out| has been introduced. This procedure, which
180simply transfers control to the label |final_end| at the end of the program,
181contains the only non-local |goto| statement in \.{GFtoDVI}.
182@^system dependencies@>
183
184@d abort(#)==@+begin print(' ',#); jump_out;@+end
185@d bad_gf(#)==abort('Bad GF file: ',#,'! (at byte ',cur_loc-1:1,')')
186@.Bad GF file@>
187
188@p procedure jump_out;
189begin goto final_end;
190end;
191
192@ As in \TeX\ and \MF, this program deals with numeric quantities that
193are integer multiples of~$2^{16}$, and calls them |scaled|.
194
195@d unity==@'200000 {|scaled| representation of 1.0}
196
197@<Types ...@>=
198@!scaled=integer; {fixed-point numbers}
199
200@* The character set.
201Like all programs written with the  \.{WEB} system, \.{GFtoDVI} can be
202used with any character set. But it uses ASCII code internally, because
203the programming for portable input-output is easier when a fixed internal
204code is used. Furthermore, both \.{GF} and \.{DVI} files use ASCII code
205for file names and certain other strings.
206The next few sections of \.{GFtoDVI} have therefore been copied from the
207analogous ones in the \.{WEB} system routines.
208
209@<Types ...@>=
210@!ASCII_code=0..255; {eight-bit numbers, a subrange of the integers}
211
212@ The original \PASCAL\ compiler was designed in the late 60s, when
213six-bit character sets were common, so it did not make provision for lowercase
214letters. Nowadays, of course, we need to deal with both capital and
215small letters in a convenient way.  So we shall assume that the
216\PASCAL\ system being used for \.{GFtoDVI} has a character set containing
217at least the standard visible ASCII characters (|"!"| through |"~"|). If
218additional characters are present, \.{GFtoDVI} can be configured to
219work with them too.
220
221Some \PASCAL\ compilers use the original name |char| for the data type
222associated with the characters in text files, while other \PASCAL s
223consider |char| to be a 64-element subrange of a larger data type that has
224some other name.  In order to accommodate this difference, we shall use
225the name |text_char| to stand for the data type of the characters in the
226output file.  We shall also assume that |text_char| consists of
227the elements |chr(first_text_char)| through |chr(last_text_char)|,
228inclusive. The following definitions should be adjusted if necessary.
229@^system dependencies@>
230
231@d text_char == char {the data type of characters in text files}
232@d first_text_char=0 {ordinal number of the smallest element of |text_char|}
233@d last_text_char=255 {ordinal number of the largest element of |text_char|}
234
235@<Types ...@>=
236@!text_file=packed file of text_char;
237
238@ The \.{GFtoDVI} processor converts between ASCII code and
239the user's external character set by means of arrays |xord| and |xchr|
240that are analogous to \PASCAL's |ord| and |chr| functions.
241
242@<Globals...@>=
243@!xord: array [text_char] of ASCII_code;
244  {specifies conversion of input characters}
245@!xchr: array [ASCII_code] of text_char;
246  {specifies conversion of output characters}
247
248@ Under our assumption that the visible characters of standard ASCII are
249all present, the following assignment statements initialize the
250|xchr| array properly, without needing any system-dependent changes.
251
252@<Set init...@>=
253xchr[@'40]:=' ';
254xchr[@'41]:='!';
255xchr[@'42]:='"';
256xchr[@'43]:='#';
257xchr[@'44]:='$';
258xchr[@'45]:='%';
259xchr[@'46]:='&';
260xchr[@'47]:='''';@/
261xchr[@'50]:='(';
262xchr[@'51]:=')';
263xchr[@'52]:='*';
264xchr[@'53]:='+';
265xchr[@'54]:=',';
266xchr[@'55]:='-';
267xchr[@'56]:='.';
268xchr[@'57]:='/';@/
269xchr[@'60]:='0';
270xchr[@'61]:='1';
271xchr[@'62]:='2';
272xchr[@'63]:='3';
273xchr[@'64]:='4';
274xchr[@'65]:='5';
275xchr[@'66]:='6';
276xchr[@'67]:='7';@/
277xchr[@'70]:='8';
278xchr[@'71]:='9';
279xchr[@'72]:=':';
280xchr[@'73]:=';';
281xchr[@'74]:='<';
282xchr[@'75]:='=';
283xchr[@'76]:='>';
284xchr[@'77]:='?';@/
285xchr[@'100]:='@@';
286xchr[@'101]:='A';
287xchr[@'102]:='B';
288xchr[@'103]:='C';
289xchr[@'104]:='D';
290xchr[@'105]:='E';
291xchr[@'106]:='F';
292xchr[@'107]:='G';@/
293xchr[@'110]:='H';
294xchr[@'111]:='I';
295xchr[@'112]:='J';
296xchr[@'113]:='K';
297xchr[@'114]:='L';
298xchr[@'115]:='M';
299xchr[@'116]:='N';
300xchr[@'117]:='O';@/
301xchr[@'120]:='P';
302xchr[@'121]:='Q';
303xchr[@'122]:='R';
304xchr[@'123]:='S';
305xchr[@'124]:='T';
306xchr[@'125]:='U';
307xchr[@'126]:='V';
308xchr[@'127]:='W';@/
309xchr[@'130]:='X';
310xchr[@'131]:='Y';
311xchr[@'132]:='Z';
312xchr[@'133]:='[';
313xchr[@'134]:='\';
314xchr[@'135]:=']';
315xchr[@'136]:='^';
316xchr[@'137]:='_';@/
317xchr[@'140]:='`';
318xchr[@'141]:='a';
319xchr[@'142]:='b';
320xchr[@'143]:='c';
321xchr[@'144]:='d';
322xchr[@'145]:='e';
323xchr[@'146]:='f';
324xchr[@'147]:='g';@/
325xchr[@'150]:='h';
326xchr[@'151]:='i';
327xchr[@'152]:='j';
328xchr[@'153]:='k';
329xchr[@'154]:='l';
330xchr[@'155]:='m';
331xchr[@'156]:='n';
332xchr[@'157]:='o';@/
333xchr[@'160]:='p';
334xchr[@'161]:='q';
335xchr[@'162]:='r';
336xchr[@'163]:='s';
337xchr[@'164]:='t';
338xchr[@'165]:='u';
339xchr[@'166]:='v';
340xchr[@'167]:='w';@/
341xchr[@'170]:='x';
342xchr[@'171]:='y';
343xchr[@'172]:='z';
344xchr[@'173]:='{';
345xchr[@'174]:='|';
346xchr[@'175]:='}';
347xchr[@'176]:='~';
348
349@ Here now is the system-dependent part of the character set.
350If \.{GFtoDVI} is being implemented on a garden-variety \PASCAL\ for which
351only standard ASCII codes will appear in the input and output files, you
352don't need to make any changes here. But if you have, for example, an extended
353character set like the one in Appendix~C of {\sl The \TeX book}, the first
354line of code in this module should be changed to
355$$\hbox{|for i:=0 to @'37 do xchr[i]:=chr(i);|}$$
356\.{WEB}'s character set is essentially identical to \TeX's.
357@^system dependencies@>
358
359@<Set init...@>=
360for i:=0 to @'37 do xchr[i]:='?';
361for i:=@'177 to @'377 do xchr[i]:='?';
362
363@ The following system-independent code makes the |xord| array contain a
364suitable inverse to the information in |xchr|.
365
366@<Set init...@>=
367for i:=first_text_char to last_text_char do xord[chr(i)]:=" ";
368for i:=1 to @'377 do xord[xchr[i]]:=i;
369xord['?']:="?";
370
371@ The |input_ln| routine waits for the user to type a line at his or her
372terminal; then it puts ASCII-code equivalents for the characters on that line
373into the |buffer| array. The |term_in| file is used for terminal input.
374@^system dependencies@>
375
376Since the terminal is being used for both input and output, some systems
377need a special routine to make sure that the user can see a prompt message
378before waiting for input based on that message. (Otherwise the message
379may just be sitting in a hidden buffer somewhere, and the user will have
380no idea what the program is waiting for.) We shall call a system-dependent
381subroutine |update_terminal| in order to avoid this problem.
382
383@d update_terminal == break(output) {empty the terminal output buffer}
384
385@<Glob...@>=
386@!buffer:array[0..terminal_line_length] of 0..255;
387@!term_in:text_file; {the terminal, considered as an input file}
388
389@ A global variable |line_length| records the first buffer position after
390the line just read.
391@^system dependencies@>
392
393@p procedure input_ln; {inputs a line from the terminal}
394begin update_terminal; reset(term_in);
395if eoln(term_in) then read_ln(term_in);
396line_length:=0;
397while (line_length<terminal_line_length)and not eoln(term_in) do
398  begin buffer[line_length]:=xord[term_in^]; incr(line_length); get(term_in);
399  end;
400end;
401
402@ The global variable |buf_ptr| is used while scanning each line of input;
403it points to the first unread character in |buffer|.
404
405@<Glob...@>=
406@!buf_ptr:0..terminal_line_length; {the number of characters read}
407@!line_length:0..terminal_line_length; {end of line read by |input_ln|}
408
409@* Device-independent file format.
410Before we get into the details of \.{GFtoDVI}, we need to know exactly
411what \.{DVI} files are. The form of such files was designed by David R.
412@^Fuchs, David Raymond@>
413Fuchs in 1979. Almost any reasonable typesetting device can be driven by
414a program that takes \.{DVI} files as input, and dozens of such
415\.{DVI}-to-whatever programs have been written. Thus, it is possible to
416print the output of document compilers like \TeX\ on many different kinds
417of equipment. (The following material has been copied almost verbatim from the
418program for \TeX.)
419
420A \.{DVI} file is a stream of 8-bit bytes, which may be regarded as a
421series of commands in a machine-like language. The first byte of each command
422is the operation code, and this code is followed by zero or more bytes
423that provide parameters to the command. The parameters themselves may consist
424of several consecutive bytes; for example, the `|set_rule|' command has two
425parameters, each of which is four bytes long. Parameters are usually
426regarded as nonnegative integers; but four-byte-long parameters,
427and shorter parameters that denote distances, can be
428either positive or negative. Such parameters are given in two's complement
429notation. For example, a two-byte-long distance parameter has a value between
430$-2^{15}$ and $2^{15}-1$.
431@.DVI {\rm files}@>
432
433Incidentally, when two or more 8-bit bytes are combined to form an integer of
43416 or more bits, the most significant bytes appear first in the file.
435This is called BigEndian order.
436@^BigEndian order@>
437
438A \.{DVI} file consists of a ``preamble,'' followed by a sequence of one
439or more ``pages,'' followed by a ``postamble.'' The preamble is simply a
440|pre| command, with its parameters that define the dimensions used in the
441file; this must come first.  Each ``page'' consists of a |bop| command,
442followed by any number of other commands that tell where characters are to
443be placed on a physical page, followed by an |eop| command. The pages
444appear in the order that they were generated, not in any particular
445numerical order. If we ignore |nop| commands and \\{fnt\_def} commands
446(which are allowed between any two commands in the file), each |eop|
447command is immediately followed by a |bop| command, or by a |post|
448command; in the latter case, there are no more pages in the file, and the
449remaining bytes form the postamble.  Further details about the postamble
450will be explained later.
451
452Some parameters in \.{DVI} commands are ``pointers.'' These are four-byte
453quantities that give the location number of some other byte in the file;
454the first byte is number~0, then comes number~1, and so on. For example,
455one of the parameters of a |bop| command points to the previous |bop|;
456this makes it feasible to read the pages in backwards order, in case the
457results are being directed to a device that stacks its output face up.
458Suppose the preamble of a \.{DVI} file occupies bytes 0 to 99. Now if the
459first page occupies bytes 100 to 999, say, and if the second
460page occupies bytes 1000 to 1999, then the |bop| that starts in byte 1000
461points to 100 and the |bop| that starts in byte 2000 points to 1000. (The
462very first |bop|, i.e., the one that starts in byte 100, has a pointer of $-1$.)
463
464@ The \.{DVI} format is intended to be both compact and easily interpreted
465by a machine. Compactness is achieved by making most of the information
466implicit instead of explicit. When a \.{DVI}-reading program reads the
467commands for a page, it keeps track of several quantities: (a)~The current
468font |f| is an integer; this value is changed only
469by \\{fnt} and \\{fnt\_num} commands. (b)~The current position on the page
470is given by two numbers called the horizontal and vertical coordinates,
471|h| and |v|. Both coordinates are zero at the upper left corner of the page;
472moving to the right corresponds to increasing the horizontal coordinate, and
473moving down corresponds to increasing the vertical coordinate. Thus, the
474coordinates are essentially Cartesian, except that vertical directions are
475flipped; the Cartesian version of |(h,v)| would be |(h,-v)|.  (c)~The
476current spacing amounts are given by four numbers |w|, |x|, |y|, and |z|,
477where |w| and~|x| are used for horizontal spacing and where |y| and~|z|
478are used for vertical spacing. (d)~There is a stack containing
479|(h,v,w,x,y,z)| values; the \.{DVI} commands |push| and |pop| are used to
480change the current level of operation. Note that the current font~|f| is
481not pushed and popped; the stack contains only information about
482positioning.
483
484The values of |h|, |v|, |w|, |x|, |y|, and |z| are signed integers having up
485to 32 bits, including the sign. Since they represent physical distances,
486there is a small unit of measurement such that increasing |h| by~1 means
487moving a certain tiny distance to the right. The actual unit of
488measurement is variable, as explained below.
489
490@ Here is a list of all the commands that may appear in a \.{DVI} file. Each
491command is specified by its symbolic name (e.g., |bop|), its opcode byte
492(e.g., 139), and its parameters (if any). The parameters are followed
493by a bracketed number telling how many bytes they occupy; for example,
494`|p[4]|' means that parameter |p| is four bytes long.
495
496\yskip\hang|set_char_0| 0. Typeset character number~0 from font~|f|
497such that the reference point of the character is at |(h,v)|. Then
498increase |h| by the width of that character. Note that a character may
499have zero or negative width, so one cannot be sure that |h| will advance
500after this command; but |h| usually does increase.
501
502\yskip\hang|set_char_1| through |set_char_127| (opcodes 1 to 127).
503Do the operations of |set_char_0|; but use the character whose number
504matches the opcode, instead of character~0.
505
506\yskip\hang|set1| 128 |c[1]|. Same as |set_char_0|, except that character
507number~|c| is typeset. \TeX82 uses this command for characters in the
508range |128<=c<256|.
509
510\yskip\hang|set2| 129 |c[2]|. Same as |set1|, except that |c|~is two
511bytes long, so it is in the range |0<=c<65536|.
512
513\yskip\hang|set3| 130 |c[3]|. Same as |set1|, except that |c|~is three
514bytes long, so it can be as large as $2^{24}-1$. Not even the Chinese
515language has this many characters, but this command might prove useful
516in some yet unforeseen way.
517
518\yskip\hang|set4| 131 |c[4]|. Same as |set1|, except that |c|~is four
519bytes long, possibly even negative. Imagine that.
520
521\yskip\hang|set_rule| 132 |a[4]| |b[4]|. Typeset a solid black rectangle
522of height |a| and width |b|, with its bottom left corner at |(h,v)|. Then
523set |h:=h+b|. If either |a<=0| or |b<=0|, nothing should be typeset. Note
524that if |b<0|, the value of |h| will decrease even though nothing else happens.
525
526\yskip\hang|put1| 133 |c[1]|. Typeset character number~|c| from font~|f|
527such that the reference point of the character is at |(h,v)|. (The `put'
528commands are exactly like the `set' commands, except that they simply put out a
529character or a rule without moving the reference point afterwards.)
530
531\yskip\hang|put2| 134 |c[2]|. Same as |set2|, except that |h| is not changed.
532
533\yskip\hang|put3| 135 |c[3]|. Same as |set3|, except that |h| is not changed.
534
535\yskip\hang|put4| 136 |c[4]|. Same as |set4|, except that |h| is not changed.
536
537\yskip\hang|put_rule| 137 |a[4]| |b[4]|. Same as |set_rule|, except that
538|h| is not changed.
539
540\yskip\hang|nop| 138. No operation, do nothing. Any number of |nop|'s
541may occur between \.{DVI} commands, but a |nop| cannot be inserted between
542a command and its parameters or between two parameters.
543
544\yskip\hang|bop| 139 $c_0[4]$ $c_1[4]$ $\ldots$ $c_9[4]$ $p[4]$. Beginning
545of a page: Set |(h,v,w,x,y,z):=(0,0,0,0,0,0)| and set the stack empty. Set
546the current font |f| to an undefined value.  The ten $c_i$ parameters can
547be used to identify pages, if a user wants to print only part of a \.{DVI}
548file; \TeX82 gives them the values of \.{\\count0} $\ldots$ \.{\\count9}
549at the time \.{\\shipout} was invoked for this page.  The parameter |p|
550points to the previous |bop| command in the file, where the first |bop|
551has $p=-1$.
552
553\yskip\hang|eop| 140.  End of page: Print what you have read since the
554previous |bop|. At this point the stack should be empty. (The \.{DVI}-reading
555programs that drive most output devices will have kept a buffer of the
556material that appears on the page that has just ended. This material is
557largely, but not entirely, in order by |v| coordinate and (for fixed |v|) by
558|h|~coordinate; so it usually needs to be sorted into some order that is
559appropriate for the device in question. \.{GFtoDVI} does not do such sorting.)
560
561\yskip\hang|push| 141. Push the current values of |(h,v,w,x,y,z)| onto the
562top of the stack; do not change any of these values. Note that |f| is
563not pushed.
564
565\yskip\hang|pop| 142. Pop the top six values off of the stack and assign
566them to |(h,v,w,x,y,z)|. The number of pops should never exceed the number
567of pushes, since it would be highly embarrassing if the stack were empty
568at the time of a |pop| command.
569
570\yskip\hang|right1| 143 |b[1]|. Set |h:=h+b|, i.e., move right |b| units.
571The parameter is a signed number in two's complement notation, |-128<=b<128|;
572if |b<0|, the reference point actually moves left.
573
574\yskip\hang|right2| 144 |b[2]|. Same as |right1|, except that |b| is a
575two-byte quantity in the range |-32768<=b<32768|.
576
577\yskip\hang|right3| 145 |b[3]|. Same as |right1|, except that |b| is a
578three-byte quantity in the range |@t$-2^{23}$@><=b<@t$2^{23}$@>|.
579
580\yskip\hang|right4| 146 |b[4]|. Same as |right1|, except that |b| is a
581four-byte quantity in the range |@t$-2^{31}$@><=b<@t$2^{31}$@>|.
582
583\yskip\hang|w0| 147. Set |h:=h+w|; i.e., move right |w| units. With luck,
584this parameterless command will usually suffice, because the same kind of motion
585will occur several times in succession; the following commands explain how
586|w| gets particular values.
587
588\yskip\hang|w1| 148 |b[1]|. Set |w:=b| and |h:=h+b|. The value of |b| is a
589signed quantity in two's complement notation, |-128<=b<128|. This command
590changes the current |w|~spacing and moves right by |b|.
591
592\yskip\hang|w2| 149 |b[2]|. Same as |w1|, but |b| is a two-byte-long
593parameter, |-32768<=b<32768|.
594
595\yskip\hang|w3| 150 |b[3]|. Same as |w1|, but |b| is a three-byte-long
596parameter, |@t$-2^{23}$@><=b<@t$2^{23}$@>|.
597
598\yskip\hang|w4| 151 |b[4]|. Same as |w1|, but |b| is a four-byte-long
599parameter, |@t$-2^{31}$@><=b<@t$2^{31}$@>|.
600
601\yskip\hang|x0| 152. Set |h:=h+x|; i.e., move right |x| units. The `|x|'
602commands are like the `|w|' commands except that they involve |x| instead
603of |w|.
604
605\yskip\hang|x1| 153 |b[1]|. Set |x:=b| and |h:=h+b|. The value of |b| is a
606signed quantity in two's complement notation, |-128<=b<128|. This command
607changes the current |x|~spacing and moves right by |b|.
608
609\yskip\hang|x2| 154 |b[2]|. Same as |x1|, but |b| is a two-byte-long
610parameter, |-32768<=b<32768|.
611
612\yskip\hang|x3| 155 |b[3]|. Same as |x1|, but |b| is a three-byte-long
613parameter, |@t$-2^{23}$@><=b<@t$2^{23}$@>|.
614
615\yskip\hang|x4| 156 |b[4]|. Same as |x1|, but |b| is a four-byte-long
616parameter, |@t$-2^{31}$@><=b<@t$2^{31}$@>|.
617
618\yskip\hang|down1| 157 |a[1]|. Set |v:=v+a|, i.e., move down |a| units.
619The parameter is a signed number in two's complement notation, |-128<=a<128|;
620if |a<0|, the reference point actually moves up.
621
622\yskip\hang|down2| 158 |a[2]|. Same as |down1|, except that |a| is a
623two-byte quantity in the range |-32768<=a<32768|.
624
625\yskip\hang|down3| 159 |a[3]|. Same as |down1|, except that |a| is a
626three-byte quantity in the range |@t$-2^{23}$@><=a<@t$2^{23}$@>|.
627
628\yskip\hang|down4| 160 |a[4]|. Same as |down1|, except that |a| is a
629four-byte quantity in the range |@t$-2^{31}$@><=a<@t$2^{31}$@>|.
630
631\yskip\hang|y0| 161. Set |v:=v+y|; i.e., move down |y| units. With luck,
632this parameterless command will usually suffice, because the same kind of motion
633will occur several times in succession; the following commands explain how
634|y| gets particular values.
635
636\yskip\hang|y1| 162 |a[1]|. Set |y:=a| and |v:=v+a|. The value of |a| is a
637signed quantity in two's complement notation, |-128<=a<128|. This command
638changes the current |y|~spacing and moves down by |a|.
639
640\yskip\hang|y2| 163 |a[2]|. Same as |y1|, but |a| is a two-byte-long
641parameter, |-32768<=a<32768|.
642
643\yskip\hang|y3| 164 |a[3]|. Same as |y1|, but |a| is a three-byte-long
644parameter, |@t$-2^{23}$@><=a<@t$2^{23}$@>|.
645
646\yskip\hang|y4| 165 |a[4]|. Same as |y1|, but |a| is a four-byte-long
647parameter, |@t$-2^{31}$@><=a<@t$2^{31}$@>|.
648
649\yskip\hang|z0| 166. Set |v:=v+z|; i.e., move down |z| units. The `|z|' commands
650are like the `|y|' commands except that they involve |z| instead of |y|.
651
652\yskip\hang|z1| 167 |a[1]|. Set |z:=a| and |v:=v+a|. The value of |a| is a
653signed quantity in two's complement notation, |-128<=a<128|. This command
654changes the current |z|~spacing and moves down by |a|.
655
656\yskip\hang|z2| 168 |a[2]|. Same as |z1|, but |a| is a two-byte-long
657parameter, |-32768<=a<32768|.
658
659\yskip\hang|z3| 169 |a[3]|. Same as |z1|, but |a| is a three-byte-long
660parameter, |@t$-2^{23}$@><=a<@t$2^{23}$@>|.
661
662\yskip\hang|z4| 170 |a[4]|. Same as |z1|, but |a| is a four-byte-long
663parameter, |@t$-2^{31}$@><=a<@t$2^{31}$@>|.
664
665\yskip\hang|fnt_num_0| 171. Set |f:=0|. Font 0 must previously have been
666defined by a \\{fnt\_def} instruction, as explained below.
667
668\yskip\hang|fnt_num_1| through |fnt_num_63| (opcodes 172 to 234). Set
669|f:=1|, \dots, |f:=63|, respectively.
670
671\yskip\hang|fnt1| 235 |k[1]|. Set |f:=k|. \TeX82 uses this command for font
672numbers in the range |64<=k<256|.
673
674\yskip\hang|fnt2| 236 |k[2]|. Same as |fnt1|, except that |k|~is two
675bytes long, so it is in the range |0<=k<65536|. \TeX82 never generates this
676command, but large font numbers may prove useful for specifications of
677color or texture, or they may be used for special fonts that have fixed
678numbers in some external coding scheme.
679
680\yskip\hang|fnt3| 237 |k[3]|. Same as |fnt1|, except that |k|~is three
681bytes long, so it can be as large as $2^{24}-1$.
682
683\yskip\hang|fnt4| 238 |k[4]|. Same as |fnt1|, except that |k|~is four
684bytes long; this is for the really big font numbers (and for the negative ones).
685
686\yskip\hang|xxx1| 239 |k[1]| |x[k]|. This command is undefined in
687general; it functions as a $(k+2)$-byte |nop| unless special \.{DVI}-reading
688programs are being used. \TeX82 generates |xxx1| when a short enough
689\.{\\special} appears, setting |k| to the number of bytes being sent. It
690is recommended that |x| be a string having the form of a keyword followed
691by possible parameters relevant to that keyword.
692
693\yskip\hang|xxx2| 240 |k[2]| |x[k]|. Like |xxx1|, but |0<=k<65536|.
694
695\yskip\hang|xxx3| 241 |k[3]| |x[k]|. Like |xxx1|, but |0<=k<@t$2^{24}$@>|.
696
697\yskip\hang|xxx4| 242 |k[4]| |x[k]|. Like |xxx1|, but |k| can be ridiculously
698large. \TeX82 uses |xxx4| when |xxx1| would be incorrect.
699
700\yskip\hang|fnt_def1| 243 |k[1]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
701Define font |k|, where |0<=k<256|; font definitions will be explained shortly.
702
703\yskip\hang|fnt_def2| 244 |k[2]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
704Define font |k|, where |0<=k<65536|.
705
706\yskip\hang|fnt_def3| 245 |k[3]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
707Define font |k|, where |0<=k<@t$2^{24}$@>|.
708
709\yskip\hang|fnt_def4| 246 |k[4]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
710Define font |k|, where |@t$-2^{31}$@><=k<@t$2^{31}$@>|.
711
712\yskip\hang|pre| 247 |i[1]| |num[4]| |den[4]| |mag[4]| |k[1]| |x[k]|.
713Beginning of the preamble; this must come at the very beginning of the
714file. Parameters |i|, |num|, |den|, |mag|, |k|, and |x| are explained below.
715
716\yskip\hang|post| 248. Beginning of the postamble, see below.
717
718\yskip\hang|post_post| 249. Ending of the postamble, see below.
719
720\yskip\noindent Commands 250--255 are undefined at the present time.
721
722@ Only a few of the operation codes above are actually needed by \.{GFtoDVI}.
723
724@d set1=128 {typeset a character and move right}
725@d put_rule=137 {typeset a rule}
726@d bop=139 {beginning of page}
727@d eop=140 {ending of page}
728@d push=141 {save the current positions}
729@d pop=142 {restore previous positions}
730@d right4=146 {move right}
731@d down4=160 {move down}
732@d z0=166 {move down |z|}
733@d z4=170 {move down and set |z|}
734@d fnt_num_0=171 {set current font to 0}
735@d fnt_def1=243 {define the meaning of a font number}
736@d pre=247 {preamble}
737@d post=248 {postamble beginning}
738@d post_post=249 {postamble ending}
739
740@ The preamble contains basic information about the file as a whole. As
741stated above, there are six parameters:
742$$\hbox{|@!i[1]| |@!num[4]| |@!den[4]| |@!mag[4]| |@!k[1]| |@!x[k]|.}$$
743The |i| byte identifies \.{DVI} format; currently this byte is always set
744to~2. (The value |i=3| is currently used for an extended format that
745allows a mixture of right-to-left and left-to-right typesetting.
746Some day we will set |i=4|, when \.{DVI} format makes another
747incompatible change---perhaps in the year 2048.)
748
749The next two parameters, |num| and |den|, are positive integers that define
750the units of measurement; they are the numerator and denominator of a
751fraction by which all dimensions in the \.{DVI} file could be multiplied
752in order to get lengths in units of $10^{-7}$ meters. (For example, there are
753exactly 7227 \TeX\ points in 254 centimeters, and \TeX82 works with scaled
754points where there are $2^{16}$ sp in a point, so \TeX82 sets |num=25400000|
755and $|den|=7227\cdot2^{16}=473628672$.)
756@^sp@>
757
758The |mag| parameter is what \TeX82 calls \.{\\mag}, i.e., 1000 times the
759desired magnification. The actual fraction by which dimensions are
760multiplied is therefore $|mag|\cdot|num|/1000|den|$. Note that if a \TeX\
761source document does not call for any `\.{true}' dimensions, and if you
762change it only by specifying a different \.{\\mag} setting, the \.{DVI}
763file that \TeX\ creates will be completely unchanged except for the value
764of |mag| in the preamble and postamble. (Fancy \.{DVI}-reading programs allow
765users to override the |mag|~setting when a \.{DVI} file is being printed.)
766
767Finally, |k| and |x| allow the \.{DVI} writer to include a comment, which is not
768interpreted further. The length of comment |x| is |k|, where |0<=k<256|.
769
770@d dvi_id_byte=2 {identifies the kind of \.{DVI} files described here}
771
772@ Font definitions for a given font number |k| contain further parameters
773$$\hbox{|c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.}$$
774The four-byte value |c| is the check sum that \TeX\ (or whatever program
775generated the \.{DVI} file) found in the \.{TFM} file for this font;
776|c| should match the check sum of the font found by programs that read
777this \.{DVI} file.
778@^check sum@>
779
780Parameter |s| contains a fixed-point scale factor that is applied to the
781character widths in font |k|; font dimensions in \.{TFM} files and other
782font files are relative to this quantity, which is always positive and
783less than $2^{27}$. It is given in the same units as the other dimensions
784of the \.{DVI} file.  Parameter |d| is similar to |s|; it is the ``design
785size,'' and (like~|s|) it is given in \.{DVI} units. Thus, font |k| is to be
786used at $|mag|\cdot s/1000d$ times its normal size.
787
788The remaining part of a font definition gives the external name of the font,
789which is an ASCII string of length |a+l|. The number |a| is the length
790of the ``area'' or directory, and |l| is the length of the font name itself;
791the standard local system font area is supposed to be used when |a=0|.
792The |n| field contains the area in its first |a| bytes.
793
794Font definitions must appear before the first use of a particular font number.
795Once font |k| is defined, it must not be defined again; however, we
796shall see below that font definitions appear in the postamble as well as
797in the pages, so in this sense each font number is defined exactly twice,
798if at all. Like |nop| commands, font definitions can
799appear before the first |bop|, or between an |eop| and a |bop|.
800
801@ The last page in a \.{DVI} file is followed by `|post|'; this command
802introduces the postamble, which summarizes important facts that \TeX\ has
803accumulated about the file, making it possible to print subsets of the data
804with reasonable efficiency. The postamble has the form
805$$\vbox{\halign{\hbox{#\hfil}\cr
806  |post| |p[4]| |num[4]| |den[4]| |mag[4]| |l[4]| |u[4]| |s[2]| |t[2]|\cr
807  $\langle\,$font definitions$\,\rangle$\cr
808  |post_post| |q[4]| |i[1]| 223's$[{\G}4]$\cr}}$$
809Here |p| is a pointer to the final |bop| in the file. The next three
810parameters, |num|, |den|, and |mag|, are duplicates of the quantities that
811appeared in the preamble.
812
813Parameters |l| and |u| give respectively the height-plus-depth of the tallest
814page and the width of the widest page, in the same units as other dimensions
815of the file. These numbers might be used by a \.{DVI}-reading program to
816position individual ``pages'' on large sheets of film or paper; however,
817the standard convention for output on normal size paper is to position each
818page so that the upper left-hand corner is exactly one inch from the left
819and the top. Experience has shown that it is unwise to design \.{DVI}-to-printer
820software that attempts cleverly to center the output; a fixed position of
821the upper left corner is easiest for users to understand and to work with.
822Therefore |l| and~|u| are often ignored.
823
824Parameter |s| is the maximum stack depth (i.e., the largest excess of
825|push| commands over |pop| commands) needed to process this file. Then
826comes |t|, the total number of pages (|bop| commands) present.
827
828The postamble continues with font definitions, which are any number of
829\\{fnt\_def} commands as described above, possibly interspersed with |nop|
830commands. Each font number that is used in the \.{DVI} file must be defined
831exactly twice: Once before it is first selected by a \\{fnt} command, and once
832in the postamble.
833
834@ The last part of the postamble, following the |post_post| byte that
835signifies the end of the font definitions, contains |q|, a pointer to the
836|post| command that started the postamble.  An identification byte, |i|,
837comes next; this currently equals~2, as in the preamble.
838
839The |i| byte is followed by four or more bytes that are all equal to
840the decimal number 223 (i.e., @'337 in octal). \TeX\ puts out four to seven of
841these trailing bytes, until the total length of the file is a multiple of
842four bytes, since this works out best on machines that pack four bytes per
843word; but any number of 223's is allowed, as long as there are at least four
844of them. In effect, 223 is a sort of signature that is added at the very end.
845@^Fuchs, David Raymond@>
846
847This curious way to finish off a \.{DVI} file makes it feasible for
848\.{DVI}-reading programs to find the postamble first, on most computers,
849even though \TeX\ wants to write the postamble last. Most operating
850systems permit random access to individual words or bytes of a file, so
851the \.{DVI} reader can start at the end and skip backwards over the 223's
852until finding the identification byte. Then it can back up four bytes, read
853|q|, and move to byte |q| of the file. This byte should, of course,
854contain the value 248 (|post|); now the postamble can be read, so the
855\.{DVI} reader can discover all the information needed for typesetting the
856pages. Note that it is also possible to skip through the \.{DVI} file at
857reasonably high speed to locate a particular page, if that proves
858desirable. This saves a lot of time, since \.{DVI} files used in production
859jobs tend to be large.
860
861Unfortunately, however, standard \PASCAL\ does not include the ability to
862@^system dependencies@>
863access a random position in a file, or even to determine the length of a file.
864Almost all systems nowadays provide the necessary capabilities, so \.{DVI}
865format has been designed to work most efficiently with modern operating systems.
866
867@* Generic font file format.
868The ``generic font'' (\.{GF}) input files that \.{GFtoDVI} must deal with
869have a structure that was inspired by \.{DVI} format, although the
870operation codes are quite different in most cases.  The term {\sl
871generic\/} indicates that this file format doesn't match the conventions
872of any name-brand manufacturer; but it is easy to convert \.{GF} files to
873the special format required by almost all digital phototypesetting
874equipment. There's a strong analogy between the \.{DVI} files written by
875\TeX\ and the \.{GF} files written by \MF; and, in fact, the reader will
876notice that many of the paragraphs below are identical to their
877counterparts in the description of \.{DVI} already given. The following
878description has been lifted almost verbatim from the program for \MF.
879
880A \.{GF} file is a stream of 8-bit bytes that may be
881regarded as a series of commands in a machine-like language. The first
882byte of each command is the operation code, and this code is followed by
883zero or more bytes that provide parameters to the command. The parameters
884themselves may consist of several consecutive bytes; for example, the
885`|boc|' (beginning of character) command has six parameters, each of
886which is four bytes long. Parameters are usually regarded as nonnegative
887integers; but four-byte-long parameters can be either positive or
888negative, hence they range in value from $-2^{31}$ to $2^{31}-1$.
889As in \.{DVI} files, numbers that occupy
890more than one byte position appear in BigEndian order,
891and negative numbers appear in two's complement notation.
892
893A \.{GF} file consists of a ``preamble,'' followed by a sequence of one or
894more ``characters,'' followed by a ``postamble.'' The preamble is simply a
895|pre| command, with its parameters that introduce the file; this must come
896first.  Each ``character'' consists of a |boc| command, followed by any
897number of other commands that specify ``black'' pixels,
898followed by an |eoc| command. The characters appear in the order that \MF\
899generated them. If we ignore no-op commands (which are allowed between any
900two commands in the file), each |eoc| command is immediately followed by a
901|boc| command, or by a |post| command; in the latter case, there are no
902more characters in the file, and the remaining bytes form the postamble.
903Further details about the postamble will be explained later.
904
905Some parameters in \.{GF} commands are ``pointers.'' These are four-byte
906quantities that give the location number of some other byte in the file;
907the first file byte is number~0, then comes number~1, and so on.
908
909@ The \.{GF} format is intended to be both compact and easily interpreted
910by a machine. Compactness is achieved by making most of the information
911relative instead of absolute. When a \.{GF}-reading program reads the
912commands for a character, it keeps track of two quantities: (a)~the current
913column number,~|m|; and (b)~the current row number,~|n|.  These are 32-bit
914signed integers, although most actual font formats produced from \.{GF}
915files will need to curtail this vast range because of practical
916limitations. (\MF\ output will never allow $\vert m\vert$ or $\vert
917n\vert$ to get extremely large, but the \.{GF} format tries to be more general.)
918
919How do \.{GF}'s row and column numbers correspond to the conventions
920of \TeX\ and \MF? Well, the ``reference point'' of a character, in \TeX's
921view, is considered to be at the lower left corner of the pixel in row~0
922and column~0. This point is the intersection of the baseline with the left
923edge of the type; it corresponds to location $(0,0)$ in \MF\ programs.
924Thus the pixel in \.{GF} row~0 and column~0 is \MF's unit square, comprising the
925region of the plane whose coordinates both lie between 0 and~1. The
926pixel in \.{GF} row~|n| and column~|m| consists of the points whose \MF\
927coordinates |(x,y)| satisfy |m<=x<=m+1| and |n<=y<=n+1|.  Negative values of
928|m| and~|x| correspond to columns of pixels {\sl left\/} of the reference
929point; negative values of |n| and~|y| correspond to rows of pixels {\sl
930below\/} the baseline.
931
932Besides |m| and |n|, there's also a third aspect of the current
933state, namely the @!|paint_switch|, which is always either \\{black} or
934\\{white}. Each \\{paint} command advances |m| by a specified amount~|d|,
935and blackens the intervening pixels if |paint_switch=black|; then
936the |paint_switch| changes to the opposite state. \.{GF}'s commands are
937designed so that |m| will never decrease within a row, and |n| will never
938increase within a character; hence there is no way to whiten a pixel that
939has been blackened.
940
941@ Here is a list of all the commands that may appear in a \.{GF} file. Each
942command is specified by its symbolic name (e.g., |boc|), its opcode byte
943(e.g., 67), and its parameters (if any). The parameters are followed
944by a bracketed number telling how many bytes they occupy; for example,
945`|d[2]|' means that parameter |d| is two bytes long.
946
947\yskip\hang|paint_0| 0. This is a \\{paint} command with |d=0|; it does
948nothing but change the |paint_switch| from \\{black} to \\{white} or vice~versa.
949
950\yskip\hang\\{paint\_1} through \\{paint\_63} (opcodes 1 to 63).
951These are \\{paint} commands with |d=1| to~63, defined as follows: If
952|paint_switch=black|, blacken |d|~pixels of the current row~|n|,
953in columns |m| through |m+d-1| inclusive. Then, in any case,
954complement the |paint_switch| and advance |m| by~|d|.
955
956\yskip\hang|paint1| 64 |d[1]|. This is a \\{paint} command with a specified
957value of~|d|; \MF\ uses it to paint when |64<=d<256|.
958
959\yskip\hang|paint2| 65 |d[2]|. Same as |paint1|, but |d|~can be as high
960as~65535.
961
962\yskip\hang|paint3| 66 |d[3]|. Same as |paint1|, but |d|~can be as high
963as $2^{24}-1$. \MF\ never needs this command, and it is hard to imagine
964anybody making practical use of it; surely a more compact encoding will be
965desirable when characters can be this large. But the command is there,
966anyway, just in case.
967
968\yskip\hang|boc| 67 |c[4]| |p[4]| |min_m[4]| |max_m[4]| |min_n[4]|
969|max_n[4]|. Beginning of a character:  Here |c| is the character code, and
970|p| points to the previous character beginning (if any) for characters having
971this code number modulo 256.  (The pointer |p| is |-1| if there was no
972prior character with an equivalent code.) The values of registers |m| and |n|
973defined by the instructions that follow for this character must
974satisfy |min_m<=m<=max_m| and |min_n<=n<=max_n|.  (The values of |max_m| and
975|min_n| need not be the tightest bounds possible.)  When a \.{GF}-reading
976program sees a |boc|, it can use |min_m|, |max_m|, |min_n|, and |max_n| to
977initialize the bounds of an array. Then it sets |m:=min_m|, |n:=max_n|, and
978|paint_switch:=white|.
979
980\yskip\hang|boc1| 68 |c[1]| |@!del_m[1]| |max_m[1]| |@!del_n[1]| |max_n[1]|.
981Same as |boc|, but |p| is assumed to be~$-1$; also |del_m=max_m-min_m|
982and |del_n=max_n-min_n| are given instead of |min_m| and |min_n|.
983The one-byte parameters must be between 0 and 255, inclusive.
984\ (This abbreviated |boc| saves 19~bytes per character, in common cases.)
985
986\yskip\hang|eoc| 69. End of character: All pixels blackened so far
987constitute the pattern for this character. In particular, a completely
988blank character might have |eoc| immediately following |boc|.
989
990\yskip\hang|skip0| 70. Decrease |n| by 1 and set |m:=min_m|,
991|paint_switch:=white|. \ (This finishes one row and begins another,
992ready to whiten the leftmost pixel in the new row.)
993
994\yskip\hang|skip1| 71 |d[1]|. Decrease |n| by |d+1|, set |m:=min_m|, and set
995|paint_switch:=white|. This is a way to produce |d| all-white rows.
996
997\yskip\hang|skip2| 72 |d[2]|. Same as |skip1|, but |d| can be as large
998as 65535.
999
1000\yskip\hang|skip3| 73 |d[3]|. Same as |skip1|, but |d| can be as large
1001as $2^{24}-1$. \MF\ obviously never needs this command.
1002
1003\yskip\hang|new_row_0| 74. Decrease |n| by 1 and set |m:=min_m|,
1004|paint_switch:=black|. \ (This finishes one row and begins another,
1005ready to {\sl blacken\/} the leftmost pixel in the new row.)
1006
1007\yskip\hang|@!new_row_1| through |@!new_row_164| (opcodes 75 to 238). Same as
1008|new_row_0|, but with |m:=min_m+1| through |min_m+164|, respectively.
1009
1010\yskip\hang|xxx1| 239 |k[1]| |x[k]|. This command is undefined in
1011general; it functions as a $(k+2)$-byte |no_op| unless special \.{GF}-reading
1012programs are being used. \MF\ generates \\{xxx} commands when encountering
1013a \&{special} string; this occurs in the \.{GF} file only between
1014characters, after the preamble, and before the postamble. However,
1015\\{xxx} commands might appear within characters,
1016in \.{GF} files generated by other
1017processors. It is recommended that |x| be a string having the form of a
1018keyword followed by possible parameters relevant to that keyword.
1019
1020\yskip\hang|xxx2| 240 |k[2]| |x[k]|. Like |xxx1|, but |0<=k<65536|.
1021
1022\yskip\hang|xxx3| 241 |k[3]| |x[k]|. Like |xxx1|, but |0<=k<@t$2^{24}$@>|.
1023\MF\ uses this when sending a \&{special} string whose length exceeds~255.
1024
1025\yskip\hang|xxx4| 242 |k[4]| |x[k]|. Like |xxx1|, but |k| can be
1026ridiculously large; |k| mustn't be negative.
1027
1028\yskip\hang|yyy| 243 |y[4]|. This command is undefined in general;
1029it functions as a 5-byte |no_op| unless special \.{GF}-reading programs
1030are being used. \MF\ puts |scaled| numbers into |yyy|'s, as a
1031result of \&{numspecial} commands; the intent is to provide numeric
1032parameters to \\{xxx} commands that immediately precede.
1033
1034\yskip\hang|no_op| 244. No operation, do nothing. Any number of |no_op|'s
1035may occur between \.{GF} commands, but a |no_op| cannot be inserted between
1036a command and its parameters or between two parameters.
1037
1038\yskip\hang|char_loc| 245 |c[1]| |dx[4]| |dy[4]| |w[4]| |p[4]|.
1039This command will appear only in the postamble, which will be explained shortly.
1040
1041\yskip\hang|@!char_loc0| 246 |c[1]| |@!dm[1]| |w[4]| |p[4]|.
1042Same as |char_loc|, except that |dy| is assumed to be zero, and the value
1043of~|dx| is taken to be |65536*dm|, where |0<=dm<256|.
1044
1045\yskip\hang|pre| 247 |i[1]| |k[1]| |x[k]|.
1046Beginning of the preamble; this must come at the very beginning of the
1047file. Parameter |i| is an identifying number for \.{GF} format, currently
1048131. The other information is merely commentary; it is not given
1049special interpretation like \\{xxx} commands are. (Note that \\{xxx}
1050commands may immediately follow the preamble, before the first |boc|.)
1051
1052\yskip\hang|post| 248. Beginning of the postamble, see below.
1053
1054\yskip\hang|post_post| 249. Ending of the postamble, see below.
1055
1056\yskip\noindent Commands 250--255 are undefined at the present time.
1057
1058@d gf_id_byte=131 {identifies the kind of \.{GF} files described here}
1059
1060@ Here are the opcodes that \.{GFtoDVI} actually refers to.
1061
1062@d paint_0=0 {beginning of the \\{paint} commands}
1063@d paint1=64 {move right a given number of columns, then
1064  black${}\swap{}$white}
1065@d paint2=65 {ditto, with potentially larger number of columns}
1066@d paint3=66 {ditto, with potentially excessive number of columns}
1067@d boc=67 {beginning of a character}
1068@d boc1=68 {abbreviated |boc|}
1069@d eoc=69 {end of a character}
1070@d skip0=70 {skip no blank rows}
1071@d skip1=71 {skip over blank rows}
1072@d skip2=72 {skip over lots of blank rows}
1073@d skip3=73 {skip over a huge number of blank rows}
1074@d new_row_0=74 {move down one row and then right}
1075@d xxx1=239 {for \&{special} strings}
1076@d xxx2=240 {for somewhat long \&{special} strings}
1077@d xxx3=241 {for extremely long \&{special} strings}
1078@d xxx4=242 {for incredibly long \&{special} strings}
1079@d yyy=243 {for \&{numspecial} numbers}
1080@d no_op=244 {no operation}
1081
1082@ The last character in a \.{GF} file is followed by `|post|'; this command
1083introduces the postamble, which summarizes important facts that \MF\ has
1084accumulated. The postamble has the form
1085$$\vbox{\halign{\hbox{#\hfil}\cr
1086  |post| |p[4]| |@!ds[4]| |@!cs[4]| |@!hppp[4]| |@!vppp[4]|
1087   |@!min_m[4]| |@!max_m[4]| |@!min_n[4]| |@!max_n[4]|\cr
1088  $\langle\,$character locators$\,\rangle$\cr
1089  |post_post| |q[4]| |i[1]| 223's$[{\G}4]$\cr}}$$
1090Here |p| is a pointer to the byte following the final |eoc| in the file
1091(or to the byte following the preamble, if there are no characters);
1092it can be used to locate the beginning of \\{xxx} commands
1093that might have preceded the postamble. The |ds| and |cs| parameters
1094@^design size@> @^check sum@>
1095give the design size and check sum, respectively, of the font (see the
1096description of \.{TFM} format below).
1097Parameters |hppp| and |vppp| are the ratios of
1098pixels per point, horizontally and vertically, expressed as |scaled| integers
1099(i.e., multiplied by $2^{16}$); they can be used to correlate the font
1100with specific device resolutions, magnifications, and ``at sizes.''  Then
1101come |min_m|, |max_m|, |min_n|, and |max_n|, which bound the values that
1102registers |m| and~|n| assume in all characters in this \.{GF} file.
1103(These bounds need not be the best possible; |max_m| and |min_n| may, on the
1104other hand, be tighter than the similar bounds in |boc| commands. For
1105example, some character may have |min_n=-100| in its |boc|, but it might
1106turn out that |n| never gets lower than |-50| in any character; then
1107|min_n| can have any value |<=-50|. If there are no characters in the file,
1108it's possible to have |min_m>max_m| and/or |min_n>max_n|.)
1109
1110@ Character locators are introduced by |char_loc| commands,
1111which specify a character residue~|c|, character escapements (|dx,dy|),
1112a character width~|w|, and a pointer~|p|
1113to the beginning of that character. (If two or more characters have the
1114same code~|c| modulo 256, only the last will be indicated; the others can be
1115located by following backpointers. Characters whose codes differ by a
1116multiple of 256 are assumed to share the same font metric information,
1117hence the \.{TFM} file contains only residues of character codes modulo~256.
1118This convention is intended for oriental languages, when there are many
1119character shapes but few distinct widths.)
1120@^oriental characters@>@^Chinese characters@>@^Japanese characters@>
1121
1122The character escapements (|dx,dy|) are the values of \MF's \&{chardx}
1123and \&{chardy} parameters; they are in units of |scaled| pixels;
1124i.e., |dx| is in horizontal pixel units times $2^{16}$, and |dy| is in
1125vertical pixel units times $2^{16}$.  This is the intended amount of
1126displacement after typesetting the character; for \.{DVI} files, |dy|
1127should be zero, but other document file formats allow nonzero vertical
1128escapement.
1129
1130The character width~|w| duplicates the information in the \.{TFM} file; it
1131is $2^{24}$ times the ratio of the true width to the font's design size.
1132
1133The backpointer |p| points to the character's |boc|, or to the first of
1134a sequence of consecutive \\{xxx} or |yyy| or |no_op| commands that
1135immediately precede the |boc|, if such commands exist; such ``special''
1136commands essentially belong to the characters, while the special commands
1137after the final character belong to the postamble (i.e., to the font
1138as a whole). This convention about |p| applies also to the backpointers
1139in |boc| commands, even though it wasn't explained in the description
1140of~|boc|. @^backpointers@>
1141
1142Pointer |p| might be |-1| if the character exists in the \.{TFM} file
1143but not in the \.{GF} file. This unusual situation can arise in \MF\ output
1144if the user had |proofing<0| when the character was being shipped out,
1145but then made |proofing>=0| in order to get a \.{GF} file.
1146
1147@ The last part of the postamble, following the |post_post| byte that
1148signifies the end of the character locators, contains |q|, a pointer to the
1149|post| command that started the postamble.  An identification byte, |i|,
1150comes next; this currently equals~131, as in the preamble.
1151
1152The |i| byte is followed by four or more bytes that are all equal to
1153the decimal number 223 (i.e., @'337 in octal). \MF\ puts out four to seven of
1154these trailing bytes, until the total length of the file is a multiple of
1155four bytes, since this works out best on machines that pack four bytes per
1156word; but any number of 223's is allowed, as long as there are at least four
1157of them. In effect, 223 is a sort of signature that is added at the very end.
1158@^Fuchs, David Raymond@>
1159
1160This curious way to finish off a \.{GF} file makes it feasible for
1161\.{GF}-reading programs to find the postamble first, on most computers,
1162even though \MF\ wants to write the postamble last. Most operating
1163systems permit random access to individual words or bytes of a file, so
1164the \.{GF} reader can start at the end and skip backwards over the 223's
1165until finding the identification byte. Then it can back up four bytes, read
1166|q|, and move to byte |q| of the file. This byte should, of course,
1167contain the value 248 (|post|); now the postamble can be read, so the
1168\.{GF} reader can discover all the information needed for individual characters.
1169
1170Unfortunately, however, standard \PASCAL\ does not include the ability to
1171@^system dependencies@>
1172access a random position in a file, or even to determine the length of a file.
1173Almost all systems nowadays provide the necessary capabilities, so \.{GF}
1174format has been designed to work most efficiently with modern operating systems.
1175But if \.{GF} files have to be processed under the restrictions of standard
1176\PASCAL, one can simply read them from front to back. This will
1177be adequate for most applications. However, the postamble-first approach
1178would facilitate a program that merges two \.{GF} files, replacing data
1179from one that is overridden by corresponding data in the other.
1180
1181@* Extensions to the generic format.
1182The \\{xxx} and \\{yyy} instructions understood by \.{GFtoDVI} will be
1183listed now, so that we have a convenient reference to all of the special
1184assumptions made later.
1185
1186Each special instruction begins with an \\{xxx} command, which consists of
1187either a keyword by itself, or a keyword followed by a space followed
1188by arguments. This \\{xxx} command may then be followed by \\{yyy}
1189commands that are understood to be arguments.
1190
1191The keywords of special instructions that are intended to be used at
1192many different sites should be published as widely as possible in order
1193to minimize conflicts. The first person to establish a keyword presumably
1194has a right to define it; \.{GFtoDVI}, as the first program
1195to use extended \.{GF} commands, has the opportunity of choosing any
1196keywords it likes, and the responsibility of choosing reasonable ones.
1197Since labels are expected to account for the bulk of extended commands
1198in typical uses of \MF, the ``null'' keyword has been set aside to
1199denote a labeling command.
1200
1201@ Here then are the special commands of \.{GFtoDVI}.
1202
1203\def\string{$\langle\,$string$\,\rangle$}
1204\def\okpagebreak{\vfil\penalty-100\vfilneg}
1205\smallskip\hang\noindent
1206\.{\SP n}\string\ $x$ $y$. Here \.n denotes the type of label; the
1207characters \.1, \.2, \.3,~\.4 respectively denote labels forced to be
1208at the top, left, right, or bottom of their dot, and the characters
1209\.5, \.6, \.7,~\.8 stand for the same possibilities but with no dot printed.
1210The character \.0 instructs \.{GFtoDVI} to choose one of the first four
1211possibilities, if there's no overlap with other labels or dots, otherwise
1212an ``overflow'' entry is placed at the right of the figure. The character
1213\./ is the same as \.0 except that overflow entries are not produced. The
1214label itself is the \string\ that follows. \MF\ coordinates of the
1215point that is to receive this label are given by arguments $x$ and~$y$,
1216in units of scaled pixels. (These arguments appear in \\{yyy} commands.)
1217(Precise definitions of the size and positioning of labels, and of the
1218notion of ``conflicting'' labels, will be given later.)
1219
1220\smallskip\hang\noindent
1221\.{rule} $x_1$ $y_1$ $x_2$ $y_2$. This command draws a line from
1222$(x_1,y_1)$ to $(x_2,y_2)$ in \MF\ coordinates. The present implementation
1223does this only if the line is either horizontal or vertical, or if its
1224slope matches the slope of the slant font.
1225
1226\smallskip\hang\noindent
1227\.{title\SP}\string. This command (which is output by \MF\
1228when it sees a ``title statement'') specifies a string that will appear
1229at the top of the next proofsheet to be output by \.{GFtoDVI}.
1230If more than one title is given, they will appear in sequence; titles
1231should be short enough to fit on a single line.
1232
1233\smallskip\hang\noindent
1234\.{titlefont\SP}\string. This command, and the other font-naming
1235commands below, must precede the first |boc| in the \.{GF} file.
1236It overrides the current font used to
1237typeset the titles at the top of proofsheets. \.{GFtoDVI} has default
1238fonts that will be used if none other are specified; the ``current'' title
1239font is initially the default title font.
1240
1241\smallskip\hang\noindent
1242\.{titlefontarea\SP}\string. This command overrides the current
1243file area (or directory name) from which \.{GFtoDVI} will try to
1244find metric information for the title font.
1245
1246\smallskip\hang\noindent
1247\.{titlefontat} $s$. This command overrides the current ``at size'' that
1248will be used for the title font. (See the discussion of font metric files
1249below, for the meaning of ``at size'' versus ``design size.'') The
1250value of~$s$ is given in units of scaled points.
1251
1252\okpagebreak
1253\smallskip\hang\noindent
1254\.{labelfont\SP}\string. This command overrides the current font
1255used to typeset the labels that are superimposed on proof figures.
1256(The label font is fairly arbitrary, but it should be dark enough to
1257stand out when superimposed on gray pixels, and it should contain at
1258least the decimal digits and the characters `\.(', `\.)', `\.=', `\.+',
1259`\.-', `\.,', and `\..'.)
1260
1261\smallskip\hang\noindent
1262\.{labelfontarea\SP}\string. This command overrides the current
1263file area (or directory name) from which \.{GFtoDVI} will try to
1264find metric information for the label font.
1265
1266\smallskip\hang\noindent
1267\.{labelfontat} $s$. This command overrides the current ``at size'' that
1268will be used for the label font.
1269
1270\okpagebreak
1271\smallskip\hang\noindent
1272\.{grayfont\SP}\string. This command overrides the current font
1273used to typeset the black pixels and the dots for labels. (Gray fonts
1274will be explained in detail later.)
1275@^gray fonts@>
1276
1277\smallskip\hang\noindent
1278\.{grayfontarea\SP}\string. This command overrides the current
1279file area (or directory name) from which \.{GFtoDVI} will try to
1280find metric information for the gray font.
1281
1282\smallskip\hang\noindent
1283\.{grayfontat} $s$. This command overrides the current ``at size'' that
1284will be used for the gray font.
1285
1286\okpagebreak
1287\smallskip\hang\noindent
1288\.{slantfont\SP}\string. This command overrides the current font
1289used to typeset rules that are neither horizontal nor vertical. (Slant
1290fonts will be explained in detail later.)
1291@^slant fonts@>
1292
1293\smallskip\hang\noindent
1294\.{slantfontarea\SP}\string. This command overrides the current
1295file area (or directory name) from which \.{GFtoDVI} will try to
1296find metric information for the slant font.
1297
1298\smallskip\hang\noindent
1299\.{slantfontat} $s$. This command overrides the current ``at size'' that
1300will be used for the slant font.
1301
1302\okpagebreak
1303\smallskip\hang\noindent
1304\.{rulethickness} $t$. This command overrides the current value used
1305for the thickness of rules. If the current value is negative, no rule
1306will be drawn; if the current value is zero, the rule thickness will
1307be specified by a parameter of the gray font. Each \.{rule} command
1308uses the rule thickness that is current at the time the command appears;
1309hence it is possible to get different thicknesses of rules on the same
1310figure. The value of $t$ is given in units of scaled points (\TeX's `\.{sp}').
1311At the beginning of each character the current rule thickness is zero.
1312
1313\smallskip\hang\noindent
1314\.{offset} $x$ $y$. This command overrides the current offset values
1315that are added to all coordinates of a character being output; $x$ and
1316$y$ are given as scaled \MF\ coordinates. This simply has the effect
1317of repositioning the figures on the pages; the title line always appears
1318in the same place, but the figure can be moved up, down, left, or right.
1319At the beginning of each character the current offsets are zero.
1320
1321\smallskip\hang\noindent
1322\.{xoffset} $x$. This command is output by \MF\ just before shipping out
1323a character whose $x$~offset is nonzero. \.{GFtoDVI} adds the specified
1324amount to the $x$ coordinates of all dots, labels, and rules
1325in the following character.
1326
1327\smallskip\hang\noindent
1328\.{yoffset} $y$. This command is output by \MF\ just before shipping out
1329a character whose $y$~offset is nonzero. \.{GFtoDVI} adds the specified
1330amount to the $y$ coordinates of all dots, labels, and rules
1331in the following character.
1332
1333@* Font metric data.
1334Before we can get into the meaty details of \.{GFtoDVI}, we need to
1335deal with yet another esoteric binary file format, since \.{GFtoDVI}
1336also does elementary typesetting operations. Therefore it has to
1337read important information about the fonts it will be using.
1338The following material (again copied almost verbatim from \TeX)
1339describes the contents of so-called \TeX\ font metric (\.{TFM}) files.
1340
1341The idea behind \.{TFM} files is that typesetting routines
1342need a compact way to store the relevant information about
1343fonts, and computer centers need a compact way to store the
1344relevant information about several hundred fonts. \.{TFM} files are
1345compact, and most of the information they contain is highly relevant,
1346so they provide a solution to the problem. \.{GFtoDVI} uses only
1347four fonts, but interesting changes in its output will occur when
1348those fonts are varied.
1349
1350The information in a \.{TFM} file appears in a sequence of 8-bit bytes.
1351Since the number of bytes is always a multiple of 4, we could
1352also regard the file as a sequence of 32-bit words; but \TeX\ uses the
1353byte interpretation, and so does \.{GFtoDVI}. The individual bytes
1354are considered to be unsigned numbers.
1355
1356@ The first 24 bytes (6 words) of a \.{TFM} file contain twelve 16-bit
1357integers that give the lengths of the various subsequent portions
1358of the file. These twelve integers are, in order:
1359$$\vbox{\halign{\hfil#&$\null=\null$#\hfil\cr
1360|@!lf|&length of the entire file, in words;\cr
1361|@!lh|&length of the header data, in words;\cr
1362|@!bc|&smallest character code in the font;\cr
1363|@!ec|&largest character code in the font;\cr
1364|@!nw|&number of words in the width table;\cr
1365|@!nh|&number of words in the height table;\cr
1366|@!nd|&number of words in the depth table;\cr
1367|@!ni|&number of words in the italic correction table;\cr
1368|@!nl|&number of words in the lig/kern table;\cr
1369|@!nk|&number of words in the kern table;\cr
1370|@!ne|&number of words in the extensible character table;\cr
1371|@!np|&number of font parameter words.\cr}}$$
1372They are all nonnegative and less than $2^{15}$. We must have |bc-1<=ec<=255|,
1373and
1374$$\hbox{|lf=6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.}$$
1375Note that a font may contain as many as 256 characters (if |bc=0| and |ec=255|),
1376and as few as 0 characters (if |bc=ec+1|). When two or more 8-bit bytes are
1377combined to form an integer of 16 or more bits, the bytes appear in
1378BigEndian order.
1379@^BigEndian order@>
1380
1381@<Glob...@>=
1382@!lf,@!lh,@!bc,@!ec,@!nw,@!nh,@!nd,@!ni,@!nl,@!nk,@!ne,@!np:0..@'77777;
1383  {subfile sizes}
1384
1385@ The rest of the \.{TFM} file may be regarded as a sequence of ten data
1386arrays having the informal specification
1387$$\def\arr$[#1]#2${\&{array} $[#1]$ \&{of} #2}
1388\vbox{\halign{\hfil\\{#}&$\,:\,$\arr#\hfil\cr
1389header&|[0..lh-1]@t\\{stuff}@>|\cr
1390char\_info&|[bc..ec]char_info_word|\cr
1391width&|[0..nw-1]fix_word|\cr
1392height&|[0..nh-1]fix_word|\cr
1393depth&|[0..nd-1]fix_word|\cr
1394italic&|[0..ni-1]fix_word|\cr
1395lig\_kern&|[0..nl-1]lig_kern_command|\cr
1396kern&|[0..nk-1]fix_word|\cr
1397exten&|[0..ne-1]extensible_recipe|\cr
1398param&|[1..np]fix_word|\cr}}$$
1399The most important data type used here is a |@!fix_word|, which is
1400a 32-bit representation of a binary fraction. A |fix_word| is a signed
1401quantity, with the two's complement of the entire word used to represent
1402negation. Of the 32 bits in a |fix_word|, exactly 12 are to the left of the
1403binary point; thus, the largest |fix_word| value is $2048-2^{-20}$, and
1404the smallest is $-2048$. We will see below, however, that all but two of
1405the |fix_word| values must lie between $-16$ and $+16$.
1406
1407@ The first data array is a block of header information, which contains
1408general facts about the font. The header must contain at least two words,
1409and for \.{TFM} files to be used with Xerox printing software it must
1410contain at least 18 words, allocated as described below. When different
1411kinds of devices need to be interfaced, it may be necessary to add further
1412words to the header block.
1413
1414\yskip\hang|header[0]| is a 32-bit check sum that \.{GFtoDVI} will copy into the
1415\.{DVI} output file whenever it uses the font.  Later on when the \.{DVI}
1416file is printed, possibly on another computer, the actual font that gets
1417used is supposed to have a check sum that agrees with the one in the
1418\.{TFM} file used by \.{GFtoDVI}. In this way, users will be warned about
1419potential incompatibilities. (However, if the check sum is zero in either
1420the font file or the \.{TFM} file, no check is made.)  The actual relation
1421between this check sum and the rest of the \.{TFM} file is not important;
1422the check sum is simply an identification number with the property that
1423incompatible fonts almost always have distinct check sums.
1424@^check sum@>
1425
1426\yskip\hang|header[1]| is a |fix_word| containing the design size of the
1427font, in units of \TeX\ points (7227 \TeX\ points = 254 cm).  This number
1428must be at least 1.0; it is fairly arbitrary, but usually the design size
1429is 10.0 for a ``10 point'' font, i.e., a font that was designed to look
1430best at a 10-point size, whatever that really means. When a \TeX\ user
1431asks for a font `\.{at} $\delta$ \.{pt}', the effect is to override the
1432design size and replace it by $\delta$, and to multiply the $x$ and~$y$
1433coordinates of the points in the font image by a factor of $\delta$
1434divided by the design size.  Similarly, specific sizes can be substituted
1435for the design size by \.{GFtoDVI} commands like `\.{titlefontat}'.  {\sl
1436All other dimensions in the\/\ \.{TFM} file are |fix_word| numbers in
1437design-size units.} Thus, for example, the value of |param[6]|, one \.{em}
1438or \.{\\quad}, is often the |fix_word| value $2^{20}=1.0$, since many
1439fonts have a design size equal to one em.  The other dimensions must be
1440less than 16 design-size units in absolute value; thus, |header[1]| and
1441|param[1]| are the only |fix_word| entries in the whole \.{TFM} file whose
1442first byte might be something besides 0 or 255.  @^design size@>@^at size@>
1443
1444\yskip\hang|header[2..11]|, if present, contains 40 bytes that identify
1445the character coding scheme. The first byte, which must be between 0 and
144639, is the number of subsequent ASCII bytes actually relevant in this
1447string, which is intended to specify what character-code-to-symbol
1448convention is present in the font.  Examples are \.{ASCII} for standard
1449ASCII, \.{TeX text} for fonts like \.{cmr10} and \.{cmti9}, \.{TeX math
1450extension} for \.{cmex10}, \.{XEROX text} for Xerox fonts, \.{GRAPHIC} for
1451special-purpose non-alphabetic fonts, \.{GFGRAY} for \.{GFtoDVI}'s
1452gray fonts, \.{GFSLANT} for \.{GFtoDVI}'s slant fonts, \.{UNSPECIFIED} for
1453the default case when there is no information.  Parentheses should not
1454appear in this name.  (Such a string is said to be in {\mc BCPL} format.)
1455@^coding scheme@>@^gray fonts@>@^slant fonts@>
1456
1457\yskip\hang|header[12..@twhatever@>]| might also be present.
1458
1459@ Next comes the |char_info| array, which contains one |char_info_word|
1460per character. Each |char_info_word| contains six fields packed into
1461four bytes as follows.
1462
1463\yskip\hang first byte: |@!width_index| (8 bits)\par
1464\hang second byte: |@!height_index| (4 bits) times 16, plus |@!depth_index|
1465  (4~bits)\par
1466\hang third byte: |@!italic_index| (6 bits) times 4, plus |@!tag|
1467  (2~bits)\par
1468\hang fourth byte: |@!remainder| (8 bits)\par
1469\yskip\noindent
1470The actual width of a character is \\{width}|[width_index]|, in design-size
1471units; this is a device for compressing information, since many characters
1472have the same width. Since it is quite common for many characters
1473to have the same height, depth, or italic correction, the \.{TFM} format
1474imposes a limit of 16 different heights, 16 different depths, and
147564 different italic corrections.
1476
1477Incidentally, the relation $\\{width}[0]=\\{height}[0]=\\{depth}[0]=
1478\\{italic}[0]=0$ should always hold, so that an index of zero implies a
1479value of zero.  The |width_index| should never be zero unless the
1480character does not exist in the font, since a character is valid if and
1481only if it lies between |bc| and |ec| and has a nonzero |width_index|.
1482
1483@ The |tag| field in a |char_info_word| has four values that explain how to
1484interpret the |remainder| field.
1485
1486\yskip\hang|tag=0| (|no_tag|) means that |remainder| is unused.\par
1487\hang|tag=1| (|lig_tag|) means that this character has a ligature/kerning
1488program starting at |lig_kern[remainder]|.\par
1489\hang|tag=2| (|list_tag|) means that this character is part of a chain of
1490characters of ascending sizes, and not the largest in the chain.  The
1491|remainder| field gives the character code of the next larger character.\par
1492\hang|tag=3| (|ext_tag|) means that this character code represents an
1493extensible character, i.e., a character that is built up of smaller pieces
1494so that it can be made arbitrarily large. The pieces are specified in
1495|@!exten[remainder]|.\par
1496
1497@d no_tag=0 {vanilla character}
1498@d lig_tag=1 {character has a ligature/kerning program}
1499@d list_tag=2 {character has a successor in a charlist}
1500@d ext_tag=3 {character is extensible}
1501
1502@ The |lig_kern| array contains instructions in a simple programming language
1503that explains what to do for special letter pairs. Each word in this array is a
1504|@!lig_kern_command| of four bytes.
1505
1506\yskip\hang first byte: |skip_byte|, indicates that this is the final program
1507  step if the byte is 128 or more, otherwise the next step is obtained by
1508  skipping this number of intervening steps.\par
1509\hang second byte: |next_char|, ``if |next_char| follows the current character,
1510  then perform the operation and stop, otherwise continue.''\par
1511\hang third byte: |op_byte|, indicates a ligature step if less than~128,
1512  a kern step otherwise.\par
1513\hang fourth byte: |remainder|.\par
1514\yskip\noindent
1515In a kern step, an
1516additional space equal to |kern[256*(op_byte-128)+remainder]| is inserted
1517between the current character and |next_char|. This amount is
1518often negative, so that the characters are brought closer together
1519by kerning; but it might be positive.
1520
1521There are eight kinds of ligature steps, having |op_byte| codes $4a+2b+c$ where
1522$0\le a\le b+c$ and $0\le b,c\le1$. The character whose code is
1523|remainder| is inserted between the current character and |next_char|;
1524then the current character is deleted if $b=0$, and |next_char| is
1525deleted if $c=0$; then we pass over $a$~characters to reach the next
1526current character (which may have a ligature/kerning program of its own).
1527
1528If the very first instruction of the |lig_kern| array has |skip_byte=255|,
1529the |next_char| byte is the so-called right boundary character of this font;
1530the value of |next_char| need not lie between |bc| and~|ec|.
1531If the very last instruction of the |lig_kern| array has |skip_byte=255|,
1532there is a special ligature/kerning program for a left boundary character,
1533beginning at location |256*op_byte+remainder|.
1534The interpretation is that \TeX\ puts implicit boundary characters
1535before and after each consecutive string of characters from the same font.
1536These implicit characters do not appear in the output, but they can affect
1537ligatures and kerning.
1538
1539If the very first instruction of a character's |lig_kern| program has
1540|skip_byte>128|, the program actually begins in location
1541|256*op_byte+remainder|. This feature allows access to large |lig_kern|
1542arrays, because the first instruction must otherwise
1543appear in a location |<=255|.
1544
1545Any instruction with |skip_byte>128| in the |lig_kern| array must have
1546|256*op_byte+remainder<nl|. If such an instruction is encountered during
1547normal program execution, it denotes an unconditional halt; no ligature
1548or kerning command is performed.
1549
1550@d stop_flag=128 {value indicating `\.{STOP}' in a lig/kern program}
1551@d kern_flag=128 {op code for a kern step}
1552
1553@ Extensible characters are specified by an |@!extensible_recipe|, which
1554consists of four bytes called |@!top|, |@!mid|, |@!bot|, and |@!rep| (in this
1555order). These bytes are the character codes of individual pieces used to
1556build up a large symbol.  If |top|, |mid|, or |bot| are zero, they are not
1557present in the built-up result. For example, an extensible vertical line is
1558like an extensible bracket, except that the top and bottom pieces are missing.
1559
1560@ The final portion of a \.{TFM} file is the |param| array, which is another
1561sequence of |fix_word| values.
1562
1563\yskip\hang|param[1]=@!slant| is the amount of italic slant.
1564For example, |slant=.25| means that when you go
1565up one unit, you also go .25 units to the right. The |slant| is a pure
1566number; it's the only |fix_word| other than the design size itself that is
1567not scaled by the design size.
1568
1569\hang|param[2]=space| is the normal spacing between words in text.
1570Note that character |" "| in the font need not have anything to do with
1571blank spaces.
1572
1573\hang|param[3]=space_stretch| is the amount of glue stretching between words.
1574
1575\hang|param[4]=space_shrink| is the amount of glue shrinking between words.
1576
1577\hang|param[5]=x_height| is the height of letters for which accents don't
1578have to be raised or lowered.
1579
1580\hang|param[6]=quad| is the size of one em in the font.
1581
1582\hang|param[7]=extra_space| is the amount added to |param[2]| at the
1583ends of sentences.
1584
1585When the character coding scheme is \.{GFGRAY} or \.{GFSLANT}, the font is
1586supposed to contain an additional parameter called
1587|default_rule_thickness|. Other special parameters go with other coding
1588schemes.
1589
1590@* Input from binary files.
1591We have seen that \.{GF} and \.{DVI} and \.{TFM} files are sequences of
15928-bit bytes.  The bytes appear physically in what is called a `|packed
1593file of 0..255|' in \PASCAL\ lingo.
1594
1595Packing is system dependent, and many \PASCAL\ systems fail to implement
1596such files in a sensible way (at least, from the viewpoint of producing
1597good production software).  For example, some systems treat all
1598byte-oriented files as text, looking for end-of-line marks and such
1599things. Therefore some system-dependent code is often needed to deal with
1600binary files, even though most of the program in this section of
1601\.{GFtoDVI} is written in standard \PASCAL.
1602@^system dependencies@>
1603
1604One common way to solve the problem is to consider files of |integer|
1605numbers, and to convert an integer in the range $-2^{31}\L x<2^{31}$ to
1606a sequence of four bytes $(a,b,c,d)$ using the following code, which
1607avoids the controversial integer division of negative numbers:
1608$$\vbox{\halign{#\hfil\cr
1609|if x>=0 then a:=x div @'100000000|\cr
1610|else begin x:=(x+@'10000000000)+@'10000000000; a:=x div @'100000000+128;|\cr
1611\quad|end|;\cr
1612|x:=x mod @'100000000;|\cr
1613|b:=x div @'200000; x:=x mod @'200000;|\cr
1614|c:=x div @'400; d:=x mod @'400;|\cr}}$$
1615The four bytes are then kept in a buffer and output one by one. (On 36-bit
1616computers, an additional division by 16 is necessary at the beginning.
1617Another way to separate an integer into four bytes is to use/abuse
1618\PASCAL's variant records, storing an integer and retrieving bytes that are
1619packed in the same place; {\sl caveat implementor!\/}) It is also desirable
1620in some cases to read a hundred or so integers at a time, maintaining a
1621larger buffer.
1622
1623We shall stick to simple \PASCAL\ in this program, for reasons of clarity,
1624even if such simplicity is sometimes unrealistic.
1625
1626@<Types ...@>=
1627@!eight_bits=0..255; {unsigned one-byte quantity}
1628@!byte_file=packed file of eight_bits; {files that contain binary data}
1629
1630@ The program deals with three binary file variables: |gf_file| is the main
1631input file that we are converting into a document; |dvi_file| is the main
1632output file that will specify that document; and |tfm_file| is
1633the current font metric file from which character-width information is
1634being read.
1635
1636@<Glob...@>=
1637@!gf_file:byte_file; {the character data we are reading}
1638@!dvi_file:byte_file; {the typesetting instructions we are writing}
1639@!tfm_file:byte_file; {a font metric file}
1640
1641@ To prepare these files for input or output, we |reset| or |rewrite|
1642them. An extension of \PASCAL\ is needed, since we want to associate
1643it with external files whose names are specified dynamically (i.e., not
1644known at compile time). The following code assumes that `|reset(f,s)|' and
1645`|rewrite(f,s)|' do this, when |f| is a file variable and |s| is a string
1646variable that specifies the file name.
1647@^system dependencies@>
1648
1649@p procedure open_gf_file; {prepares to read packed bytes in |gf_file|}
1650begin reset(gf_file,name_of_file);
1651cur_loc:=0;
1652end;
1653@#
1654procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|}
1655begin reset(tfm_file,name_of_file);
1656end;
1657@#
1658procedure open_dvi_file; {prepares to write packed bytes in |dvi_file|}
1659begin rewrite(dvi_file,name_of_file);
1660end;
1661
1662@ If you looked carefully at the preceding code, you probably asked,
1663``What are |cur_loc| and |name_of_file|?'' Good question. They are global
1664variables: The integer |cur_loc| tells which byte of the input file will
1665be read next, and the string |name_of_file| will be set to the current
1666file name before the file-opening procedures are called.
1667
1668@<Glob...@>=
1669@!cur_loc:integer; {current byte number in |gf_file|}
1670@!name_of_file:packed array[1..file_name_size] of char; {external file name}
1671
1672@ It turns out to be convenient to read four bytes at a time, when we are
1673inputting from \.{TFM} files. The input goes into global variables
1674|b0|, |b1|, |b2|, and |b3|, with |b0| getting the first byte and |b3|
1675the fourth.
1676
1677@<Glob...@>=
1678@!b0,@!b1,@!b2,@!b3: eight_bits; {four bytes input at once}
1679
1680@ The |read_tfm_word| procedure sets |b0| through |b3| to the next
1681four bytes in the current \.{TFM} file.
1682@^system dependencies@>
1683
1684@p procedure read_tfm_word;
1685begin read(tfm_file,b0); read(tfm_file,b1);
1686read(tfm_file,b2); read(tfm_file,b3);
1687end;
1688
1689@ We shall use another set of simple functions to read the next byte or
1690bytes from |gf_file|. There are four possibilities, each of which is
1691treated as a separate function in order to minimize the overhead for
1692subroutine calls.
1693@^system dependencies@>
1694
1695@p function get_byte:integer; {returns the next byte, unsigned}
1696var b:eight_bits;
1697begin if eof(gf_file) then get_byte:=0
1698else  begin read(gf_file,b); incr(cur_loc); get_byte:=b;
1699  end;
1700end;
1701@#
1702function get_two_bytes:integer; {returns the next two bytes, unsigned}
1703var a,@!b:eight_bits;
1704begin read(gf_file,a); read(gf_file,b);
1705cur_loc:=cur_loc+2;
1706get_two_bytes:=a*256+b;
1707end;
1708@#
1709function get_three_bytes:integer; {returns the next three bytes, unsigned}
1710var a,@!b,@!c:eight_bits;
1711begin read(gf_file,a); read(gf_file,b); read(gf_file,c);
1712cur_loc:=cur_loc+3;
1713get_three_bytes:=(a*256+b)*256+c;
1714end;
1715@#
1716function signed_quad:integer; {returns the next four bytes, signed}
1717var a,@!b,@!c,@!d:eight_bits;
1718begin read(gf_file,a); read(gf_file,b); read(gf_file,c); read(gf_file,d);
1719cur_loc:=cur_loc+4;
1720if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
1721else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
1722end;
1723
1724@* Reading the font information.
1725Now let's get down to brass tacks and consider the more substantial
1726routines that actually convert \.{TFM} data into a form suitable for
1727computation.  The routines in this part of the program have been borrowed
1728from \TeX, with slight changes, since \.{GFtoDVI} has to do some of the
1729things that \TeX\ does.
1730
1731The \.{TFM} data is stored in a large array called
1732|font_info|. Each item of |font_info| is a |memory_word|; the |fix_word|
1733data gets converted into |scaled| entries, while everything else goes into
1734words of type |four_quarters|. (These data structures are special cases of
1735the more general memory words of \TeX. On some machines it is necessary to
1736define |min_quarterword=-128| and |max_quarterword=127| in order to pack
1737four quarterwords into a single word.)
1738@^system dependencies@>
1739
1740@d min_quarterword=0 {change this to allow efficient packing, if necessary}
1741@d max_quarterword=255 {ditto}
1742@d qi(#)==#+min_quarterword
1743  {to put an |eight_bits| item into a quarterword}
1744@d qo(#)==#-min_quarterword
1745  {to take an |eight_bits| item out of a quarterword}
1746@d title_font=1
1747@d label_font=2
1748@d gray_font=3
1749@d slant_font=4
1750@d logo_font=5
1751@d non_char==qi(256)
1752@d non_address==font_mem_size
1753
1754@<Types ...@>=
1755@!font_index = 0..font_mem_size;
1756@!quarterword = min_quarterword..max_quarterword; {1/4 of a word}
1757@!four_quarters = packed record@;@/
1758  @!b0:quarterword;
1759  @!b1:quarterword;
1760  @!b2:quarterword;
1761  @!b3:quarterword;
1762  end;
1763@!memory_word = record@;@/
1764  case boolean of
1765  true: (@!sc:scaled);
1766  false: (@!qqqq:four_quarters);
1767  end;
1768@!internal_font_number=title_font..logo_font;
1769
1770@ Besides |font_info|, there are also a number of index arrays that point
1771into it, so that we can locate width and height information, etc.  For
1772example, the |char_info| data for character |c| in font |f| will be in
1773|font_info[char_base[f]+c].qqqq|; and if |w| is the |width_index| part of
1774this word (the |b0| field), the width of the character is
1775|font_info[width_base[f]+w].sc|. (These formulas assume that
1776|min_quarterword| has already been added to |w|, but not to |c|.)
1777
1778@<Glob...@>=
1779@!font_info:array[font_index] of memory_word; {the font metric data}
1780@!fmem_ptr:font_index; {first unused word of |font_info|}
1781@!font_check:array[internal_font_number] of four_quarters; {check sum}
1782@!font_size:array[internal_font_number] of scaled; {``at'' size}
1783@!font_dsize:array[internal_font_number] of scaled; {``design'' size}
1784@!font_bc:array[internal_font_number] of eight_bits;
1785  {beginning (smallest) character code}
1786@!font_ec:array[internal_font_number] of eight_bits;
1787  {ending (largest) character code}
1788@!char_base:array[internal_font_number] of integer;
1789  {base addresses for |char_info|}
1790@!width_base:array[internal_font_number] of integer;
1791  {base addresses for widths}
1792@!height_base:array[internal_font_number] of integer;
1793  {base addresses for heights}
1794@!depth_base:array[internal_font_number] of integer;
1795  {base addresses for depths}
1796@!italic_base:array[internal_font_number] of integer;
1797  {base addresses for italic corrections}
1798@!lig_kern_base:array[internal_font_number] of integer;
1799  {base addresses for ligature/kerning programs}
1800@!kern_base:array[internal_font_number] of integer;
1801  {base addresses for kerns}
1802@!exten_base:array[internal_font_number] of integer;
1803  {base addresses for extensible recipes}
1804@!param_base:array[internal_font_number] of integer;
1805  {base addresses for font parameters}
1806@!bchar_label:array[internal_font_number] of font_index;
1807  {start of |lig_kern| program for left boundary character,
1808  |non_address| if there is none}
1809@!font_bchar:array[internal_font_number] of min_quarterword..non_char;
1810  {right boundary character, |non_char| if there is none}
1811
1812@ @<Set init...@>=
1813fmem_ptr:=0;
1814
1815@ Of course we want to define macros that suppress the detail of how font
1816information is actually packed, so that we don't have to write things like
1817$$\hbox{|font_info[width_base[f]+font_info[char_base[f]+c].qqqq.b0].sc|}$$
1818too often. The \.{WEB} definitions here make |char_info(f)(c)| the
1819|four_quarters| word of font information corresponding to character
1820|c| of font |f|. If |q| is such a word, |char_width(f)(q)| will be
1821the character's width; hence the long formula above is at least
1822abbreviated to
1823$$\hbox{|char_width(f)(char_info(f)(c))|.}$$
1824In practice we will try to fetch |q| first and look at several of its
1825fields at the same time.
1826
1827The italic correction of a character will be denoted by
1828|char_italic(f)(q)|, so it is analogous to |char_width|.  But we will get
1829at the height and depth in a slightly different way, since we usually want
1830to compute both height and depth if we want either one.  The value of
1831|height_depth(q)| will be the 8-bit quantity
1832$$b=|height_index|\times16+|depth_index|,$$ and if |b| is such a byte we
1833will write |char_height(f)(b)| and |char_depth(f)(b)| for the height and
1834depth of the character |c| for which |q=char_info(f)(c)|. Got that?
1835
1836The tag field will be called |char_tag(q)|; and the remainder byte will be
1837called |rem_byte(q)|.
1838
1839@d char_info_end(#)==#].qqqq
1840@d char_info(#)==font_info[char_base[#]+char_info_end
1841@d char_width_end(#)==#.b0].sc
1842@d char_width(#)==font_info[width_base[#]+char_width_end
1843@d char_exists(#)==(#.b0>min_quarterword)
1844@d char_italic_end(#)==(qo(#.b2)) div 4].sc
1845@d char_italic(#)==font_info[italic_base[#]+char_italic_end
1846@d height_depth(#)==qo(#.b1)
1847@d char_height_end(#)==(#) div 16].sc
1848@d char_height(#)==font_info[height_base[#]+char_height_end
1849@d char_depth_end(#)==# mod 16].sc
1850@d char_depth(#)==font_info[depth_base[#]+char_depth_end
1851@d char_tag(#)==((qo(#.b2)) mod 4)
1852@d skip_byte(#)==qo(#.b0)
1853@d next_char(#)==#.b1
1854@d op_byte(#)==qo(#.b2)
1855@d rem_byte(#)==#.b3
1856
1857@ Here are some macros that help process ligatures and kerns.
1858We write |char_kern(f)(j)| to find the amount of kerning specified by
1859kerning command~|j| in font~|f|.
1860
1861@d lig_kern_start(#)==lig_kern_base[#]+rem_byte {beginning of lig/kern program}
1862@d lig_kern_restart_end(#)==256*(op_byte(#))+rem_byte(#)
1863@d lig_kern_restart(#)==lig_kern_base[#]+lig_kern_restart_end
1864@d char_kern_end(#)==256*(op_byte(#)-128)+rem_byte(#)].sc
1865@d char_kern(#)==font_info[kern_base[#]+char_kern_end
1866
1867@ Font parameters are referred to as |slant(f)|, |space(f)|, etc.
1868
1869@d param_end(#)==param_base[#]].sc
1870@d param(#)==font_info[#+param_end
1871@d slant==param(1) {slant to the right, per unit distance upward}
1872@d space==param(2) {normal space between words}
1873@d x_height==param(5) {one ex}
1874@d default_rule_thickness==param(8) {thickness of rules}
1875
1876@ Here is the subroutine that inputs the information on |tfm_file|, assuming
1877that the file has just been reset. Parameter~|f| tells which metric file is
1878being read (either |title_font| or |label_font| or |gray_font| or |slant_font|
1879or |logo_font|); parameter~|s| is the ``at'' size, which will be
1880substituted for the design size if it is positive.
1881
1882This routine does only limited checking of the validity of the file,
1883because another program (\.{TFtoPL}) is available to diagnose errors in
1884the rare case that something is amiss.
1885
1886@d bad_tfm=11 {label for |read_font_info|}
1887@d abend==goto bad_tfm {do this when the \.{TFM} data is wrong}
1888
1889@p procedure read_font_info(@!f:integer;@!s:scaled); {input a \.{TFM} file}
1890label done,bad_tfm;
1891var k:font_index; {index into |font_info|}
1892@!lf,@!lh,@!bc,@!ec,@!nw,@!nh,@!nd,@!ni,@!nl,@!nk,@!ne,@!np:0..65535;
1893  {sizes of subfiles}
1894@!bch_label:integer; {left boundary label for ligatures}
1895@!bchar:0..256; {right boundary character for ligatures}
1896@!qw:four_quarters;@!sw:scaled; {accumulators}
1897@!z:scaled; {the design size or the ``at'' size}
1898@!alpha:integer;@!beta:1..16;
1899  {auxiliary quantities used in fixed-point multiplication}
1900begin @<Read and check the font data; |abend| if the \.{TFM} file is
1901  malformed; otherwise |goto done|@>;
1902bad_tfm: print_nl('Bad TFM file for');
1903@.Bad TFM file...@>
1904case f of
1905title_font:abort('titles!');
1906label_font:abort('labels!');
1907gray_font:abort('pixels!');
1908slant_font:abort('slants!');
1909logo_font:abort('METAFONT logo!');
1910end; {there are no other cases}
1911done: {it might be good to close |tfm_file| now}
1912end;
1913
1914@ @<Read and check...@>=
1915@<Read the {\.{TFM}} size fields@>;
1916@<Use size fields to allocate font information@>;
1917@<Read the {\.{TFM}} header@>;
1918@<Read character data@>;
1919@<Read box dimensions@>;
1920@<Read ligature/kern program@>;
1921@<Read extensible character recipes@>;
1922@<Read font parameters@>;
1923@<Make final adjustments and |goto done|@>
1924
1925@ @d read_two_halves_end(#)==#:=b2*256+b3
1926@d read_two_halves(#)==read_tfm_word; #:=b0*256+b1; read_two_halves_end
1927
1928@<Read the {\.{TFM}} size fields@>=
1929begin read_two_halves(lf)(lh);
1930read_two_halves(bc)(ec);
1931if (bc>ec+1)or(ec>255) then abend;
1932if bc>255 then {|bc=256| and |ec=255|}
1933  begin bc:=1; ec:=0;
1934  end;
1935read_two_halves(nw)(nh);
1936read_two_halves(nd)(ni);
1937read_two_halves(nl)(nk);
1938read_two_halves(ne)(np);
1939if lf<>6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np then abend;
1940end
1941
1942@ The preliminary settings of the index variables |width_base|,
1943|lig_kern_base|, |kern_base|, and |exten_base| will be corrected later by
1944subtracting |min_quarterword| from them; and we will subtract 1 from
1945|param_base| too. It's best to forget about such anomalies until later.
1946
1947@<Use size fields to allocate font information@>=
1948lf:=lf-6-lh; {|lf| words should be loaded into |font_info|}
1949if np<8 then lf:=lf+8-np; {at least eight parameters will appear}
1950if fmem_ptr+lf>font_mem_size then abort('No room for TFM file!');
1951@.No room for TFM file@>
1952char_base[f]:=fmem_ptr-bc;
1953width_base[f]:=char_base[f]+ec+1;
1954height_base[f]:=width_base[f]+nw;
1955depth_base[f]:=height_base[f]+nh;
1956italic_base[f]:=depth_base[f]+nd;
1957lig_kern_base[f]:=italic_base[f]+ni;
1958kern_base[f]:=lig_kern_base[f]+nl;
1959exten_base[f]:=kern_base[f]+nk;
1960param_base[f]:=exten_base[f]+ne
1961
1962@ Only the first two words of the header are needed by \.{GFtoDVI}.
1963
1964@d store_four_quarters(#)==
1965  begin read_tfm_word;
1966  qw.b0:=qi(b0); qw.b1:=qi(b1); qw.b2:=qi(b2); qw.b3:=qi(b3);
1967  #:=qw;
1968  end
1969
1970@<Read the {\.{TFM}} header@>=
1971begin if lh<2 then abend;
1972store_four_quarters(font_check[f]);
1973read_tfm_word;
1974if b0>127 then abend; {design size must be positive}
1975z:=((b0*256+b1)*256+b2)*16+(b3 div 16);
1976if z<unity then abend;
1977while lh>2 do
1978  begin read_tfm_word; decr(lh); {ignore the rest of the header}
1979  end;
1980font_dsize[f]:=z;
1981if s>0 then z:=s;
1982font_size[f]:=z;
1983end
1984
1985@ @<Read character data@>=
1986for k:=fmem_ptr to width_base[f]-1 do
1987  begin store_four_quarters(font_info[k].qqqq);
1988  if (b0>=nw)or(b1 div @'20>=nh)or(b1 mod @'20>=nd)or
1989    (b2 div 4>=ni) then abend;
1990  case b2 mod 4 of
1991  lig_tag: if b3>=nl then abend;
1992  ext_tag: if b3>=ne then abend;
1993  no_tag,list_tag: do_nothing;
1994  end; {there are no other cases}
1995  end
1996
1997@ A |fix_word| whose four bytes are $(b0,b1,b2,b3)$ from left to right
1998represents the number
1999$$x=\left\{\vcenter{\halign{$#$,\hfil\qquad&if $#$\hfil\cr
2000b_1\cdot2^{-4}+b_2\cdot2^{-12}+b_3\cdot2^{-20}&b_0=0;\cr
2001-16+b_1\cdot2^{-4}+b_2\cdot2^{-12}+b_3\cdot2^{-20}&b_0=255.\cr}}\right.$$
2002(No other choices of |b0| are allowed, since the magnitude of a number in
2003design-size units must be less than 16.)  We want to multiply this
2004quantity by the integer~|z|, which is known to be less than $2^{27}$. Let
2005$\alpha=16z$.  If $|z|<2^{23}$, the individual multiplications $b\cdot z$,
2006$c\cdot z$, $d\cdot z$ cannot overflow; otherwise we will divide |z| by 2,
20074, 8, or 16, to obtain a multiplier less than $2^{23}$, and we can
2008compensate for this later. If |z| has thereby been replaced by
2009$|z|^\prime=|z|/2^e$, let $\beta=2^{4-e}$; we shall compute
2010$$\lfloor(b_1+b_2\cdot2^{-8}+b_3\cdot2^{-16})\,z^\prime/\beta\rfloor$$
2011if $a=0$, or the same quantity minus $\alpha$ if $a=255$.
2012
2013@d store_scaled(#)==begin read_tfm_word;
2014  sw:=(((((b3*z)div@'400)+(b2*z))div@'400)+(b1*z))div beta;
2015  if b0=0 then #:=sw@+else if b0=255 then #:=sw-alpha@+else abend;
2016  end
2017
2018@<Read box dimensions@>=
2019begin @<Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$@>;
2020for k:=width_base[f] to lig_kern_base[f]-1 do
2021  store_scaled(font_info[k].sc);
2022if font_info[width_base[f]].sc<>0 then abend; {\\{width}[0] must be zero}
2023if font_info[height_base[f]].sc<>0 then abend; {\\{height}[0] must be zero}
2024if font_info[depth_base[f]].sc<>0 then abend; {\\{depth}[0] must be zero}
2025if font_info[italic_base[f]].sc<>0 then abend; {\\{italic}[0] must be zero}
2026end
2027
2028@ @<Replace |z|...@>=
2029begin alpha:=16*z; beta:=16;
2030while z>=@'40000000 do
2031  begin z:=z div 2; beta:=beta div 2;
2032  end;
2033end
2034
2035@ @d check_byte_range(#)==begin if (#<bc)or(#>ec) then abend@+end
2036
2037@<Read ligature/kern program@>=
2038begin bch_label:=@'77777; bchar:=256;
2039if nl>0 then
2040  begin for k:=lig_kern_base[f] to kern_base[f]-1 do
2041    begin store_four_quarters(font_info[k].qqqq);
2042    if b0>stop_flag then
2043      begin if 256*b2+b3>=nl then abend;
2044      if b0=255 then if k=lig_kern_base[f] then bchar:=b1;
2045      end
2046    else begin if b1<>bchar then check_byte_range(b1);
2047      if b2<kern_flag then check_byte_range(b3)
2048      else if 256*(b2-128)+b3>=nk then abend;
2049      end;
2050    end;
2051  if b0=255 then bch_label:=256*b2+b3;
2052  end;
2053for k:=kern_base[f] to exten_base[f]-1 do
2054  store_scaled(font_info[k].sc);
2055end
2056
2057@ @<Read extensible character recipes@>=
2058for k:=exten_base[f] to param_base[f]-1 do
2059  begin store_four_quarters(font_info[k].qqqq);
2060  if b0<>0 then check_byte_range(b0);
2061  if b1<>0 then check_byte_range(b1);
2062  if b2<>0 then check_byte_range(b2);
2063  check_byte_range(b3);
2064  end
2065
2066@ @<Read font parameters@>=
2067begin for k:=1 to np do
2068  if k=1 then {the |slant| parameter is a pure number}
2069    begin read_tfm_word;
2070    if b0>127 then sw:=b0-256@+else sw:=b0;
2071    sw:=sw*@'400+b1; sw:=sw*@'400+b2;
2072    font_info[param_base[f]].sc:=(sw*@'20)+(b3 div@'20);
2073    end
2074  else store_scaled(font_info[param_base[f]+k-1].sc);
2075for k:=np+1 to 8 do font_info[param_base[f]+k-1].sc:=0;
2076end
2077
2078@ Now to wrap it up, we have checked all the necessary things about the \.{TFM}
2079file, and all we need to do is put the finishing touches on the data for
2080the new font.
2081
2082@d adjust(#)==#[f]:=qo(#[f])
2083  {correct for the excess |min_quarterword| that was added}
2084
2085@<Make final adjustments...@>=
2086font_bc[f]:=bc; font_ec[f]:=ec;
2087if bch_label<nl then bchar_label[f]:=bch_label+lig_kern_base[f]
2088else bchar_label[f]:=non_address;
2089font_bchar[f]:=qi(bchar);
2090adjust(width_base); adjust(lig_kern_base);
2091adjust(kern_base); adjust(exten_base);
2092decr(param_base[f]);
2093fmem_ptr:=fmem_ptr+lf; goto done
2094
2095@* The string pool.
2096\.{GFtoDVI} remembers strings by putting them into an array called
2097|str_pool|. The |str_start| array tells where each string starts in the pool.
2098
2099@<Types ...@>=
2100@!pool_pointer = 0..pool_size; {for variables that point into |str_pool|}
2101@!str_number = 0..max_strings; {for variables that point into |str_start|}
2102
2103@ As new strings enter, we keep track of the storage currently used, by
2104means of two global variables called |pool_ptr| and |str_ptr|. These are
2105periodically reset to their initial values when we move from one character
2106to another, because most strings are of only temporary interest.
2107
2108@<Glob...@>=
2109@!str_pool:packed array[pool_pointer] of ASCII_code; {the characters}
2110@!str_start : array[str_number] of pool_pointer; {the starting pointers}
2111@!pool_ptr : pool_pointer; {first unused position in |str_pool|}
2112@!str_ptr : str_number; {start of the current string being created}
2113@!init_str_ptr:str_number; {|str_ptr| setting when a new character starts}
2114
2115@ Several of the elementary string operations are performed using \.{WEB}
2116macros instead of using \PASCAL\ procedures, because many of the
2117operations are done quite frequently and we want to avoid the
2118overhead of procedure calls. For example, here is
2119a simple macro that computes the length of a string.
2120@.WEB@>
2121
2122@d length(#)==(str_start[#+1]-str_start[#]) {the number of characters
2123  in string number \#}
2124
2125@ Strings are created by appending character codes to |str_pool|.
2126The macro called |append_char|, defined here, does not check to see if the
2127value of |pool_ptr| has gotten too high; that test is supposed to be
2128made before |append_char| is used.
2129
2130To test if there is room to append |l| more characters to |str_pool|,
2131we shall write |str_room(l)|, which aborts \.{GFtoDVI} and gives an
2132apologetic error message if there isn't enough room.
2133
2134@d append_char(#) == {put |ASCII_code| \# at the end of |str_pool|}
2135begin str_pool[pool_ptr]:=#; incr(pool_ptr);
2136end
2137@d str_room(#) == {make sure that the pool hasn't overflowed}
2138  begin if pool_ptr+# > pool_size then
2139    abort('Too many strings!');
2140@.Too many strings@>
2141  end
2142
2143@ Once a sequence of characters has been appended to |str_pool|, it
2144officially becomes a string when the function |make_string| is called.
2145This function returns the identification number of the new string as its
2146value.
2147
2148@p function make_string : str_number; {current string enters the pool}
2149begin if str_ptr=max_strings then
2150  abort('Too many labels!');
2151@.Too many labels@>
2152incr(str_ptr); str_start[str_ptr]:=pool_ptr;
2153make_string:=str_ptr-1;
2154end;
2155
2156@ The first strings in the string pool are the keywords that \.{GFtoDVI}
2157recognizes in the \\{xxx} commands of a \.{GF} file. They are entered
2158into |str_pool| by means of a tedious bunch of assignment statements,
2159together with calls on the |first_string| subroutine.
2160
2161@d init_str0(#)==first_string(#)
2162@d init_str1(#)==buffer[1]:=#; init_str0
2163@d init_str2(#)==buffer[2]:=#; init_str1
2164@d init_str3(#)==buffer[3]:=#; init_str2
2165@d init_str4(#)==buffer[4]:=#; init_str3
2166@d init_str5(#)==buffer[5]:=#; init_str4
2167@d init_str6(#)==buffer[6]:=#; init_str5
2168@d init_str7(#)==buffer[7]:=#; init_str6
2169@d init_str8(#)==buffer[8]:=#; init_str7
2170@d init_str9(#)==buffer[9]:=#; init_str8
2171@d init_str10(#)==buffer[10]:=#; init_str9
2172@d init_str11(#)==buffer[11]:=#; init_str10
2173@d init_str12(#)==buffer[12]:=#; init_str11
2174@d init_str13(#)==buffer[13]:=#; init_str12
2175@d longest_keyword=13
2176
2177@p procedure first_string(@!c:integer);
2178begin if str_ptr<>c then abort('?'); {internal consistency check}
2179@.?@>
2180while l>0 do
2181  begin append_char(buffer[l]); decr(l);
2182  end;
2183incr(str_ptr); str_start[str_ptr]:=pool_ptr;
2184end;
2185
2186@ @<Glob...@>=
2187@!l:integer; {length of string being made by |first_string|}
2188
2189@ Here are the tedious assignments just promised.
2190String number 0 is the empty string.
2191
2192@d null_string=0 {the empty keyword}
2193@d area_code=4 {add to font code for the `\.{area}' keywords}
2194@d at_code=8 {add to font code for the `\.{at}' keywords}
2195@d rule_code=13 {code for the keyword `\.{rule}'}
2196@d title_code=14 {code for the keyword `\.{title}'}
2197@d rule_thickness_code=15 {code for the keyword `\.{rulethickness}'}
2198@d offset_code=16 {code for the keyword `\.{offset}'}
2199@d x_offset_code=17 {code for the keyword `\.{xoffset}'}
2200@d y_offset_code=18 {code for the keyword `\.{yoffset}'}
2201@d max_keyword=18 {largest keyword code number}
2202
2203@<Initialize the strings@>=
2204str_ptr:=0; pool_ptr:=0; str_start[0]:=0;@/
2205l:=0; init_str0(null_string);@/
2206l:=9; init_str9("t")("i")("t")("l")("e")("f")("o")("n")("t")(title_font);@/
2207l:=9; init_str9("l")("a")("b")("e")("l")("f")("o")("n")("t")(label_font);@/
2208l:=8; init_str8("g")("r")("a")("y")("f")("o")("n")("t")(gray_font);@/
2209l:=9; init_str9("s")("l")("a")("n")("t")("f")("o")("n")("t")(slant_font);@/
2210l:=13; init_str13("t")("i")("t")("l")("e")
2211  ("f")("o")("n")("t")("a")("r")("e")("a")(title_font+area_code);@/
2212l:=13; init_str13("l")("a")("b")("e")("l")
2213  ("f")("o")("n")("t")("a")("r")("e")("a")(label_font+area_code);@/
2214l:=12; init_str12("g")("r")("a")("y")
2215  ("f")("o")("n")("t")("a")("r")("e")("a")(gray_font+area_code);@/
2216l:=13; init_str13("s")("l")("a")("n")("t")
2217  ("f")("o")("n")("t")("a")("r")("e")("a")(slant_font+area_code);@/
2218l:=11; init_str11("t")("i")("t")("l")("e")
2219  ("f")("o")("n")("t")("a")("t")(title_font+at_code);@/
2220l:=11; init_str11("l")("a")("b")("e")("l")
2221  ("f")("o")("n")("t")("a")("t")(label_font+at_code);@/
2222l:=10; init_str10("g")("r")("a")("y")
2223  ("f")("o")("n")("t")("a")("t")(gray_font+at_code);@/
2224l:=11; init_str11("s")("l")("a")("n")("t")
2225  ("f")("o")("n")("t")("a")("t")(slant_font+at_code);@/
2226l:=4; init_str4("r")("u")("l")("e")(rule_code);@/
2227l:=5; init_str5("t")("i")("t")("l")("e")(title_code);@/
2228l:=13; init_str13("r")("u")("l")("e")
2229  ("t")("h")("i")("c")("k")("n")("e")("s")("s")(rule_thickness_code);@/
2230l:=6; init_str6("o")("f")("f")("s")("e")("t")(offset_code);@/
2231l:=7; init_str7("x")("o")("f")("f")("s")("e")("t")(x_offset_code);@/
2232l:=7; init_str7("y")("o")("f")("f")("s")("e")("t")(y_offset_code);@/
2233
2234@ We will also find it useful to have the following strings. (The names of
2235default fonts will presumably be different at different sites.)
2236@^system dependencies@>
2237@^default fonts@>
2238
2239@d gf_ext=max_keyword+1 {string number for `\.{.gf}'}
2240@d dvi_ext=max_keyword+2 {string number for `\.{.dvi}'}
2241@d tfm_ext=max_keyword+3 {string number for `\.{.tfm}'}
2242@d page_header=max_keyword+4 {string number for `\.{\ \ Page\ }'}
2243@d char_header=max_keyword+5 {string number for `\.{\ \ Character\ }'}
2244@d ext_header=max_keyword+6 {string number for `\.{\ \ Ext\ }'}
2245@d left_quotes=max_keyword+7 {string number for `\.{\ \ ``}'}
2246@d right_quotes=max_keyword+8 {string number for `\.{''}'}
2247@d equals_sign=max_keyword+9 {string number for `\.{ = }'}
2248@d plus_sign=max_keyword+10 {string number for `\.{ + (}'}
2249@d default_title_font=max_keyword+11
2250  {string number for the default |title_font|}
2251@d default_label_font=max_keyword+12
2252  {string number for the default |label_font|}
2253@d default_gray_font=max_keyword+13 {string number for the default |gray_font|}
2254@d logo_font_name=max_keyword+14 {string number for the font with \MF\ logo}
2255@d small_logo=max_keyword+15 {string number for `\.{METAFONT}'}
2256@d home_font_area=max_keyword+16 {string number for system-dependent font area}
2257
2258@<Initialize the strings@>=
2259l:=3; init_str3(".")("g")("f")(gf_ext);@/
2260l:=4; init_str4(".")("d")("v")("i")(dvi_ext);@/
2261l:=4; init_str4(".")("t")("f")("m")(tfm_ext);@/
2262l:=7; init_str7(" ")(" ")("P")("a")("g")("e")(" ")(page_header);@/
2263l:=12; init_str12(" ")(" ")("C")("h")("a")("r")("a")("c")("t")("e")("r")(" ")
2264  (char_header);@/
2265l:=6; init_str6(" ")(" ")("E")("x")("t")(" ")(ext_header);@/
2266l:=4; init_str4(" ")(" ")("`")("`")(left_quotes);@/
2267l:=2; init_str2("'")("'")(right_quotes);@/
2268l:=3; init_str3(" ")("=")(" ")(equals_sign);@/
2269l:=4; init_str4(" ")("+")(" ")("(")(plus_sign);@/
2270l:=4; init_str4("c")("m")("r")("8")(default_title_font);@/
2271l:=6; init_str6("c")("m")("t")("t")("1")("0")(default_label_font);@/
2272l:=4; init_str4("g")("r")("a")("y")(default_gray_font);@/
2273l:=5; init_str5("l")("o")("g")("o")("8")(logo_font_name);@/
2274l:=8; init_str8("M")("E")("T")("A")("F")("O")("N")("T")(small_logo);
2275
2276@ If an \\{xxx} command has just been encountered in the \.{GF} file,
2277the following procedure interprets its keyword. More precisely, we assume
2278that |cur_gf| contains an op-code byte just read from the \.{GF} file,
2279where |xxx1<=cur_gf<=no_op|. The |interpret_xxx| procedure will read the
2280rest of the command, in the following way:
2281\smallskip
2282\item{1)} If |cur_gf| is |no_op| or |yyy|, or if it's an \\{xxx} command with
2283an unknown keyword, the bytes are simply read and ignored, and the
2284value |no_operation| is returned.
2285
2286\item{2)} If |cur_gf| is an \\{xxx} command (either |xxx1| or $\cdots$
2287or |xxx4|), and if the associated string matches a keyword exactly,
2288the string number of that keyword is returned (e.g., |rule_thickness_code|).
2289
2290\item{3)} If |cur_gf| is an \\{xxx} command whose string begins with
2291keyword and space, the string number of that keyword is returned, and
2292the remainder of the string is put into the string pool (where it will be
2293string number |cur_string|. Exception: If the keyword is |null_string|,
2294the character immediately following the blank space is put into the
2295global variable |label_type|, and the remaining characters go into the
2296string pool.
2297
2298\smallskip\noindent
2299In all cases, |cur_gf| will then be reset to the op-code byte that
2300immediately follows the original command.
2301
2302@d no_operation=max_keyword+1
2303
2304@<Types ...@>=
2305@!keyword_code=null_string..no_operation;
2306
2307@ @<Glob...@>=
2308@!cur_gf:eight_bits; {the byte most recently read from |gf_file|}
2309@!cur_string:str_number; {the string following a keyword and space}
2310@!label_type:eight_bits; {the character following a null keyword and space}
2311
2312@ We will be using this procedure when reading the \.{GF} file just
2313after the preamble and just after |eoc| commands.
2314
2315@p function interpret_xxx:keyword_code;
2316label done,done1,not_found;
2317var @!k:integer; {number of bytes in an \\{xxx} command}
2318@!j:integer; {number of bytes read so far}
2319@!l:0..longest_keyword; {length of keyword to check}
2320@!m:keyword_code; {runs through the list of known keywords}
2321@!n1:0..longest_keyword; {buffered character being checked}
2322@!n2:pool_pointer; {pool character being checked}
2323@!c:keyword_code; {the result to return}
2324begin c:=no_operation; cur_string:=null_string;
2325case cur_gf of
2326no_op:goto done;
2327yyy:begin k:=signed_quad; goto done;
2328  end;
2329xxx1:k:=get_byte;
2330xxx2:k:=get_two_bytes;
2331xxx3:k:=get_three_bytes;
2332xxx4:k:=signed_quad;
2333end; {there are no other cases}
2334@<Read the next |k| characters of the \.{GF} file;
2335  change |c| and |goto done| if a keyword is recognized@>;
2336done: cur_gf:=get_byte; interpret_xxx:=c;
2337end;
2338
2339@ @<Read the next |k|...@>=
2340j:=0;@+if k<2 then goto not_found;
2341loop@+  begin l:=j;
2342  if j=k then goto done1;
2343  if j=longest_keyword then goto not_found;
2344  incr(j); buffer[j]:=get_byte;
2345  if buffer[j]=" " then goto done1;
2346  end;
2347done1:@<If the keyword in |buffer[1..l]| is known, change |c| and |goto done|@>;
2348not_found: while j<k do
2349  begin incr(j); cur_gf:=get_byte;
2350  end
2351
2352@ @<If the keyword...@>=
2353for m:=null_string to max_keyword do if length(m)=l then
2354  begin n1:=0; n2:=str_start[m];
2355  while (n1<l)and(buffer[n1+1]=str_pool[n2]) do
2356    begin incr(n1); incr(n2);
2357    end;
2358  if n1=l then
2359    begin c:=m;
2360    if m=null_string then
2361      begin incr(j); label_type:=get_byte;
2362      end;
2363    str_room(k-j);
2364    while j<k do
2365      begin incr(j); append_char(get_byte);
2366      end;
2367    cur_string:=make_string; goto done;
2368    end;
2369  end
2370
2371@ When an \\{xxx} command takes a numeric argument, |get_yyy| reads
2372that argument and puts the following byte into |cur_gf|.
2373
2374@p function get_yyy:scaled;
2375var @!v:scaled; {value just read}
2376begin if cur_gf<>yyy then get_yyy:=0
2377else  begin v:=signed_quad; cur_gf:=get_byte; get_yyy:=v;
2378  end;
2379end;
2380
2381@ A simpler method is used for special commands between |boc| and |eoc|,
2382since \.{GFtoDVI} doesn't even look at them.
2383
2384@p procedure skip_nop;
2385label done;
2386var @!k:integer; {number of bytes in an \\{xxx} command}
2387@!j:integer; {number of bytes read so far}
2388begin case cur_gf of
2389no_op:goto done;
2390yyy:begin k:=signed_quad; goto done;
2391  end;
2392xxx1:k:=get_byte;
2393xxx2:k:=get_two_bytes;
2394xxx3:k:=get_three_bytes;
2395xxx4:k:=signed_quad;
2396end; {there are no other cases}
2397for j:=1 to k do cur_gf:=get_byte;
2398done: cur_gf:=get_byte;
2399end;
2400
2401@* File names.
2402It's time now to fret about file names. \.{GFtoDVI} uses the conventions of
2403\TeX\ and \MF\ to convert file names into strings that can be used to open
2404files. Three routines called |begin_name|, |more_name|, and |end_name| are
2405involved, so that the system-dependent parts of file naming conventions are
2406isolated from the system-independent ways in which file names are used.
2407(See the \TeX\ or \MF\ program listing for further explanation.)
2408@^system dependencies@>
2409
2410@<Glob...@>=
2411@!cur_name:str_number; {name of file just scanned}
2412@!cur_area:str_number; {file area just scanned, or |null_string|}
2413@!cur_ext:str_number; {file extension just scanned, or |null_string|}
2414
2415@ The file names we shall deal with for illustrative purposes have the
2416following structure:  If the name contains `\.>' or `\.:', the file area
2417consists of all characters up to and including the final such character;
2418otherwise the file area is null.  If the remaining file name contains
2419`\..', the file extension consists of all such characters from the first
2420remaining `\..' to the end, otherwise the file extension is null.
2421@^system dependencies@>
2422
2423We can scan such file names easily by using two global variables that keep track
2424of the occurrences of area and extension delimiters:
2425
2426@<Glob...@>=
2427@!area_delimiter:pool_pointer; {the most recent `\.>' or `\.:', if any}
2428@!ext_delimiter:pool_pointer; {the relevant `\..', if any}
2429
2430@ Font metric files whose areas are not given
2431explicitly are assumed to appear in a standard system area called
2432|home_font_area|.  This system area name will, of course, vary from place
2433to place. The program here sets it to `\.{TeXfonts:}'.
2434@^system dependencies@>
2435@.TeXfonts@>
2436
2437@<Initialize the strings@>=
2438l:=9; init_str9("T")("e")("X")("f")("o")("n")("t")("s")(":")(home_font_area);@/
2439
2440@ Here now is the first of the system-dependent routines for file name scanning.
2441@^system dependencies@>
2442
2443@p procedure begin_name;
2444begin area_delimiter:=0; ext_delimiter:=0;
2445end;
2446
2447@ And here's the second.
2448@^system dependencies@>
2449
2450@p function more_name(@!c:ASCII_code):boolean;
2451begin if c=" " then more_name:=false
2452else  begin if (c=">")or(c=":") then
2453    begin area_delimiter:=pool_ptr; ext_delimiter:=0;
2454    end
2455  else if (c=".")and(ext_delimiter=0) then ext_delimiter:=pool_ptr;
2456  str_room(1); append_char(c); {contribute |c| to the current string}
2457  more_name:=true;
2458  end;
2459end;
2460
2461@ The third.
2462@^system dependencies@>
2463
2464@p procedure end_name;
2465begin if str_ptr+3>max_strings then
2466  abort('Too many strings!');
2467@.Too many strings@>
2468if area_delimiter=0 then cur_area:=null_string
2469else  begin cur_area:=str_ptr; incr(str_ptr);
2470  str_start[str_ptr]:=area_delimiter+1;
2471  end;
2472if ext_delimiter=0 then
2473  begin cur_ext:=null_string; cur_name:=make_string;
2474  end
2475else  begin cur_name:=str_ptr; incr(str_ptr);
2476  str_start[str_ptr]:=ext_delimiter; cur_ext:=make_string;
2477  end;
2478end;
2479
2480@ Another system-dependent routine is needed to convert three strings
2481into the |name_of_file| value that is used to open files. The present code
2482allows both lowercase and uppercase letters in the file name.
2483@^system dependencies@>
2484
2485@d append_to_name(#)==begin c:=#; incr(k);
2486  if k<=file_name_size then name_of_file[k]:=xchr[c];
2487  end
2488
2489@p procedure pack_file_name(@!n,@!a,@!e:str_number);
2490var k:integer; {number of positions filled in |name_of_file|}
2491@!c: ASCII_code; {character being packed}
2492@!j:integer; {index into |str_pool|}
2493@!name_length:0..file_name_size; {number of characters packed}
2494begin k:=0;
2495for j:=str_start[a] to str_start[a+1]-1 do append_to_name(str_pool[j]);
2496for j:=str_start[n] to str_start[n+1]-1 do append_to_name(str_pool[j]);
2497for j:=str_start[e] to str_start[e+1]-1 do append_to_name(str_pool[j]);
2498if k<=file_name_size then name_length:=k@+else name_length:=file_name_size;
2499for k:=name_length+1 to file_name_size do name_of_file[k]:=' ';
2500end;
2501
2502@ Now let's consider the routines by which \.{GFtoDVI} deals with file names
2503in a system-independent manner.
2504The global variable |job_name| contains the \.{GF} file name that is
2505being input. This name is extended by `\.{dvi}'
2506in order to make the name of the output file.
2507
2508@<Glob...@>=
2509@!job_name:str_number; {principal file name}
2510
2511@ The |start_gf| procedure prompts the user for the name of the generic
2512font file to be input. It opens the file, making sure that some input is
2513present; then it opens the output file.
2514
2515Although this routine is system-independent, it should probably be
2516modified to take the file name from the command line (without an initial
2517prompt), on systems that permit such things.
2518
2519@p procedure start_gf;
2520label found,done;
2521begin loop@+begin print_nl('GF file name: '); input_ln;
2522@.GF file name@>
2523  buf_ptr:=0; buffer[line_length]:="?";
2524  while buffer[buf_ptr]=" " do incr(buf_ptr);
2525  if buf_ptr<line_length then
2526    begin @<Scan the file name in the buffer@>;
2527    if cur_ext=null_string then cur_ext:=gf_ext;
2528    pack_file_name(cur_name,cur_area,cur_ext); open_gf_file;
2529    if not eof(gf_file) then goto found;
2530    print_nl('Oops... I can''t find file '); print(name_of_file);
2531@.Oops...@>
2532@.I can't find...@>
2533    end;
2534  end;
2535found:job_name:=cur_name; pack_file_name(job_name,null_string,dvi_ext);
2536open_dvi_file;
2537end;
2538
2539@ @<Scan the file name in the buffer@>=
2540if buffer[line_length-1]="/" then
2541  begin interaction:=true; decr(line_length);
2542  end;
2543begin_name;
2544loop@+  begin if buf_ptr=line_length then goto done;
2545  if not more_name(buffer[buf_ptr]) then goto done;
2546  incr(buf_ptr);
2547  end;
2548done:end_name
2549
2550@ Special instructions found near the beginning of the \.{GF} file might
2551change the names, areas, and ``at'' sizes of the fonts that \.{GFtoDVI}
2552will be using. But when we reach the first |boc| instruction, we input
2553all of the \.{TFM} files. The global variable |interaction| is set |true|
2554if a |"/"| was removed at the end of the file name; this means that the
2555user will have a chance to issue special instructions online just before
2556the fonts are loaded.
2557
2558@d check_fonts==@+if fonts_not_loaded then load_fonts
2559
2560@<Glob...@>=
2561@!interaction:boolean; {is the user allowed to type specials online?}
2562@!fonts_not_loaded:boolean; {have the \.{TFM} files still not been input?}
2563@!font_name:array[internal_font_number] of str_number; {current font names}
2564@!font_area:array[internal_font_number] of str_number; {current font areas}
2565@!font_at:array[internal_font_number] of scaled; {current font ``at'' sizes}
2566
2567@ @<Set init...@>=
2568interaction:=false; fonts_not_loaded:=true;
2569font_name[title_font]:=default_title_font;
2570font_name[label_font]:=default_label_font;
2571font_name[gray_font]:=default_gray_font;
2572font_name[slant_font]:=null_string;
2573font_name[logo_font]:=logo_font_name;
2574for k:=title_font to logo_font do
2575  begin font_area[k]:=null_string; font_at[k]:=0;
2576  end;
2577
2578@ After the following procedure has been performed, there will be no
2579turning back; the fonts will have been firmly established in
2580\.{GFtoDVI}'s memory.
2581
2582@<Declare the procedure called |load_fonts|@>=
2583procedure load_fonts;
2584label done,continue,found,not_found;
2585var @!f:internal_font_number;
2586@!i:four_quarters; {font information word}
2587@!j,@!k,@!v:integer; {registers for initializing font tables}
2588@!m:title_font..slant_font+area_code; {keyword found}
2589@!n1:0..longest_keyword; {buffered character being checked}
2590@!n2:pool_pointer; {pool character being checked}
2591begin if interaction then @<Get online special input@>;
2592fonts_not_loaded:=false;
2593for f:=title_font to logo_font do
2594 if (f<>slant_font)or(length(font_name[f])>0) then
2595  begin if length(font_area[f])=0 then font_area[f]:=home_font_area;
2596  pack_file_name(font_name[f],font_area[f],tfm_ext);
2597  open_tfm_file; read_font_info(f,font_at[f]);
2598  if font_area[f]=home_font_area then font_area[f]:=null_string;
2599  dvi_font_def(f); {put the font name in the \.{DVI} file}
2600  end;
2601@<Initialize global variables that depend on the font data@>;
2602end;
2603
2604@ @<Get online special input@>=
2605loop@+  begin not_found: print_nl('Special font substitution: ');
2606@.Special font subst...@>
2607  continue: input_ln;
2608  if line_length=0 then goto done;
2609  @<Search buffer for valid keyword; if successful, |goto found|@>;
2610  print('Please say, e.g., "grayfont foo" or "slantfontarea baz".');
2611  goto not_found;
2612  found: @<Update the font name or area@>;
2613  print('OK; any more? '); goto continue;
2614  end;
2615done:
2616
2617@ @<Search buffer for valid keyword; if successful, |goto found|@>=
2618buf_ptr:=0; buffer[line_length]:=" ";
2619while buffer[buf_ptr]<>" " do incr(buf_ptr);
2620for m:=title_font to slant_font+area_code do if length(m)=buf_ptr then
2621  begin n1:=0; n2:=str_start[m];
2622  while (n1<buf_ptr)and(buffer[n1]=str_pool[n2]) do
2623    begin incr(n1); incr(n2);
2624    end;
2625  if n1=buf_ptr then goto found;
2626  end
2627
2628@ @<Update the font name or area@>=
2629incr(buf_ptr); str_room(line_length-buf_ptr);
2630while buf_ptr<line_length do
2631  begin append_char(buffer[buf_ptr]); incr(buf_ptr);
2632  end;
2633if m>area_code then font_area[m-area_code]:=make_string
2634else  begin font_name[m]:=make_string; font_area[m]:=null_string;
2635  font_at[m]:=0;
2636  end;
2637init_str_ptr:=str_ptr
2638
2639@* Shipping pages out.
2640The following routines are used to write the \.{DVI} file. They have
2641been copied from \TeX, but simplified; we don't have to handle
2642nearly as much generality as \TeX\ does.
2643
2644Statistics about the entire set of pages that will be shipped out must be
2645reported in the \.{DVI} postamble. The global variables |total_pages|,
2646|max_v|, |max_h|, and |last_bop| are used to record this information.
2647
2648@<Glob...@>=
2649@!total_pages:integer; {the number of pages that have been shipped out}
2650@!max_v:scaled; {maximum height-plus-depth of pages shipped so far}
2651@!max_h:scaled; {maximum width of pages shipped so far}
2652@!last_bop:integer; {location of previous |bop| in the \.{DVI} output}
2653
2654@ @<Set init...@>=
2655total_pages:=0; max_v:=0; max_h:=0; last_bop:=-1;
2656
2657@ The \.{DVI} bytes are output to a buffer instead of being written directly
2658to the output file. This makes it possible to reduce the overhead of
2659subroutine calls.
2660
2661The output buffer is divided into two parts of equal size; the bytes found
2662in |dvi_buf[0..half_buf-1]| constitute the first half, and those in
2663|dvi_buf[half_buf..dvi_buf_size-1]| constitute the second. The global
2664variable |dvi_ptr| points to the position that will receive the next
2665output byte. When |dvi_ptr| reaches |dvi_limit|, which is always equal
2666to one of the two values |half_buf| or |dvi_buf_size|, the half buffer that
2667is about to be invaded next is sent to the output and |dvi_limit| is
2668changed to its other value. Thus, there is always at least a half buffer's
2669worth of information present, except at the very beginning of the job.
2670
2671Bytes of the \.{DVI} file are numbered sequentially starting with 0;
2672the next byte to be generated will be number |dvi_offset+dvi_ptr|.
2673
2674@<Types ...@>=
2675@!dvi_index=0..dvi_buf_size; {an index into the output buffer}
2676
2677@ Some systems may find it more efficient to make |dvi_buf| a |packed|
2678array, since output of four bytes at once may be facilitated.
2679@^system dependencies@>
2680
2681@<Glob...@>=
2682@!dvi_buf:array[dvi_index] of eight_bits; {buffer for \.{DVI} output}
2683@!half_buf:dvi_index; {half of |dvi_buf_size|}
2684@!dvi_limit:dvi_index; {end of the current half buffer}
2685@!dvi_ptr:dvi_index; {the next available buffer address}
2686@!dvi_offset:integer; {|dvi_buf_size| times the number of times the
2687  output buffer has been fully emptied}
2688
2689@ Initially the buffer is all in one piece; we will output half of it only
2690after it first fills up.
2691
2692@<Set init...@>=
2693half_buf:=dvi_buf_size div 2; dvi_limit:=dvi_buf_size; dvi_ptr:=0;
2694dvi_offset:=0;
2695
2696@ The actual output of |dvi_buf[a..b]| to |dvi_file| is performed by calling
2697|write_dvi(a,b)|. It is safe to assume that |a| and |b+1| will both be
2698multiples of 4 when |write_dvi(a,b)| is called; therefore it is possible on
2699many machines to use efficient methods to pack four bytes per word and to
2700output an array of words with one system call.
2701@^system dependencies@>
2702
2703@p procedure write_dvi(@!a,@!b:dvi_index);
2704var k:dvi_index;
2705begin for k:=a to b do write(dvi_file,dvi_buf[k]);
2706end;
2707
2708@ To put a byte in the buffer without paying the cost of invoking a procedure
2709each time, we use the macro |dvi_out|.
2710
2711@d dvi_out(#)==@+begin dvi_buf[dvi_ptr]:=#; incr(dvi_ptr);
2712  if dvi_ptr=dvi_limit then dvi_swap;
2713  end
2714
2715@p procedure dvi_swap; {outputs half of the buffer}
2716begin if dvi_limit=dvi_buf_size then
2717  begin write_dvi(0,half_buf-1); dvi_limit:=half_buf;
2718  dvi_offset:=dvi_offset+dvi_buf_size; dvi_ptr:=0;
2719  end
2720else  begin write_dvi(half_buf,dvi_buf_size-1); dvi_limit:=dvi_buf_size;
2721  end;
2722end;
2723
2724@ Here is how we clean out the buffer when \TeX\ is all through; |dvi_ptr|
2725will be a multiple of~4.
2726
2727@<Empty the last bytes out of |dvi_buf|@>=
2728if dvi_limit=half_buf then write_dvi(half_buf,dvi_buf_size-1);
2729if dvi_ptr>0 then write_dvi(0,dvi_ptr-1)
2730
2731@ The |dvi_four| procedure outputs four bytes in two's complement notation,
2732without risking arithmetic overflow.
2733
2734@p procedure dvi_four(@!x:integer);
2735begin if x>=0 then dvi_out(x div @'100000000)
2736else  begin x:=x+@'10000000000;
2737  x:=x+@'10000000000;
2738  dvi_out((x div @'100000000) + 128);
2739  end;
2740x:=x mod @'100000000; dvi_out(x div @'200000);
2741x:=x mod @'200000; dvi_out(x div @'400);
2742dvi_out(x mod @'400);
2743end;
2744
2745@ Here's a procedure that outputs a font definition.
2746
2747@d select_font(#)==dvi_out(fnt_num_0+#) {set current font to \#}
2748
2749@p procedure dvi_font_def(@!f:internal_font_number);
2750var k:integer; {index into |str_pool|}
2751begin dvi_out(fnt_def1);
2752dvi_out(f);@/
2753dvi_out(qo(font_check[f].b0));
2754dvi_out(qo(font_check[f].b1));
2755dvi_out(qo(font_check[f].b2));
2756dvi_out(qo(font_check[f].b3));@/
2757dvi_four(font_size[f]);
2758dvi_four(font_dsize[f]);@/
2759dvi_out(length(font_area[f]));
2760dvi_out(length(font_name[f]));
2761@<Output the font name whose internal number is |f|@>;
2762end;@/
2763@t\4@>@<Declare the procedure called |load_fonts|@>@;
2764
2765@ @<Output the font name whose internal number is |f|@>=
2766for k:=str_start[font_area[f]] to str_start[font_area[f]+1]-1 do
2767  dvi_out(str_pool[k]);
2768for k:=str_start[font_name[f]] to str_start[font_name[f]+1]-1 do
2769  dvi_out(str_pool[k])
2770
2771@ The |typeset| subroutine typesets any eight-bit character.
2772
2773@p procedure typeset(@!c:eight_bits);
2774begin if c>=128 then dvi_out(set1);
2775dvi_out(c);
2776end;
2777
2778@ The |dvi_scaled| subroutine takes a |real| value |x| and outputs
2779a decimal approximation to |x/unity|, correct to one decimal place.
2780
2781@p procedure dvi_scaled(@!x:real);
2782var @!n:integer; {an integer approximation to |10*x/unity|}
2783@!m:integer; {the integer part of the answer}
2784@!k:integer; {the number of digits in |m|}
2785begin n:=round(x/6553.6);
2786if n<0 then
2787  begin dvi_out("-"); n:=-n;
2788  end;
2789m:=n div 10; k:=0;
2790repeat incr(k); buffer[k]:=(m mod 10)+"0"; m:=m div 10;
2791until m=0;
2792repeat dvi_out(buffer[k]); decr(k);
2793until k=0;
2794if n mod 10 <> 0 then
2795  begin dvi_out("."); dvi_out((n mod 10)+"0");
2796  end;
2797end;
2798
2799@ At the end of the program, we must finish things off by writing the
2800post\-amble. An integer variable~|k| will be declared for use by this routine.
2801
2802@<Finish the \.{DVI} file and |goto final_end|@>=
2803begin dvi_out(post); {beginning of the postamble}
2804dvi_four(last_bop); last_bop:=dvi_offset+dvi_ptr-5; {|post| location}
2805dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp}
2806dvi_four(1000); {magnification factor}
2807dvi_four(max_v); dvi_four(max_h);@/
2808dvi_out(0); dvi_out(3); {`\\{max\_push}' is said to be 3}@/
2809dvi_out(total_pages div 256); dvi_out(total_pages mod 256);@/
2810if not fonts_not_loaded then
2811  for k:=title_font to logo_font do
2812    if length(font_name[k])>0 then dvi_font_def(k);
2813dvi_out(post_post); dvi_four(last_bop); dvi_out(dvi_id_byte);@/
2814k:=4+((dvi_buf_size-dvi_ptr) mod 4); {the number of 223's}
2815while k>0 do
2816  begin dvi_out(223); decr(k);
2817  end;
2818@<Empty the last bytes out of |dvi_buf|@>;
2819goto final_end;
2820end
2821
2822@* Rudimentary typesetting.
2823One of \.{GFtoDVI}'s little duties is to be a mini-\TeX: It must be able
2824to typeset the equivalent of `\.{\\hbox\{}$\langle$string$\rangle$\.\}' for
2825a given string of ASCII characters, using either the title font or the
2826label font.
2827
2828The |hbox| procedure does this. The width, height, and depth of the
2829box defined by string~|s| in font~|f| are computed in global variables
2830|box_width|, |box_height|, and |box_depth|.
2831
2832The task would be trivial if it weren't for ligatures and kerns, which
2833are implemented here in full generality. (Infinite looping is possible
2834if the \.{TFM} file is malformed; \.{TFtoPL} will diagnose such problems.)
2835
2836We assume that |" "| is a space character; character code @'40 will not
2837be typeset unless it is accessed via a ligature.
2838
2839If parameter |send_it| is |false|, we merely want to know the box dimensions.
2840Otherwise typesetting commands are also sent to
2841the \.{DVI} file; we assume in this case that font |f| has already been
2842selected in the \.{DVI} file as the current font.
2843
2844@d set_cur_r==if k<end_k then cur_r:=qi(str_pool[k])
2845    else cur_r:=bchar
2846
2847@p procedure hbox(@!s:str_number;@!f:internal_font_number;@!send_it:boolean);
2848label continue, done;
2849var @!k,@!end_k,@!max_k:pool_pointer; {indices into |str_pool|}
2850@!i,@!j:four_quarters; {font information words}
2851@!cur_l:0..256; {character to the left of the ``cursor''}
2852@!cur_r:min_quarterword..non_char; {character to the right of the ``cursor''}
2853@!bchar:min_quarterword..non_char; {right boundary character}
2854@!stack_ptr:0..lig_lookahead; {number of entries on |lig_stack|}
2855@!l:font_index; {pointer to lig/kern instruction}
2856@!kern_amount:scaled; {extra space to be typeset}
2857@!hd:eight_bits; {height and depth indices for a character}
2858@!x:scaled; {temporary register}
2859@!save_c:ASCII_code; {character temporarily blanked out}
2860begin box_width:=0; box_height:=0; box_depth:=0;@/
2861k:=str_start[s]; max_k:=str_start[s+1];
2862save_c:=str_pool[max_k]; str_pool[max_k]:=" ";
2863while k<max_k do
2864  begin if str_pool[k]=" " then @<Typeset a space in font |f| and advance~|k|@>
2865  else begin end_k:=k;
2866    repeat incr(end_k); until str_pool[end_k]=" ";
2867    kern_amount:=0; cur_l:=256; stack_ptr:=0; bchar:=font_bchar[f];
2868    set_cur_r; suppress_lig:=false;
2869continue: @<If there's a ligature or kern at the cursor position,
2870     update the cursor data structures, possibly advancing~|k|; continue
2871     until the cursor wants to move right@>;
2872    @<Typeset character |cur_l|, if it exists in the font;
2873     also append an optional kern@>;
2874    @<Move the cursor to the right and |goto continue|, if there's
2875     more work to do in the current word@>;
2876    end; {now |k=end_k|}
2877  end;
2878str_pool[max_k]:=save_c;
2879end;
2880
2881@ @<Glob...@>=
2882@!box_width:scaled; {width of box constructed by |hbox|}
2883@!box_height:scaled; {height of box constructed by |hbox|}
2884@!box_depth:scaled; {depth of box constructed by |hbox|}
2885@!lig_stack:array[1..lig_lookahead] of quarterword; {inserted ligature chars}
2886@!dummy_info:four_quarters; {fake |char_info| for nonexistent character}
2887@!suppress_lig:boolean; {should we bypass checking for ligatures next time?}
2888
2889@ @<Set init...@>=
2890dummy_info.b0:=qi(0); dummy_info.b1:=qi(0); dummy_info.b2:=qi(0);
2891dummy_info.b3:=qi(0);
2892
2893@ @<Typeset a space...@>=
2894begin box_width:=box_width+space(f);
2895if send_it then
2896  begin dvi_out(right4); dvi_four(space(f));
2897  end;
2898incr(k);
2899end
2900
2901@ @<If there's a ligature...@>=
2902if(cur_l<font_bc[f])or(cur_l>font_ec[f]) then
2903  begin i:=dummy_info;
2904  if cur_l=256 then l:=bchar_label[f]@+else l:=non_address;
2905  end
2906else begin i:=char_info(f)(cur_l);
2907  if char_tag(i)<>lig_tag then l:=non_address
2908  else begin l:=lig_kern_start(f)(i); j:=font_info[l].qqqq;
2909    if skip_byte(j)>stop_flag then l:=lig_kern_restart(f)(j);
2910    end;
2911  end;
2912if suppress_lig then suppress_lig:=false
2913else while l<qi(kern_base[f]) do
2914  begin j:=font_info[l].qqqq;
2915  if next_char(j)=cur_r then if skip_byte(j)<=stop_flag then
2916    if op_byte(j)>=kern_flag then
2917      begin kern_amount:=char_kern(f)(j); goto done;
2918      end
2919    else @<Carry out a ligature operation, updating the cursor structure
2920      and possibly advancing~|k|; |goto continue| if the cursor doesn't
2921      advance, otherwise |goto done|@>;
2922  if skip_byte(j)>=stop_flag then goto done;
2923  l:=l+skip_byte(j)+1;
2924  end;
2925done:
2926
2927@ At this point |i| contains |char_info| for |cur_l|.
2928
2929@<Typeset character...@>=
2930if char_exists(i) then
2931  begin box_width:=box_width+char_width(f)(i)+kern_amount;@/
2932  hd:=height_depth(i);
2933  x:=char_height(f)(hd);
2934  if x>box_height then box_height:=x;
2935  x:=char_depth(f)(hd);
2936  if x>box_depth then box_depth:=x;
2937  if send_it then
2938    begin typeset(cur_l);
2939    if kern_amount<>0 then
2940      begin dvi_out(right4); dvi_four(kern_amount);
2941      end;
2942    end;
2943  kern_amount:=0;
2944  end
2945
2946@ @d pop_stack==begin decr(stack_ptr);
2947    if stack_ptr>0 then cur_r:=lig_stack[stack_ptr]
2948    else set_cur_r;
2949    end
2950
2951@<Carry out a ligature operation, updating the cursor structure...@>=
2952begin case op_byte(j) of
29531,5:cur_l:=qo(rem_byte(j));
29542,6:begin cur_r:=rem_byte(j);
2955  if stack_ptr=0 then
2956    begin stack_ptr:=1;
2957    if k<end_k then incr(k) {a non-space character is consumed}
2958    else bchar:=non_char; {the right boundary character is consumed}
2959    end;
2960  lig_stack[stack_ptr]:=cur_r;
2961  end;
29623,7,11:begin cur_r:=rem_byte(j); incr(stack_ptr); lig_stack[stack_ptr]:=cur_r;
2963  if op_byte(j)=11 then suppress_lig:=true;
2964  end;
2965othercases begin cur_l:=qo(rem_byte(j));
2966  if stack_ptr>0 then pop_stack
2967  else if k=end_k then goto done
2968  else begin incr(k); set_cur_r;
2969    end;
2970  end
2971endcases;
2972if op_byte(j)>3 then goto done;
2973goto continue;
2974end
2975
2976@ @<Move the cursor to the right and |goto continue|...@>=
2977cur_l:=qo(cur_r);
2978if stack_ptr>0 then
2979  begin pop_stack; goto continue;
2980  end;
2981if k<end_k then
2982  begin incr(k); set_cur_r; goto continue;
2983  end
2984
2985@* Gray fonts.
2986A proof diagram constructed by \.{GFtoDVI}
2987can be regarded as an array of rectangles, where each rectangle is either
2988blank or filled with a special symbol that we shall call $x$. A blank
2989rectangle represents a white pixel, while $x$ represents a black pixel.
2990Additional labels and reference lines are often superimposed on this
2991array of rectangles; hence it is usually best to choose a symbol $x$ that
2992has a somewhat gray appearance, although any symbol can actually be used.
2993
2994In order to construct such proofs, \.{GFtoDVI} needs to work with
2995a special type of font known as a ``gray font''; it's possible to
2996obtain a wide variety of different sorts of proofs by using different
2997sorts of gray fonts. The next few paragraphs explain exactly what gray
2998fonts are supposed to contain, in case you want to design your own.
2999@^gray fonts@>
3000
3001@ The simplest gray font contains only two characters, namely $x$
3002and another symbol that is used for dots that identify key points.
3003If proofs with relatively large pixels are desired, a two-character
3004gray font is all that's needed. However, if the pixel size is to be
3005relatively small, practical considerations make a two-character
3006font too inefficient, since it requires the typesetting of tens
3007of thousands of tiny little characters; printing device drivers
3008rarely work very well when they are presented with data that is
3009so different from ordinary text. Therefore a gray font with small
3010pixels usually has a number of characters that replicate $x$ in
3011such a way that comparatively few characters actually need to be
3012typeset.
3013
3014Since many printing devices are not able to cope with
3015arbitrarily large or complex characters, it is not possible for a
3016single gray font to work well on all machines. In fact,
3017$x$ must have a width that is an integer multiple of the printing
3018device's unit of horizontal position, since rounding the positions of grey
3019characters would otherwise produce unsightly streaks on proof output.
3020Thus, there is no way to make the gray font as device-independent as
3021the rest of the system, in the sense that we would expect approximately
3022identical output on machines with different resolution. Fortunately,
3023proof sheets are rarely considered to be final documents; hence
3024\.{GFtoDVI} is set up to provide results that adapt suitably to
3025local conditions.
3026
3027@ With such constraints understood, we can now take a look at what
3028\.{GFtoDVI} expects to see in a gray font. The character~$x$ always
3029appears in position~1. It must have positive height~$h$ and positive
3030width~$w$; its depth and italic correction are ignored.
3031
3032Positions 2--120 of a gray font are reserved for special combinations
3033of $x$'s and blanks, stacked on top of each other. None of these character
3034codes need be present in the font; but if they are, the slots should be
3035occupied by characters of width~$w$ that have certain configurations of
3036$x$'s and blanks, prescribed for each character position. For example,
3037position~3 of the font should either contain no character at all,
3038or it should contain a character consisting of two $x$'s, one above
3039the other; one of these $x$'s should appear immediately above the
3040baseline, and the other should appear immediately below.
3041
3042It will be convenient to use a horizontal notation like `\.{XOXXO}'
3043to stand for a vertical stack of $x$'s and blanks. The convention
3044will be that the stack is built from bottom to top, and the topmost
3045rectangle should sit on the baseline. Thus, `\.{XOXXO}' stands
3046actually for a character of depth~$4h$ that looks like this:
3047$$\vcenter{\halign{\hfil#\hfil\cr
3048blank\cr
3049$x$\rlap{\qquad\raise8pt\hbox{\smash{\hbox{$\longleftarrow$ baseline}}}}\cr
3050$x$\cr
3051blank\cr
3052$x$\cr
3053}}$$
3054(We use a horizontal notation instead of a vertical one in this explanation,
3055because column
3056vectors take too much space, and because the horizontal notation corresponds
3057to binary numbers in a convenient way.)
3058
3059Positions 1--63 of a gray font are reserved for the patterns \.X, \.{XO},
3060\.{XX}, \.{XOO}, \.{XOX}, \dots, \.{XXXXXX}, just as in the normal
3061binary notation of the numbers 1--63. Positions 64--70 are reserved for
3062the special patterns \.{XOOOOOO}, \.{XXOOOOO}, \dots, \.{XXXXXXO},
3063\.{XXXXXXX} of length seven; positions 71--78 are, similarly, reserved for
3064the length-eight patterns \.{XOOOOOOO} through \.{XXXXXXXX}. The
3065length-nine patterns \.{XOOOOOOOO} through \.{XXXXXXXXX} are assigned
3066to positions 79--87, the length-ten patterns to positions 88--97,
3067the length-eleven patterns to positions 98--108, and the length-twelve
3068patterns to positions 109--120.
3069
3070The following program sets a global array |c[1..120]| to the bit patterns
3071just described. Another array |d[1..120]| is set to contain only the next
3072higher bit; this determines the depth of the corresponding character.
3073
3074@<Set init...@>=
3075c[1]:=1; d[1]:=2; two_to_the[0]:=1; m:=1;
3076for k:=1 to 13 do two_to_the[k]:=2*two_to_the[k-1];
3077for k:=2 to 6 do @<Add a full set of |k|-bit characters@>;
3078for k:=7 to 12 do @<Add special |k|-bit characters of the form \.{X..XO..O}@>;
3079
3080@ @<Glob...@>=
3081@!c:array[1..120] of 1..4095; {bit patterns for a gray font}
3082@!d:array[1..120] of 2..4096; {the superleading bits}
3083@!two_to_the:array[0..13] of 1..8192; {powers of 2}
3084
3085@ @<Add a full set of |k|-bit...@>=
3086begin n:=two_to_the[k-1];
3087for j:=0 to n-1 do
3088  begin incr(m); c[m]:=m; d[m]:=n+n;
3089  end;
3090end
3091
3092@ @<Add special |k|-bit...@>=
3093begin n:=two_to_the[k-1];
3094for j:=k downto 1 do
3095  begin incr(m); d[m]:=n+n;
3096  if j=k then c[m]:=n
3097  else c[m]:=c[m-1]+two_to_the[j-1];
3098  end;
3099end
3100
3101@ Position 0 of a gray font is reserved for the ``dot'' character, which
3102should have positive height~$h'$ and positive width~$w'$. When \.{GFtoDVI}
3103wants to put a dot at some place $(x,y)$ on the figure, it positions
3104the dot character so that its reference point is at $(x,y)$. The
3105dot will be considered to occupy a rectangle $(x+\delta,y+\epsilon)$
3106for $-w'\leq\delta\leq w'$ and $-h'\leq\epsilon\leq h'$; the rectangular
3107box for a label will butt up against the rectangle enclosing the dot.
3108
3109@ All other character positions of a gray font (namely, positions 121--255)
3110are unreserved, in the sense that they have no predefined meaning.
3111But \.{GFtoDVI} may access them via the ``character list'' feature of
3112\.{TFM} files, starting with any of the characters in positions
31131--120. In such a case each succeeding character in a list should be
3114equivalent to two of its predecessors, horizontally adjacent to each other.
3115For example, in a character list like
3116$$53,\;121,\;122,\;123$$
3117character 121 will stand for two 53's, character 122 for two 121's (i.e.,
3118four 53's), and character 123 for two 122's (i.e., eight 53's). Since
3119position~53 contains the pattern \.{XXOXOX}, character~123 in this example
3120would have height~$h$, depth~$5h$, and width~$8w$, and it would stand for
3121the pattern
3122$$\vcenter{\halign{&$\hfil#\hfil$\cr
3123x&x&x&x&x&x&x&x\cr
3124&&&&&&&\cr
3125x&x&x&x&x&x&x&x\cr
3126&&&&&&&\cr
3127x&x&x&x&x&x&x&x\cr
3128x&x&x&x&x&x&x&x\cr}}$$
3129Such a pattern is, of course, rather unlikely to occur in a \.{GF} file,
3130but \.{GFtoDVI} would be able to use if it were present. Designers
3131of gray fonts should provide characters only for patterns that they think
3132will occur often enough to make the doubling worthwhile. For example,
3133the character in position 120 (\.{XXXXXXXXXXXX}), or whatever is the
3134tallest stack of $x$'s present in the font, is a natural candidate for
3135repeated doubling.
3136
3137Here's how \.{GFtoDVI} decides what characters of the gray font will be used,
3138given a configuration of black and white pixels: If there are no black
3139pixels, stop. Otherwise look at the top row that contains at least one
3140black pixel, and the eleven rows that follow. For each such column,
3141find the largest~$k$ such that $1\leq k\leq120$ and the gray font contains
3142character~$k$ and the pattern assigned to position~$k$ appears in the
3143given column. Typeset character $k$ (unless no such character exists)
3144and erase the corresponding black pixels; use doubled characters,
3145if they are present in the gray font, if two or more consecutive equal
3146characters need to be typeset. Repeat the same process on the remaining
3147configuration, until all the black pixels have been erased.
3148
3149If all characters in positions 1--120 are present, this process is guaranteed to
3150take care of at least six rows each time; and it usually takes care of
3151twelve, since all patterns that contain at most one ``run'' of $x$'s
3152are present.
3153
3154@ Fonts have optional parameters, as described in Appendix~F of {\sl The
3155\TeX book}, and some of these are important in gray fonts. The
3156slant parameter~$s$, if nonzero, will cause \.{GFtoDVI} to skew its
3157output; in this case the character $x$ will presumably be a parallelogram
3158with a corresponding slant, rather than the usual rectangle. \MF's
3159coordinate $(x,y)$ will appear in physical position $(xw+yhs,yh)$
3160on the proofsheets.
3161
3162Parameter number~8 of a gray font specifies the thickness of rules
3163that go on the proofs. If this parameter is zero, \TeX's default
3164rule thickness (0.4\thinspace pt) will be used.
3165
3166The other parameters of a gray font are ignored by \.{GFtoDVI}, but
3167it is conventional to set the font space parameter to~$w$ and the
3168xheight parameter to~$h$.
3169
3170@ For best results the designer of a gray font should choose $h$ and~$w$
3171so that the user's \.{DVI}-to-hardcopy software will not make any
3172rounding errors. Furthermore, the dot should be an even number~$2m$ of
3173pixels in diameter, and the rule thickness should work out to an
3174even number~$2n$ of pixels; then the dots and rules will be centered on
3175the correct positions, in case of integer coordinates. Gray fonts
3176are almost always intended for particular output devices, even though
3177`\.{DVI}' stands for `device independent'; we use \.{DVI} files for \MF\
3178proofs chiefly because software to print \.{DVI} files is already in place.
3179
3180@* Slant fonts.
3181\.{GFtoDVI} also makes use of another special type of font, if it is
3182necessary to typeset slanted rules. The format of such  so-called
3183``slant fonts'' is quite a bit simpler than the format of gray fonts.
3184
3185A slant font should contain exactly $n$ characters, in positions 1 to~$n$,
3186where the character in position~$k$ represents a slanted line $k$ units
3187tall, starting at the baseline. These lines all have a fixed slant ratio~$s$.
3188
3189The following simple algorithm is used to typeset a rule that is $m$ units
3190high: Compute $q=\lceil m/n\rceil$; then typeset $q$~characters of
3191approximately equal size, namely $(m\bmod q)$ copies of character number
3192$\lceil m/q\rceil$ and $q-(m\bmod q)$ copies of character number
3193$\lfloor m/q\rfloor$. For example, if $n=15$ and $m=100$, we have $q=7$;
3194a 100-unit-high rule will be composed of 7~pieces, using characters
319514,~14, 14, 14, 14, 15,~15.
3196
3197@<Glob...@>=
3198@!rule_slant:real; {the slant ratio $s$ in the slant font,
3199  or zero if there is no slant font}
3200@!slant_n:integer; {the number of characters in the slant font}
3201@!slant_unit:real; {the number of scaled points in the slant font unit}
3202@!slant_reported:real; {invalid slant ratio reported to the user}
3203
3204@ \.{GFtoDVI} looks only at the height of character $n$, so the \.{TFM} file
3205need not be accurate about the heights of the other characters. (This is
3206fortunate, since \.{TFM} format allows at most 16 different heights per font.)
3207
3208The width of character~$k$ should be $k/n$ times $s$ times the height of
3209character~$n$.
3210
3211The slant parameter of a slant file should be $s$. It is customary to
3212set the |default_rule_thickness| parameter (number~8) to the thickness of
3213the slanted rules, but \.{GFtoDVI} doesn't look at it.
3214
3215@ For best results on a particular output device, it is usually wise to
3216choose the `unit' in the above discussion to be an integer number of pixels,
3217and to make it no larger than the default rule thickness in the gray font
3218being used.
3219
3220@ @<Initialize glob...@>=
3221if length(font_name[slant_font])=0 then rule_slant:=0.0
3222else  begin rule_slant:=slant(slant_font)/unity;
3223  slant_n:=font_ec[slant_font];
3224  i:=char_info(slant_font)(slant_n);
3225  slant_unit:=char_height(slant_font)(height_depth(i))/slant_n;
3226  end;
3227slant_reported:=0.0;
3228
3229@ The following error message is given when an absent slant has been
3230requested.
3231
3232@p procedure slant_complaint(@!r:real);
3233begin if abs(r-slant_reported)>0.001 then
3234  begin print_nl('Sorry, I can''t make diagonal rules of slant ',r:10:5,'!');
3235@.Sorry, I can't...@>
3236  slant_reported:=r;
3237  end;
3238end;
3239
3240@* Representation of rectangles.
3241OK---the preliminary spadework has now been done. We're ready at last
3242to concentrate on \.{GFtoDVI}'s {\sl raison d'\^^Detre}.
3243
3244One of the most interesting tasks remaining is to make
3245a ``map'' of the labels that have been allocated.
3246There usually aren't a great many labels, so we don't need fancy data
3247structures; but we do make use of linked nodes containing nine fields.
3248The nodes generally represent rectangular boxes according to the
3249following conventions:
3250\smallskip\hang\noindent
3251|xl|, |xr|, |yt|, and |yb| are the left, right, top, and bottom locations
3252of a rectangle, expressed in \.{DVI} coordinates. (This program uses
3253scaled points as \.{DVI} coordinates. Since \.{DVI} coordinates increase
3254as one moves down the page, |yb| will be greater than |yt|.)
3255\smallskip\hang\noindent
3256|xx| and |yy| are the coordinates of the reference point of a box to be
3257typeset from this node, again in \.{DVI} coordinates.
3258\smallskip\hang\noindent
3259|prev| and |next| point to the predecessor and successor of this node.
3260Sometimes the nodes are singly linked and only |next| is relevant; otherwise
3261the nodes are doubly linked in order of their |yy| coordinates, so that we
3262can move down by going to |next|, or up by going to |prev|.
3263\smallskip\hang\noindent
3264|info| is the number of a string associated with this node.
3265\smallskip\noindent
3266
3267The nine fields of a node appear in nine global arrays.
3268Null pointers are denoted by |null|, which happens to be zero.
3269
3270@d null=0
3271
3272@<Types ...@>=
3273@!node_pointer=null..max_labels;
3274
3275@ @<Glob...@>=
3276@!xl,@!xr,@!yt,@!yb:array[1..max_labels] of scaled; {boundary coordinates}
3277@!xx,@!yy:array[0..max_labels] of scaled; {reference coordinates}
3278@!prev,@!next:array[0..max_labels] of node_pointer; {links}
3279@!info:array[1..max_labels] of str_number; {associated strings}
3280@!max_node:node_pointer; {the largest node in use}
3281@!max_height:scaled; {greatest difference between |yy| and |yt|}
3282@!max_depth:scaled; {greatest difference between |yb| and |yy|}
3283
3284
3285@ It's easy to allocate a new node (unless no more room is left):
3286
3287@p function get_avail:node_pointer;
3288begin incr(max_node);
3289if max_node=max_labels then abort('Too many labels and/or rules!');
3290@.Too many labels@>
3291get_avail:=max_node;
3292end;
3293
3294@ The doubly linked nodes are sorted by |yy| coordinates so that we don't have
3295to work too hard to find nearest neighbors or to determine if rectangles overlap.
3296The first node in the doubly linked rectangle list is always in location~0,
3297and the last node is always in location |max_labels|; the |yy| coordinates
3298of these nodes are very small and very large, respectively.
3299
3300@d end_of_list==max_labels
3301
3302@<Set init...@>=
3303yy[0]:=-@'10000000000; yy[end_of_list]:=@'10000000000;
3304
3305@ The |node_ins| procedure inserts a new rectangle, represented by node~|p|,
3306into the doubly linked list. There's a second parameter, |q|; node~|q| should
3307already be in the doubly linked list, preferably with |yy[q]| near |yy[p]|.
3308
3309@p procedure node_ins(@!p,@!q:node_pointer);
3310var @!r:node_pointer; {for tree traversal}
3311begin if yy[p]>=yy[q] then
3312  begin repeat r:=q; q:=next[q];@+until yy[p]<=yy[q];
3313  next[r]:=p; prev[p]:=r; next[p]:=q; prev[q]:=p;
3314  end
3315else  begin repeat r:=q; q:=prev[q];@+until yy[p]>=yy[q];
3316  prev[r]:=p; next[p]:=r; prev[p]:=q; next[q]:=p;
3317  end;
3318if yy[p]-yt[p]>max_height then max_height:=yy[p]-yt[p];
3319if yb[p]-yy[p]>max_depth then max_depth:=yb[p]-yy[p];
3320end;
3321
3322@ The data structures need to be initialized for each character in the
3323\.{GF} file.
3324
3325@<Initialize variables for the next character@>=
3326max_node:=0; next[0]:=end_of_list; prev[end_of_list]:=0;
3327max_height:=0; max_depth:=0;
3328
3329@ The |overlap| subroutine determines whether or not the rectangle specified
3330in node~|p| has a nonempty intersection with some rectangle in the doubly
3331linked list. Again |q|~is a parameter that gives us a starting point
3332in the list. We assume that |q<>end_of_list|, so that |next[q]| is meaningful.
3333
3334@p function overlap(@!p,@!q:node_pointer):boolean;
3335label exit;
3336var @!y_thresh:scaled; {cutoff value to speed the search}
3337@!x_left,@!x_right,@!y_top,@!y_bot:scaled; {boundaries to test for overlap}
3338@!r:node_pointer; {runs through the neighbors of |q|}
3339begin x_left:=xl[p]; x_right:=xr[p]; y_top:=yt[p]; y_bot:=yb[p];
3340@<Look for overlaps in the successors of node |q|@>;
3341@<Look for overlaps in node |q| and its predecessors@>;
3342overlap:=false;
3343exit: end;
3344
3345@ @<Look for overlaps in the successors of node |q|@>=
3346y_thresh:=y_bot+max_height; r:=next[q];
3347while yy[r]<y_thresh do
3348  begin if y_bot > yt[r] then if x_left<xr[r] then
3349   if x_right>xl[r] then if y_top<yb[r] then
3350    begin overlap:=true; return;
3351    end;
3352  r:=next[r];
3353  end
3354
3355@ @<Look for overlaps in node |q| and its predecessors@>=
3356y_thresh:=y_top-max_depth; r:=q;
3357while yy[r]>y_thresh do
3358  begin if y_bot > yt[r] then if x_left<xr[r] then
3359   if x_right>xl[r] then if y_top<yb[r] then
3360    begin overlap:=true; return;
3361    end;
3362  r:=prev[r];
3363  end
3364
3365@ Nodes that represent dots instead of labels satisfy the following
3366constraints:
3367$$\vcenter{\halign{#\hfil&\quad#\hfil\cr
3368|info[p]<0;|&|p>=first_dot|;\cr
3369|xl[p]=xx[p]-dot_width|,&|xr[p]=xx[p]+dot_width|;\cr
3370|yt[p]=yy[p]-dot_height|,&|yb[p]=yy[p]+dot_height|.\cr}}$$
3371
3372The |nearest_dot| subroutine finds a node whose reference point is as
3373close as possible to a given position, ignoring nodes that are too close.
3374More precisely, the ``nearest'' node
3375minimizes$$d(q,p)=\max\bigl(\vert |xx|[q]-|xx|[p]\vert,
3376  \vert |yy|[q]-|yy|[p]\vert\bigr)$$ over all nodes~|q|
3377with |d(q,p)>=d0|. We call the subroutine |nearest_dot| because it is used only
3378when the doubly linked list contains nothing but dots.
3379
3380The routine also sets the global variable |twin| to |true|, if there is a
3381node |q<>p| with |d(q,p)<d0|.
3382
3383@ @<Glob...@>=
3384@!first_dot:node_pointer; {the node address where dots begin}
3385@!twin:boolean; {is there a nearer dot than the ``nearest'' dot?}
3386
3387@ If there is no nearest dot, the value |null| is returned;
3388otherwise a pointer to the nearest dot is returned.
3389
3390@p function nearest_dot(@!p:node_pointer; @!d0:scaled):node_pointer;
3391var @!best_q:node_pointer; {value to return}
3392@!d_min,@!d:scaled; {distances}
3393begin twin:=false; best_q:=0; d_min:=@'2000000000;
3394@<Search for the nearest dot in nodes following |p|@>;
3395@<Search for the nearest dot in nodes preceding |p|@>;
3396nearest_dot:=best_q;
3397end;
3398
3399@ @<Search for the nearest dot in nodes following |p|@>=
3400q:=next[p];
3401while yy[q]<yy[p]+d_min do
3402  begin d:=abs(xx[q]-xx[p]);
3403  if d<yy[q]-yy[p] then d:=yy[q]-yy[p];
3404  if d<d0 then twin:=true
3405  else if d<d_min then
3406    begin d_min:=d; best_q:=q;
3407    end;
3408  q:=next[q];
3409  end
3410
3411@ @<Search for the nearest dot in nodes preceding |p|@>=
3412q:=prev[p];
3413while yy[q]>yy[p]-d_min do
3414  begin d:=abs(xx[q]-xx[p]);
3415  if d<yy[p]-yy[q] then d:=yy[p]-yy[q];
3416  if d<d0 then twin:=true
3417  else if d<d_min then
3418    begin d_min:=d; best_q:=q;
3419    end;
3420  q:=prev[q];
3421  end
3422
3423@* Doing the labels.
3424Each ``character'' in the \.{GF} file is preceded by a number of special
3425commands that define labels, titles, rules, etc. We store these away,
3426to be considered later when the |boc| command appears. The |boc|
3427command establishes the size information by which labels and rules
3428can be positioned, so we spew out the label information as soon as
3429we see the |boc|. The gray pixels will be typeset after all the labels
3430for a particular character have been finished.
3431
3432@ Here is the part of \.{GFtoDVI} that stores information preceding a~|boc|.
3433It comes into play when |cur_gf| is between |xxx1| and~|no_op|, inclusive.
3434
3435@d font_change(#)==if fonts_not_loaded then
3436    begin #; end
3437  else print_nl('(Tardy font change will be ignored (byte ',
3438@.Tardy font change...@>
3439    cur_loc:1,')!)')
3440
3441@<Process a no-op command@>=
3442begin k:=interpret_xxx;
3443case k of
3444no_operation: do_nothing;
3445title_font,label_font,gray_font,slant_font:font_change(font_name[k]:=cur_string;
3446  font_area[k]:=null_string;font_at[k]:=0;init_str_ptr:=str_ptr);
3447title_font+area_code,label_font+area_code,gray_font+area_code,
3448  slant_font+area_code:@|
3449  font_change(font_area[k-area_code]:=cur_string;init_str_ptr:=str_ptr);
3450title_font+at_code,label_font+at_code,gray_font+at_code,
3451  slant_font+at_code:@|
3452  font_change(font_at[k-at_code]:=get_yyy;init_str_ptr:=str_ptr);
3453rule_thickness_code:rule_thickness:=get_yyy;
3454rule_code:@<Store a rule@>;
3455offset_code:@<Override the offsets@>;
3456x_offset_code:x_offset:=get_yyy;
3457y_offset_code:y_offset:=get_yyy;
3458title_code:@<Store a title@>;
3459null_string:@<Store a label@>;
3460end; {there are no other cases}
3461end
3462
3463@ The following quantities are cleared just before reading the
3464\.{GF} commands pertaining to a character.
3465
3466@<Glob...@>=
3467@!rule_thickness:scaled; {the current rule thickness
3468  (zero means use the default)}
3469@!offset_x,@!offset_y:scaled; {the current offsets for images}
3470@!x_offset,@!y_offset:scaled; {the current offsets for labels}
3471@!pre_min_x,@!pre_max_x,@!pre_min_y,@!pre_max_y:scaled;
3472  {extreme values of coordinates preceding a character, in \MF\ pixels}
3473
3474@ @<Initialize variables for the next character@>=
3475rule_thickness:=0;
3476offset_x:=0; offset_y:=0; x_offset:=0; y_offset:=0;
3477pre_min_x:=@'2000000000; pre_max_x:=-@'2000000000;
3478pre_min_y:=@'2000000000; pre_max_y:=-@'2000000000;
3479
3480@ @<Override the offsets@>=
3481begin offset_x:=get_yyy; offset_y:=get_yyy;
3482end
3483
3484@ Rules that will need to be drawn are kept in a linked list accessible
3485via |rule_ptr|, in last-in-first-out order.  The nodes of this list will
3486never get into the doubly linked list, and indeed these nodes use different
3487field conventions entirely (because rules may be slanted).
3488
3489@d x0==xl {starting |x| coordinate of a stored rule}
3490@d y0==yt {starting |y| coordinate (in scaled \MF\ pixels)}
3491@d x1==xr {ending |x| coordinate of a stored rule}
3492@d y1==yb {ending |y| coordinate of a stored rule}
3493@d rule_size==xx {thickness of a stored rule, in scaled points}
3494
3495@<Glob...@>=
3496@!rule_ptr:node_pointer; {top of the stack of remembered rules}
3497
3498@ @<Store a rule@>=
3499begin p:=get_avail; next[p]:=rule_ptr; rule_ptr:=p;@/
3500x0[p]:=get_yyy; y0[p]:=get_yyy; x1[p]:=get_yyy; y1[p]:=get_yyy;
3501if x0[p]<pre_min_x then pre_min_x:=x0[p];
3502if x0[p]>pre_max_x then pre_max_x:=x0[p];
3503if y0[p]<pre_min_y then pre_min_y:=y0[p];
3504if y0[p]>pre_max_y then pre_max_y:=y0[p];
3505if x1[p]<pre_min_x then pre_min_x:=x1[p];
3506if x1[p]>pre_max_x then pre_max_x:=x1[p];
3507if y1[p]<pre_min_y then pre_min_y:=y1[p];
3508if y1[p]>pre_max_y then pre_max_y:=y1[p];
3509rule_size[p]:=rule_thickness;
3510end
3511
3512@ Titles and labels are, likewise, stored temporarily in singly linked lists.
3513In this case the lists are first-in-first-out.
3514Variables |title_tail| and |label_tail| point to the most recently inserted
3515title or label; variables |title_head| and |label_head|
3516point to the beginning of the list. (A standard coding trick is used
3517for |label_head|, which is kept in |next[end_of_list]|; we have
3518|label_tail=end_of_list| when the list is empty.)
3519
3520The |prev| field in nodes of the temporary label list specifies the
3521type of label, so we call it |lab_typ|.
3522
3523@d lab_typ==prev {the type of a stored label (|"/"..."8"|)}
3524@d label_head==next[end_of_list]
3525
3526@<Glob...@>=
3527@!label_tail:node_pointer; {tail of the queue of remembered labels}
3528@!title_head,@!title_tail:node_pointer; {head and tail of the queue for titles}
3529
3530@ We must start the lists out empty.
3531
3532@<Initialize variables for the next char...@>=
3533rule_ptr:=null;
3534title_head:=null; title_tail:=null; label_head:=null; label_tail:=end_of_list;
3535first_dot:=max_labels;
3536
3537@ @<Store a title@>=
3538begin p:=get_avail; info[p]:=cur_string;
3539if title_head=null then title_head:=p
3540else next[title_tail]:=p;
3541title_tail:=p;
3542end
3543
3544@ We store the coordinates of each label in units of \MF\ pixels; they
3545will be converted to \.{DVI} coordinates later.
3546
3547@<Store a label@>=
3548if (label_type<"/")or(label_type>"8") then
3549  print_nl('Bad label type precedes byte ',cur_loc:1,'!')
3550@.Bad label type...@>
3551else  begin p:=get_avail; next[label_tail]:=p; label_tail:=p;@/
3552  lab_typ[p]:=label_type; info[p]:=cur_string;@/
3553  xx[p]:=get_yyy; yy[p]:=get_yyy;
3554  if xx[p]<pre_min_x then pre_min_x:=xx[p];
3555  if xx[p]>pre_max_x then pre_max_x:=xx[p];
3556  if yy[p]<pre_min_y then pre_min_y:=yy[p];
3557  if yy[p]>pre_max_y then pre_max_y:=yy[p];
3558  end
3559
3560@ The process of ferreting everything away comes to an abrupt halt
3561when a |boc| command is sensed. The following steps are performed
3562at such times:
3563
3564@<Process a character@>=
3565begin check_fonts;
3566@<Finish reading the parameters of the |boc|@>;
3567@<Get ready to convert \MF\ coordinates to \.{DVI} coordinates@>;
3568@<Output the |bop| and the title line@>;
3569print('[',total_pages:1); update_terminal; {print a progress report}
3570@<Output all rules for the current character@>;
3571@<Output all labels for the current character@>;
3572do_pixels;
3573dvi_out(eop); {finish the page}
3574@<Adjust the maximum page width@>;
3575print(']'); update_terminal;
3576end
3577
3578@ @<Finish reading the parameters of the |boc|@>=
3579if cur_gf=boc then
3580  begin ext:=signed_quad; {read the character code}
3581  char_code:=ext mod 256;
3582  if char_code<0 then char_code:=char_code+256;
3583  ext:=(ext-char_code) div 256;
3584  k:=signed_quad; {read and ignore the prev pointer}
3585  min_x:=signed_quad; {read the minimum $x$ coordinate}
3586  max_x:=signed_quad; {read the maximum $x$ coordinate}
3587  min_y:=signed_quad; {read the minimum $y$ coordinate}
3588  max_y:=signed_quad; {read the maximum $y$ coordinate}
3589  end
3590else  begin ext:=0; char_code:=get_byte; {|cur_gf=boc1|}
3591  min_x:=get_byte; max_x:=get_byte; min_x:=max_x-min_x;@/
3592  min_y:=get_byte; max_y:=get_byte; min_y:=max_y-min_y;
3593  end;
3594if max_x-min_x>widest_row then abort('Character too wide!')
3595@.Character too wide@>
3596
3597@ @<Glob...@>=
3598@!char_code,@!ext:integer; {the current character code and extension}
3599@!min_x,@!max_x,@!min_y,@!max_y:integer; {character boundaries, in pixels}
3600@!x,@!y:integer; {current painting position, in pixels}
3601@!z:integer; {initial painting position in row, relative to |min_x|}
3602
3603@ \MF\ coordinates $(x,y)$ are converted to \.{DVI} coordinates by the
3604following routine. Real values |x_ratio|, |y_ratio|, and |slant_ratio|
3605will have been calculated based on the gray font; |scaled| values
3606|delta_x| and |delta_y| will have been computed so that, in the absence
3607of slanting and offsets, the \MF\ coordinates |(min_x,max_y+1)| will correspond
3608to the \.{DVI} coordinates $(0,50\,\rm pt)$.
3609
3610@p procedure convert(@!x,@!y:scaled);
3611begin x:=x+x_offset; y:=y+y_offset;
3612dvi_y:=-round(y_ratio*y)+delta_y;
3613dvi_x:=round(x_ratio*x+slant_ratio*y)+delta_x;
3614end;
3615
3616@ @<Glob...@>=
3617@!x_ratio,@!y_ratio,@!slant_ratio:real; {conversion factors}
3618@!unsc_x_ratio,@!unsc_y_ratio,@!unsc_slant_ratio:real;
3619  {ditto, times |unity|}
3620@!fudge_factor:real; {unconversion factor}
3621@!delta_x,@!delta_y:scaled; {magic constants used by |convert|}
3622@!dvi_x,@!dvi_y:scaled; {outputs of |convert|, in scaled points}
3623@!over_col:scaled; {overflow labels start here}
3624@!page_height,page_width:scaled; {size of the current page}
3625
3626@ @<Initialize global variables that depend on the font data@>=
3627i:=char_info(gray_font)(1);
3628if not char_exists(i) then abort('Missing pixel char!');
3629@.Missing pixel char@>
3630unsc_x_ratio:=char_width(gray_font)(i);
3631x_ratio:=unsc_x_ratio/unity;
3632unsc_y_ratio:=char_height(gray_font)(height_depth(i));
3633y_ratio:=unsc_y_ratio/unity;
3634unsc_slant_ratio:=slant(gray_font)*y_ratio;
3635slant_ratio:=unsc_slant_ratio/unity;
3636if x_ratio*y_ratio=0 then abort('Vanishing pixel size!');
3637@.Vanishing pixel size@>
3638fudge_factor:=(slant_ratio/x_ratio)/y_ratio;
3639
3640@ @<Get ready to convert...@>=
3641if pre_min_x<min_x*unity then offset_x:=offset_x+min_x*unity-pre_min_x;
3642if pre_max_y>max_y*unity then offset_y:=offset_y+max_y*unity-pre_max_y;
3643if pre_max_x>max_x*unity then pre_max_x:=pre_max_x div unity
3644else pre_max_x:=max_x;
3645if pre_min_y<min_y*unity then pre_min_y:=pre_min_y div unity
3646else pre_min_y:=min_y;
3647delta_y:=round(unsc_y_ratio*(max_y+1)-y_ratio*offset_y)+3276800;
3648delta_x:=round(x_ratio*offset_x-unsc_x_ratio*min_x);
3649if slant_ratio>=0 then
3650  over_col:=round(unsc_x_ratio*pre_max_x+unsc_slant_ratio*max_y)
3651else over_col:=round(unsc_x_ratio*pre_max_x+unsc_slant_ratio*min_y);
3652over_col:=over_col+delta_x+10000000;
3653page_height:=round(unsc_y_ratio*(max_y+1-pre_min_y))+3276800-offset_y;
3654if page_height>max_v then max_v:=page_height;
3655page_width:=over_col-10000000
3656
3657@ The |dvi_goto| subroutine outputs bytes to the \.{DVI} file that
3658will initiate typesetting at given \.{DVI} coordinates, assuming that
3659the current position of the \.{DVI} reader is $(0,0)$. This subroutine
3660begins by outputting a |push| command; therefore, a |pop| command should
3661be given later. That |pop| will restore the \.{DVI} position to $(0,0)$.
3662
3663@p procedure dvi_goto(@!x,@!y:scaled);
3664begin dvi_out(push);
3665if x<>0 then
3666  begin dvi_out(right4); dvi_four(x);
3667  end;
3668if y<>0 then
3669  begin dvi_out(down4); dvi_four(y);
3670  end;
3671end;
3672
3673@ @<Output the |bop| and the title line@>=
3674dvi_out(bop); incr(total_pages); dvi_four(total_pages);
3675dvi_four(char_code); dvi_four(ext);
3676for k:=3 to 9 do dvi_four(0);
3677dvi_four(last_bop); last_bop:=dvi_offset+dvi_ptr-45;@/
3678dvi_goto(0,655360); {the top baseline is 10\thinspace pt down}
3679if use_logo then
3680  begin select_font(logo_font); hbox(small_logo,logo_font,true);
3681  end;
3682select_font(title_font); hbox(time_stamp,title_font,true);@/
3683hbox(page_header,title_font,true); dvi_scaled(total_pages*65536.0);@/
3684if (char_code<>0)or(ext<>0) then
3685  begin hbox(char_header,title_font,true); dvi_scaled(char_code*65536.0);
3686  if ext<>0 then
3687    begin hbox(ext_header,title_font,true); dvi_scaled(ext*65536.0);
3688    end;
3689  end;
3690if title_head<>null then
3691  begin next[title_tail]:=null;
3692  repeat hbox(left_quotes,title_font,true);
3693  hbox(info[title_head],title_font,true);
3694  hbox(right_quotes,title_font,true);
3695  title_head:=next[title_head];
3696  until title_head=null;
3697  end;
3698dvi_out(pop)
3699
3700@ @d tol==6554 {one tenth of a point, in \.{DVI} coordinates}
3701
3702@<Output all rules for the current character@>=
3703if rule_slant<>0 then select_font(slant_font);
3704while rule_ptr<>null do
3705  begin p:=rule_ptr; rule_ptr:=next[p];@/
3706  if rule_size[p]=0 then rule_size[p]:=gray_rule_thickness;
3707  if rule_size[p]>0 then
3708    begin convert(x0[p],y0[p]); temp_x:=dvi_x; temp_y:=dvi_y;
3709    convert(x1[p],y1[p]);
3710    if abs(temp_x-dvi_x)<tol then @<Output a vertical rule@>
3711    else if abs(temp_y-dvi_y)<tol then @<Output a horizontal rule@>
3712    else @<Try to output a diagonal rule@>;
3713    end;
3714  end
3715
3716@ @<Glob...@>=
3717@!gray_rule_thickness:scaled; {thickness of rules, according to the gray font}
3718@!temp_x,@!temp_y:scaled; {temporary registers for intermediate calculations}
3719
3720@ @<Initialize glob...@>=
3721gray_rule_thickness:=default_rule_thickness(gray_font);
3722if gray_rule_thickness=0 then gray_rule_thickness:=26214; {0.4\thinspace pt}
3723
3724@ @<Output a vertical rule@>=
3725begin if temp_y>dvi_y then
3726  begin k:=temp_y; temp_y:=dvi_y; dvi_y:=k;
3727  end;
3728dvi_goto(dvi_x-(rule_size[p] div 2), dvi_y);
3729dvi_out(put_rule); dvi_four(dvi_y-temp_y); dvi_four(rule_size[p]);
3730dvi_out(pop);
3731end
3732
3733@ @<Output a horizontal rule@>=
3734begin if temp_x<dvi_x then
3735  begin k:=temp_x; temp_x:=dvi_x; dvi_x:=k;
3736  end;
3737dvi_goto(dvi_x,dvi_y+(rule_size[p] div 2));
3738dvi_out(put_rule); dvi_four(rule_size[p]); dvi_four(temp_x-dvi_x);
3739dvi_out(pop);
3740end
3741
3742@ @<Try to output a diagonal rule@>=
3743if (rule_slant=0)or@|
3744 (abs(temp_x+rule_slant*(temp_y-dvi_y)-dvi_x)>rule_size[p]) then
3745  slant_complaint((dvi_x-temp_x)/(temp_y-dvi_y))
3746else  begin if temp_y>dvi_y then
3747    begin k:=temp_y; temp_y:=dvi_y; dvi_y:=k;@/
3748    k:=temp_x; temp_x:=dvi_x; dvi_x:=k;
3749    end;
3750  m:=round((dvi_y-temp_y)/slant_unit);
3751  if m>0 then
3752    begin dvi_goto(dvi_x,dvi_y);
3753    q:=((m-1) div slant_n)+1; k:=m div q;
3754    p:=m mod q; q:=q-p;
3755    @<Vertically typeset |q| copies of character |k|@>;
3756    @<Vertically typeset |p| copies of character |k+1|@>;
3757    dvi_out(pop);
3758    end;
3759  end
3760
3761@ @<Vertically typeset |q| copies of character |k|@>=
3762typeset(k); dy:=round(k*slant_unit); dvi_out(z4); dvi_four(-dy);
3763while q>1 do
3764  begin typeset(k); dvi_out(z0); decr(q);
3765  end
3766
3767@ @<Vertically typeset |p| copies of character |k+1|@>=
3768if p>0 then
3769  begin incr(k); typeset(k);
3770  dy:=round(k*slant_unit); dvi_out(z4); dvi_four(-dy);
3771  while p>1 do
3772    begin typeset(k); dvi_out(z0); decr(p);
3773    end;
3774  end
3775
3776@ Now we come to a more interesting part of the computation, where we
3777go through the stored labels and try to fit them in the illustration for
3778the current character, together with their associated dots.
3779
3780It would simplify font-switching slightly if we were to typeset the labels
3781first, but we find it desirable to typeset the dots first and then turn to the
3782labels. This procedure makes it possible for us to allow the dots to
3783overlap each other without allowing the labels to overlap. After the
3784dots are in place, we typeset all prescribed labels, that is, labels with a
3785|lab_typ| of |"1".."8"|; these, too, are allowed to overlap the dots and
3786each other.
3787
3788@<Output all labels for the current character@>=
3789overflow_line:=1;
3790if label_head<>null then
3791  begin next[label_tail]:=null; select_font(gray_font);
3792  @<Output all dots@>;
3793  @<Find nearest dots, to help in label positioning@>;
3794  select_font(label_font);
3795  @<Output all prescribed labels@>;
3796  @<Output all attachable labels@>;
3797  @<Output all overflow labels@>;
3798  end
3799
3800@ @<Glob...@>=
3801@!overflow_line:integer; {the number of labels that didn't fit, plus~1}
3802
3803@ A label that appears above its dot is considered to occupy a
3804rectangle of height~$h+\Delta$, depth~$d$, and width~$w+2\Delta$, where
3805$(h,w,d)$ are the height, width, and depth of the label computed by |hbox|,
3806and $\Delta$ is an additional amount of blank space that keeps labels from
3807coming too close to each other. (\.{GFtoDVI} arbitrarily defines $\Delta$
3808to be one half the width of a space in the label font.) This label is
3809centered over its dot, with its baseline $d+h'$ above the center of the dot;
3810here $h'=|dot_height|$ is the height of character~0 in the gray font.
3811
3812Similarly, a label that appears below its dot is considered to occupy
3813a rectangle of height~$h$, depth~$d+\Delta$, and width~$w+2\Delta$; the
3814baseline is $h+h'$ below the center of the dot.
3815
3816A label at the right of its dot is considered to occupy a rectangle of
3817height~$h+\Delta$, depth~$d+\Delta$, and width~$w+\Delta$. Its
3818reference point can be found by starting at the center of the dot and
3819moving right $w'=|dot_width|$ (i.e., the width of character~0 in the
3820gray font), then moving down by half the x-height of the label font.
3821A label at the left of its dot is similar.
3822
3823A dot is considered to occupy a rectangle of height $2h'$ and width~$2w'$,
3824centered on the dot.
3825
3826When the label type is |"1"| or more, the labels
3827are put into the doubly linked list unconditionally.
3828 Otherwise they are put into the list
3829only if we can find a way to fit them in without
3830overlapping any previously inserted rectangles.
3831
3832@<Glob...@>=
3833@!delta:scaled; {extra padding to keep labels from being too close}
3834@!half_x_height:scaled; {amount to drop baseline of label below the dot center}
3835@!thrice_x_height:scaled; {baseline separation for overflow labels}
3836@!dot_width,@!dot_height:scaled; {$w'$ and $h'$ in the discussion above}
3837
3838@ @<Initialize global variables that depend on the font data@>=
3839i:=char_info(gray_font)(0);
3840if not char_exists(i) then abort('Missing dot char!');
3841@.Missing dot char@>
3842dot_width:=char_width(gray_font)(i);
3843dot_height:=char_height(gray_font)(height_depth(i));
3844delta:=space(label_font) div 2;
3845thrice_x_height:=3*x_height(label_font);
3846half_x_height:=thrice_x_height div 6;
3847
3848@ Here is a subroutine that computes the rectangle boundaries
3849|xl[p]|, |xr[p]|, |yt[p]|, |yb[p]|, and the reference point coordinates
3850|xx[p]|,~|yy[p]|, for a label that is to be placed above a dot.
3851The coordinates of the dot's center are assumed given in |dvi_x|
3852and |dvi_y|; the |hbox| subroutine is assumed to have
3853already computed the height, width, and depth of the label box.
3854
3855@p procedure top_coords(@!p:node_pointer);
3856begin xx[p]:=dvi_x-(box_width div 2); xl[p]:=xx[p]-delta;
3857xr[p]:=xx[p]+box_width+delta;@/
3858yb[p]:=dvi_y-dot_height; yy[p]:=yb[p]-box_depth;
3859yt[p]:=yy[p]-box_height-delta;
3860end;
3861
3862@ The other three label positions are handled by similar routines.
3863
3864@p procedure bot_coords(@!p:node_pointer);
3865begin xx[p]:=dvi_x-(box_width div 2); xl[p]:=xx[p]-delta;
3866xr[p]:=xx[p]+box_width+delta;@/
3867yt[p]:=dvi_y+dot_height; yy[p]:=yt[p]+box_height;
3868yb[p]:=yy[p]+box_depth+delta;
3869end;
3870@#
3871procedure right_coords(@!p:node_pointer);
3872begin xl[p]:=dvi_x+dot_width; xx[p]:=xl[p]; xr[p]:=xx[p]+box_width+delta;@/
3873yy[p]:=dvi_y+half_x_height; yb[p]:=yy[p]+box_depth+delta;
3874yt[p]:=yy[p]-box_height-delta;
3875end;
3876@#
3877procedure left_coords(@!p:node_pointer);
3878begin xr[p]:=dvi_x-dot_width; xx[p]:=xr[p]-box_width; xl[p]:=xx[p]-delta;@/
3879yy[p]:=dvi_y+half_x_height; yb[p]:=yy[p]+box_depth+delta;
3880yt[p]:=yy[p]-box_height-delta;
3881end;
3882
3883@ @<Output all dots@>=
3884p:=label_head; first_dot:=max_node+1;
3885while p<>null do
3886  begin convert(xx[p],yy[p]); xx[p]:=dvi_x; yy[p]:=dvi_y;
3887  if lab_typ[p]<"5" then
3888    @<Enter a dot for label |p| in the rectangle list,
3889      and typeset the dot@>;
3890  p:=next[p];
3891  end
3892
3893@ We plant links between dots and their labels by using (or abusing) the
3894|xl| and |info| fields, which aren't needed for their normal purposes.
3895
3896@d dot_for_label==xl
3897@d label_for_dot==info
3898
3899@<Enter a dot...@>=
3900begin q:=get_avail; dot_for_label[p]:=q; label_for_dot[q]:=p;@/
3901xx[q]:=dvi_x; xl[q]:=dvi_x-dot_width; xr[q]:=dvi_x+dot_width;@/
3902yy[q]:=dvi_y; yt[q]:=dvi_y-dot_height; yb[q]:=dvi_y+dot_height;@/
3903node_ins(q,0);@/
3904dvi_goto(xx[q],yy[q]); dvi_out(0); dvi_out(pop);
3905end
3906
3907@ Prescribed labels are now taken out of the singly linked list and
3908inserted into the doubly linked list.
3909
3910@<Output all prescribed labels@>=
3911q:=end_of_list; {|label_head=next[q]|}
3912while next[q]<>null do
3913  begin p:=next[q];
3914  if lab_typ[p]>"0" then
3915    begin next[q]:=next[p];
3916    @<Enter a prescribed label for node |p| into the rectangle list,
3917      and typeset it@>;
3918    end
3919  else q:=next[q];
3920  end
3921
3922@ @<Enter a prescr...@>=
3923begin hbox(info[p],label_font,false); {Compute the size of this label}
3924dvi_x:=xx[p];  dvi_y:=yy[p];
3925if lab_typ[p]<"5" then r:=dot_for_label[p]@+else r:=0;
3926case lab_typ[p] of
3927"1","5":top_coords(p);
3928"2","6":left_coords(p);
3929"3","7":right_coords(p);
3930"4","8":bot_coords(p);
3931end; {no other cases are possible}
3932node_ins(p,r);@/
3933dvi_goto(xx[p],yy[p]); hbox(info[p],label_font,true); dvi_out(pop);
3934end
3935
3936@ \.{GFtoDVI}'s algorithm for positioning the ``floating'' labels
3937was devised by Arthur~L. Samuel.
3938@^Samuel, Arthur Lee@>
3939It tries to place labels in a priority order, based on the position of
3940the nearest dot to a given dot. If that dot, for example, lies in the first
3941octant (i.e., east to northeast of the given dot), the given label will
3942be put into the west slot unless that slot is already blocked; then the
3943south slot will be tried, etc.
3944
3945First we need to compute the octants. We also note if two or more dots
3946are nearly coincident, since Samuel's algorithm modifies the priority
3947order on that case. The information is temporarily recorded in the |xr| array.
3948
3949@d octant==xr {octant code for nearest dot, plus 8 for coincident dots}
3950
3951@<Find nearest dots, to help in label positioning@>=
3952p:=label_head;
3953while p<>null do
3954  begin if lab_typ[p]<="0" then
3955    @<Compute the octant code for floating label |p|@>;
3956  p:=next[p];
3957  end;
3958
3959@ There's a sneaky way to identify octant numbers, represented by the
3960code shown here. (Remember that |y|~coordinates increase downward
3961in the \.{DVI} convention.)
3962
3963@d first_octant=0
3964@d second_octant=1
3965@d third_octant=2
3966@d fourth_octant=3
3967@d fifth_octant=7
3968@d sixth_octant=6
3969@d seventh_octant=5
3970@d eighth_octant=4
3971
3972@<Compute the octant code for floating label |p|@>=
3973begin r:=dot_for_label[p]; q:=nearest_dot(r,10);
3974if twin then octant[p]:=8@+else octant[p]:=0;
3975if q<>null then
3976  begin dx:=xx[q]-xx[r]; dy:=yy[q]-yy[r];
3977  if dy>0 then octant[p]:=octant[p]+4;
3978  if dx<0 then incr(octant[p]);
3979  if dy>dx then incr(octant[p]);
3980  if -dy>dx then incr(octant[p]);
3981  end;
3982end
3983
3984@ A procedure called |place_label| will try to place the remaining
3985labels in turn. If it fails, we ``disconnect'' the dot from this
3986label so that an unlabeled dot will not appear as a reference in the
3987overflow column.
3988
3989@<Output all attachable labels@>=
3990q:=end_of_list; {now |next[q]=label_head|}
3991while next[q]<>null do
3992  begin p:=next[q]; r:=next[p]; s:=dot_for_label[p];
3993  if place_label(p) then next[q]:=r
3994  else  begin label_for_dot[s]:=null; {disconnect the dot}
3995    if lab_typ[p]="/" then next[q]:=r {remove label from list}
3996    else q:=p; {retain label in list for the overflow column}
3997    end;
3998  end
3999
4000@ Here is the |place_label| routine, which uses the previously computed
4001|octant| information as a heuristic. If the label can be placed, it
4002is inserted into the rectangle list and typeset.
4003
4004@p function place_label(@!p:node_pointer):boolean;
4005label exit, found;
4006var @!oct:0..15; {octant code}
4007@!dfl:node_pointer; {saved value of |dot_for_label[p]|}
4008begin hbox(info[p],label_font,false); {Compute the size of this label}
4009dvi_x:=xx[p]; dvi_y:=yy[p];
4010@<Find non-overlapping coordinates, if possible, and |goto| found;
4011  otherwise set |place_label:=false| and |return|@>;
4012found:node_ins(p,dfl);@/
4013dvi_goto(xx[p],yy[p]); hbox(info[p],label_font,true); dvi_out(pop);
4014place_label:=true;
4015exit:end;
4016
4017@ @<Find non-overlapping coordinates, if possible...@>=
4018dfl:=dot_for_label[p]; oct:=octant[p];
4019@<Try the first choice for label direction@>;
4020@<Try the second choice for label direction@>;
4021@<Try the third choice for label direction@>;
4022@<Try the fourth choice for label direction@>;
4023xx[p]:=dvi_x;  yy[p]:=dvi_y; dot_for_label[p]:=dfl; {no luck; restore the coordinates}
4024place_label:=false; return
4025
4026@ @<Try the first choice for label direction@>=
4027case oct of
4028first_octant,eighth_octant,second_octant+8,seventh_octant+8: left_coords(p);
4029second_octant,third_octant,first_octant+8,fourth_octant+8: bot_coords(p);
4030fourth_octant,fifth_octant,third_octant+8,sixth_octant+8: right_coords(p);
4031sixth_octant,seventh_octant,fifth_octant+8,eighth_octant+8: top_coords(p);
4032end;
4033if not overlap(p,dfl) then goto found
4034
4035@ @<Try the second choice for label direction@>=
4036case oct of
4037first_octant,fourth_octant,fifth_octant+8,eighth_octant+8: bot_coords(p);
4038second_octant,seventh_octant,third_octant+8,sixth_octant+8: left_coords(p);
4039third_octant,sixth_octant,second_octant+8,seventh_octant+8: right_coords(p);
4040fifth_octant,eighth_octant,first_octant+8,fourth_octant+8: top_coords(p);
4041end;
4042if not overlap(p,dfl) then goto found
4043
4044@ @<Try the third choice for label direction@>=
4045case oct of
4046first_octant,fourth_octant,sixth_octant+8,seventh_octant+8: top_coords(p);
4047second_octant,seventh_octant,fourth_octant+8,fifth_octant+8: right_coords(p);
4048third_octant,sixth_octant,first_octant+8,eighth_octant+8: left_coords(p);
4049fifth_octant,eighth_octant,second_octant+8,third_octant+8: bot_coords(p);
4050end;
4051if not overlap(p,dfl) then goto found
4052
4053@ @<Try the fourth choice for label direction@>=
4054case oct of
4055first_octant,eighth_octant,first_octant+8,eighth_octant+8: right_coords(p);
4056second_octant,third_octant,second_octant+8,third_octant+8: top_coords(p);
4057fourth_octant,fifth_octant,fourth_octant+8,fifth_octant+8: left_coords(p);
4058sixth_octant,seventh_octant,sixth_octant+8,seventh_octant+8: bot_coords(p);
4059end;
4060if not overlap(p,dfl) then goto found
4061
4062@ @<Output all overflow labels@>=
4063@<Remove all rectangles from list, except for dots that have labels@>;
4064p:=label_head;
4065while p<>null do
4066  begin @<Typeset an overflow label for |p|@>;
4067  p:=next[p];
4068  end
4069
4070@ When we remove a dot that couldn't be labeled, we set its |next| field
4071to the preceding node that survives, so that we can use the |nearest_dot|
4072routine later. (This is a bit of a kludge.)
4073
4074@<Remove all rectangles from list, except for dots that have labels@>=
4075p:=next[0];
4076while p<>end_of_list do
4077  begin q:=next[p];
4078  if (p<first_dot) or (label_for_dot[p]=null) then
4079    begin r:=prev[p]; next[r]:=q; prev[q]:=r; next[p]:=r;
4080    end;
4081  p:=q;
4082  end
4083
4084@ Now we have to insert |p| into the list temporarily, because of the
4085way |nearest_dot| works.
4086
4087@<Typeset an overflow label for |p|@>=
4088begin r:=next[dot_for_label[p]]; s:=next[r]; t:=next[p];
4089next[p]:=s; prev[s]:=p; next[r]:=p; prev[p]:=r;@/
4090q:=nearest_dot(p,0);@/
4091next[r]:=s; prev[s]:=r; next[p]:=t; {remove |p| again}
4092incr(overflow_line);
4093dvi_goto(over_col,overflow_line*thrice_x_height+655360);
4094hbox(info[p],label_font,true);
4095if q<>null then
4096  begin hbox(equals_sign,label_font,true);
4097  hbox(info[label_for_dot[q]],label_font,true);
4098  hbox(plus_sign,label_font,true);
4099  dvi_scaled((xx[p]-xx[q])/x_ratio+(yy[p]-yy[q])*fudge_factor);
4100  dvi_out(",");
4101  dvi_scaled((yy[q]-yy[p])/y_ratio);
4102  dvi_out(")");
4103  end;
4104dvi_out(pop);
4105end
4106
4107@ @<Adjust the maximum page width@>=
4108if overflow_line>1 then page_width:=over_col+10000000;
4109  {overflow labels are estimated to occupy $10^7\,$sp}
4110if page_width>max_h then max_h:=page_width
4111
4112@* Doing the pixels.
4113The most interesting part of \.{GFtoDVI} is the way it makes use of a gray
4114font to typeset the pixels of a character. In fact, the author must admit having
4115great fun devising the algorithms below. Perhaps the reader will also
4116enjoy reading them.
4117
4118The basic idea will be to use an array of 12-bit integers to represent the next
4119twelve rows that need to be typeset. The binary expansions of these integers,
4120reading from least significant bit to most significant bit, will represent
4121pixels from top to bottom.
4122
4123@ We have already used such a binary representation in the tables
4124|c[1..120]| and |d[1..120]| of bit patterns and lengths that are potentially
4125present in a gray font; we shall now use those tables to compute
4126an auxiliary array |b[0..4095]|. Given a 12-bit number~$v$, the gray-font
4127character appropriate to $v$'s binary pattern will be~|b[v]|. If no
4128character should be typeset for this pattern in the current row,
4129|b[v]| will be~0.
4130
4131The array |b| can have many different configurations, depending on how
4132many characters are actually present in the gray font. But
4133it's not difficult to compute |b| by going through the existing characters
4134in increasing order and marking all patterns~$x$ to which they apply.
4135
4136@<Initialize glob...@>=
4137for k:=0 to 4095 do b[k]:=0;
4138for k:=font_bc[gray_font] to font_ec[gray_font] do
4139 if k>=1 then if k<=120 then
4140  if char_exists(char_info(gray_font)(k)) then
4141  begin v:=c[k];
4142  repeat b[v]:=k; v:=v+d[k];
4143  until v>4095;
4144  end;
4145
4146@ We also compute an auxiliary array |rho[0..4095]| such that $\\{rho}[v]=2^j$
4147when |v| is an odd multiple of~$2^j$; we also set $\\{rho}[0]=2^{12}$.
4148
4149@<Initialize g...@>=
4150for j:=0 to 11 do
4151  begin k:=two_to_the[j]; v:=k;
4152  repeat rho[v]:=k; v:=v+k+k;
4153  until v>4095;
4154  end;
4155rho[0]:=4096;
4156
4157@ @<Glob...@>=
4158@!b:array[0..4095] of 0..120; {largest existing character for a given pattern}
4159@!rho:array[0..4095] of 1..4096; {the ``ruler function''}
4160
4161@ But how will we use these tables? Let's imagine that the \.{DVI} file
4162already contains instructions that have selected the gray font and moved
4163to the proper horizontal coordinate for the row that we wish to process next.
4164Let's suppose that 12-bit patterns have been set up in array~|a|, and that
4165the global variables |starting_col| and |finishing_col| are known such
4166that |a[j]| is zero unless |starting_col<=j<=finishing_col|. Here's what
4167we can do, assuming that appropriate local variables and labels have
4168been declared:
4169
4170@<Typeset the pixels of the current row@>=
4171j:=starting_col;
4172loop@+  begin while (j<=finishing_col)and(b[a[j]]=0) do incr(j);
4173  if j>finishing_col then goto done;
4174  dvi_out(push); @<Move to column |j| in the \.{DVI} output@>;
4175  repeat v:=b[a[j]]; a[j]:=a[j]-c[v];
4176  k:=j; incr(j);
4177  while b[a[j]]=v do
4178    begin a[j]:=a[j]-c[v]; incr(j);
4179    end;
4180  k:=j-k; @<Output the equivalent of |k| copies of character |v|@>;
4181  until b[a[j]]=0;
4182  dvi_out(pop);
4183  end;
4184done:
4185
4186@ @<Move to column |j| in the \.{DVI} output@>=
4187dvi_out(right4);
4188dvi_four(round(unsc_x_ratio*j+unsc_slant_ratio*y)+delta_x)
4189
4190@ The doubling-up property of gray font character lists is utilized here.
4191
4192@<Output the equivalent of |k| copies of character |v|@>=
4193reswitch: if k=1 then typeset(v)
4194else  begin i:=char_info(gray_font)(v);
4195  if char_tag(i)=list_tag then {|v| has a successor}
4196    begin if odd(k) then typeset(v);
4197    k:=k div 2; v:=qo(rem_byte(i)); goto reswitch;
4198    end
4199  else repeat typeset(v); decr(k);
4200    until k=0;
4201  end
4202
4203@ @<Glob...@>=
4204@!a:array[0..widest_row] of 0..4095; {bit patterns for twelve rows}
4205
4206@ In order to use the approach above, we need to be able to initialize
4207array~|a|, and we need to be able to keep it up to date as new rows
4208scroll by. A moment's thought about the problem reveals that we will either
4209have to read an entire character from the \.{GF} file into memory,
4210or we'll need to adopt a coroutine-like approach: A single \\{skip}
4211command in the \.{GF} file might need to be processed in pieces, since
4212it might generate more rows of zeroes than we are ready to absorb
4213all at once into~|a|.
4214
4215The coroutine method actually turns out to be quite simple, so we shall
4216introduce a global variable |blank_rows|, which tells how many rows of
4217blanks should be generated before we read the \.{GF} instructions
4218for another row.
4219
4220@<Glob...@>=
4221@!blank_rows:integer;
4222  {rows of blanks carried over from a previous \.{GF} command}
4223
4224@ Initialization and updating of~|a| can now be handled as follows,
4225if we introduce another variable~|l| that is set initially to~1:
4226
4227@<Add more rows to |a|, until 12-bit entries are obtained@>=
4228repeat @<Put the bits for the next row, times |l|, into |a|@>;
4229l:=l+l; decr(y);
4230until l=4096;
4231
4232@ As before, |cur_gf| will contain the first \.{GF} command that has
4233not yet been interpreted.
4234
4235@<Put the bits...@>=
4236if blank_rows>0 then decr(blank_rows)
4237else if cur_gf<>eoc then
4238  begin x:=z;
4239  if starting_col>x then starting_col:=x;
4240  @<Read and process \.{GF} commands until coming to the end of this row@>;
4241  end;
4242
4243@ @d do_skip==z:=0; paint_black:=false
4244@d end_with(#)==begin #; cur_gf:=get_byte; goto done1;@+end
4245@d five_cases(#)==#,#+1,#+2,#+3,#+4
4246@d eight_cases(#)==#,#+1,#+2,#+3,#+4,#+5,#+6,#+7
4247@d thirty_two_cases(#)==eight_cases(#),eight_cases(#+8),
4248  eight_cases(#+16), eight_cases(#+24)
4249@d sixty_four_cases(#)==thirty_two_cases(#), thirty_two_cases(#+32)
4250
4251@<Read and process...@>=
4252loop  @+begin continue: case cur_gf of
4253  sixty_four_cases(0): k:=cur_gf;
4254  paint1:k:=get_byte;
4255  paint2:k:=get_two_bytes;
4256  paint3:k:=get_three_bytes;
4257  eoc:goto done1;
4258  skip0:end_with(blank_rows:=0; do_skip);
4259  skip1:end_with(blank_rows:=get_byte; do_skip);
4260  skip2:end_with(blank_rows:=get_two_bytes; do_skip);
4261  skip3:end_with(blank_rows:=get_three_bytes; do_skip);
4262  sixty_four_cases(new_row_0),sixty_four_cases(new_row_0+64),
4263   thirty_two_cases(new_row_0+128),five_cases(new_row_0+160):
4264    end_with(z:=cur_gf-new_row_0;paint_black:=true);
4265  xxx1,xxx2,xxx3,xxx4,yyy,no_op:begin skip_nop; goto continue;
4266    end;
4267  othercases bad_gf('Improper opcode')
4268  endcases;@/
4269  @<Paint |k| bits and read another command@>;
4270  end;
4271done1:
4272
4273@ @<Paint |k| bits and read another command@>=
4274if x+k>finishing_col then finishing_col:=x+k;
4275if paint_black then for j:=x to x+k-1 do a[j]:=a[j]+l;
4276paint_black:=not paint_black;
4277x:=x+k;
4278cur_gf:=get_byte
4279
4280@ When the current row has been typeset, all entries of |a| will be even;
4281we want to divide them by~2 and incorporate a new row with $l=2^{11}$.
4282However, if they are all multiples of~4, we actually want to divide by~4
4283and incorporate two new rows, with $l=2^{10}$ and $l=2^{11}$. In general,
4284we want to divide by the maximum possible power of~2 and add the corresponding
4285number of new rows; that's where the |rho|~array comes in handy:
4286
4287@<Advance to the next row that needs to be typeset;
4288  or |return|, if we're all done@>=
4289l:=rho[a[starting_col]];
4290for j:=starting_col+1 to finishing_col do if l>rho[a[j]] then l:=rho[a[j]];
4291if l=4096 then
4292  if cur_gf=eoc then return
4293  else  begin y:=y-blank_rows; blank_rows:=0; l:=1;
4294    starting_col:=z; finishing_col:=z;
4295    end
4296else  begin while a[starting_col]=0 do incr(starting_col);
4297  while a[finishing_col]=0 do decr(finishing_col);
4298  for j:=starting_col to finishing_col do a[j]:=a[j] div l;
4299  l:=4096 div l;
4300  end
4301
4302@ We now have constructed the major components of the necessary routine;
4303it simply remains to glue them all together in the proper framework.
4304
4305@p procedure do_pixels;
4306label done,done1,reswitch,continue,exit;
4307var @!paint_black:boolean; {the paint switch}
4308@!starting_col,@!finishing_col:0..widest_row; {currently nonzero area}
4309@!j:0..widest_row; {for traversing that area}
4310@!l:integer; {power of two used to manipulate bit patterns}
4311@!i:four_quarters; {character information word}
4312@!v:eight_bits; {character corresponding to a pixel pattern}
4313begin select_font(gray_font);
4314delta_x:=delta_x+round(unsc_x_ratio*min_x);
4315for j:=0 to max_x-min_x do a[j]:=0;
4316l:=1; z:=0; starting_col:=0; finishing_col:=0; y:=max_y+12; paint_black:=false;
4317blank_rows:=0; cur_gf:=get_byte;
4318loop@+  begin @<Add more rows...@>;
4319  dvi_goto(0,delta_y-round(unsc_y_ratio*y)); @<Typeset the pixels...@>;
4320  dvi_out(pop); @<Advance to the next...@>;
4321  end;
4322exit:end;
4323
4324@* The main program.
4325Now we are ready to put it all together. This is where \.{GFtoDVI} starts,
4326and where it ends.
4327
4328@p begin initialize; {get all variables initialized}
4329@<Initialize the strings@>;
4330start_gf; {open the input and output files}
4331@<Process the preamble@>;
4332cur_gf:=get_byte; init_str_ptr:=str_ptr;
4333loop@+  begin @<Initialize variables for the next character@>;
4334  while (cur_gf>=xxx1)and(cur_gf<=no_op) do @<Process a no-op command@>;
4335  if cur_gf=post then @<Finish the \.{DVI} file and |goto final_end|@>;
4336  if cur_gf<>boc then if cur_gf<>boc1 then abort('Missing boc!');
4337@.Missing boc@>
4338  @<Process a character@>;
4339  cur_gf:=get_byte; str_ptr:=init_str_ptr; pool_ptr:=str_start[str_ptr];
4340  end;
4341final_end:end.
4342
4343@ The main program needs a few global variables in order to do its work.
4344
4345@<Glob...@>=
4346@!k,@!m,@!p,@!q,@!r,@!s,@!t,@!dx,@!dy:integer; {general purpose registers}
4347@!time_stamp:str_number; {the date and time when the input file was made}
4348@!use_logo:boolean; {should \MF's logo be put on the title line?}
4349
4350@ \MF\ sets the opening string to 32 bytes that give date and time as follows:
4351$$\hbox{|' METAFONT output yyyy.mm.dd:tttt'|}$$
4352We copy this to the \.{DVI} file, but remove the `\.{METAFONT}' part so that
4353it can be replaced by its proper logo.
4354
4355@<Process the preamble@>=
4356if get_byte<>pre then bad_gf('No preamble');
4357@.No preamble@>
4358if get_byte<>gf_id_byte then bad_gf('Wrong ID');
4359@.Wrong ID@>
4360k:=get_byte; {|k| is the length of the initial string to be copied}
4361for m:=1 to k do append_char(get_byte);
4362dvi_out(pre); dvi_out(dvi_id_byte); {output the preamble}
4363dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp}
4364dvi_four(1000); {magnification factor}
4365dvi_out(k); use_logo:=false; s:=str_start[str_ptr];
4366for m:=1 to k do dvi_out(str_pool[s+m-1]);
4367if str_pool[s]=" " then
4368 if str_pool[s+1]="M" then
4369  if str_pool[s+2]="E" then
4370   if str_pool[s+3]="T" then
4371    if str_pool[s+4]="A" then
4372     if str_pool[s+5]="F" then
4373      if str_pool[s+6]="O" then
4374       if str_pool[s+7]="N" then
4375        if str_pool[s+8]="T" then
4376    begin incr(str_ptr); str_start[str_ptr]:=s+9; use_logo:=true;
4377    end; {we will substitute `\MF' for \.{METAFONT}}
4378time_stamp:=make_string
4379
4380@* System-dependent changes.
4381This section should be replaced, if necessary, by changes to the program
4382that are necessary to make \.{GFtoDVI} work at a particular installation.
4383It is usually best to design your change file so that all changes to
4384previous sections preserve the section numbering; then everybody's version
4385will be consistent with the printed program. More extensive changes,
4386which introduce new sections, can be inserted here; then only the index
4387itself will get a new section number.
4388@^system dependencies@>
4389
4390@* Index.
4391Here is a list of the section numbers where each identifier is used.
4392Cross references to error messages and a few other tidbits of information
4393also appear.
4394