modernc.org/knuth@v0.0.4/web/testdata/ctan.org/tex-archive/systems/knuth/dist/mfware/gftodvi.web (about)

     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    \titlefalse % 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.
    56  The \.{GFtoDVI} utility program reads binary generic font (``\.{GF}'')
    57  files that are produced by font compilers such as \MF, and converts them
    58  into device-independent (``\.{DVI}'') files that can be printed to give
    59  annotated hardcopy proofs of the character shapes. The annotations are
    60  specified by the comparatively simple conventions of plain \MF; i.e.,
    61  there are mechanisms for labeling chosen points and for superimposing
    62  horizontal or vertical rules on the enlarged character shapes.
    63  
    64  The purpose of \.{GFtoDVI} is simply to make proof copies; it does not
    65  exhaustively test the validity of a \.{GF} file, nor do its algorithms
    66  much resemble the algorithms that are typically used to prepare font
    67  descriptions for commercial typesetting equipment. Another program,
    68  \.{GFtype}, is available for validity checking; \.{GFtype} also serves
    69  as a model of programs that convert fonts from \.{GF} format to some
    70  other coding scheme.
    71  
    72  The |banner| string defined here should be changed whenever \.{GFtoDVI}
    73  gets 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
    78  to use extensions; for example, \.{GFtoDVI} must read files whose names
    79  are dynamically specified, and such a task would be impossible in pure \PASCAL.
    80  All places where nonstandard constructions are used have been listed in
    81  the index under ``system dependencies.''
    82  @!@^system dependencies@>
    83  
    84  Another exception to standard \PASCAL\ occurs in the
    85  use of default branches in |case| statements; the conventions
    86  of \.{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,
    94  because their external names
    95  will be determined at run time (e.g., by interpreting the
    96  command line that invokes this program). Error messages and other remarks
    97  are written on the |output| file, which the user may
    98  choose to assign to the terminal if the system permits it.
    99  @^system dependencies@>
   100  
   101  The term |print| is used instead of |write| when this program writes on
   102  the |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);
   109  label @<Labels in the outer block@>@/
   110  const @<Constants in the outer block@>@/
   111  type @<Types in the outer block@>@/
   112  var @<Globals in the outer block@>@/
   113  procedure 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
   127  reduce \.{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
   142  occasional |goto| statements will be meaningful. We insert the label
   143  `|exit|:' just before the `\ignorespaces|end|\unskip' of a procedure in
   144  which we have used the `|return|' statement defined below; the label
   145  `|reswitch|' is occasionally used just prior to a |case|
   146  statement in which some cases change the conditions and we wish to branch
   147  to the newly applicable case.  Loops that are set up with the |loop|
   148  construction 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  
   152  Incidentally, this program never declares a label that isn't actually used,
   153  because 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
   176  that were noticed.
   177  
   178  Such errors might be discovered inside of subroutines inside of subroutines,
   179  so a procedure called |jump_out| has been introduced. This procedure, which
   180  simply transfers control to the label |final_end| at the end of the program,
   181  contains 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;
   189  begin goto final_end;
   190  end;
   191  
   192  @ As in \TeX\ and \MF, this program deals with numeric quantities that
   193  are 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.
   201  Like all programs written with the  \.{WEB} system, \.{GFtoDVI} can be
   202  used with any character set. But it uses ASCII code internally, because
   203  the programming for portable input-output is easier when a fixed internal
   204  code is used. Furthermore, both \.{GF} and \.{DVI} files use ASCII code
   205  for file names and certain other strings.
   206  The next few sections of \.{GFtoDVI} have therefore been copied from the
   207  analogous 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
   213  six-bit character sets were common, so it did not make provision for lowercase
   214  letters. Nowadays, of course, we need to deal with both capital and
   215  small letters in a convenient way.  So we shall assume that the
   216  \PASCAL\ system being used for \.{GFtoDVI} has a character set containing
   217  at least the standard visible ASCII characters (|"!"| through |"~"|). If
   218  additional characters are present, \.{GFtoDVI} can be configured to
   219  work with them too.
   220  
   221  Some \PASCAL\ compilers use the original name |char| for the data type
   222  associated with the characters in text files, while other \PASCAL s
   223  consider |char| to be a 64-element subrange of a larger data type that has
   224  some other name.  In order to accommodate this difference, we shall use
   225  the name |text_char| to stand for the data type of the characters in the
   226  output file.  We shall also assume that |text_char| consists of
   227  the elements |chr(first_text_char)| through |chr(last_text_char)|,
   228  inclusive. 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
   239  the user's external character set by means of arrays |xord| and |xchr|
   240  that 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
   249  all present, the following assignment statements initialize the
   250  |xchr| array properly, without needing any system-dependent changes.
   251  
   252  @<Set init...@>=
   253  xchr[@'40]:=' ';
   254  xchr[@'41]:='!';
   255  xchr[@'42]:='"';
   256  xchr[@'43]:='#';
   257  xchr[@'44]:='$';
   258  xchr[@'45]:='%';
   259  xchr[@'46]:='&';
   260  xchr[@'47]:='''';@/
   261  xchr[@'50]:='(';
   262  xchr[@'51]:=')';
   263  xchr[@'52]:='*';
   264  xchr[@'53]:='+';
   265  xchr[@'54]:=',';
   266  xchr[@'55]:='-';
   267  xchr[@'56]:='.';
   268  xchr[@'57]:='/';@/
   269  xchr[@'60]:='0';
   270  xchr[@'61]:='1';
   271  xchr[@'62]:='2';
   272  xchr[@'63]:='3';
   273  xchr[@'64]:='4';
   274  xchr[@'65]:='5';
   275  xchr[@'66]:='6';
   276  xchr[@'67]:='7';@/
   277  xchr[@'70]:='8';
   278  xchr[@'71]:='9';
   279  xchr[@'72]:=':';
   280  xchr[@'73]:=';';
   281  xchr[@'74]:='<';
   282  xchr[@'75]:='=';
   283  xchr[@'76]:='>';
   284  xchr[@'77]:='?';@/
   285  xchr[@'100]:='@@';
   286  xchr[@'101]:='A';
   287  xchr[@'102]:='B';
   288  xchr[@'103]:='C';
   289  xchr[@'104]:='D';
   290  xchr[@'105]:='E';
   291  xchr[@'106]:='F';
   292  xchr[@'107]:='G';@/
   293  xchr[@'110]:='H';
   294  xchr[@'111]:='I';
   295  xchr[@'112]:='J';
   296  xchr[@'113]:='K';
   297  xchr[@'114]:='L';
   298  xchr[@'115]:='M';
   299  xchr[@'116]:='N';
   300  xchr[@'117]:='O';@/
   301  xchr[@'120]:='P';
   302  xchr[@'121]:='Q';
   303  xchr[@'122]:='R';
   304  xchr[@'123]:='S';
   305  xchr[@'124]:='T';
   306  xchr[@'125]:='U';
   307  xchr[@'126]:='V';
   308  xchr[@'127]:='W';@/
   309  xchr[@'130]:='X';
   310  xchr[@'131]:='Y';
   311  xchr[@'132]:='Z';
   312  xchr[@'133]:='[';
   313  xchr[@'134]:='\';
   314  xchr[@'135]:=']';
   315  xchr[@'136]:='^';
   316  xchr[@'137]:='_';@/
   317  xchr[@'140]:='`';
   318  xchr[@'141]:='a';
   319  xchr[@'142]:='b';
   320  xchr[@'143]:='c';
   321  xchr[@'144]:='d';
   322  xchr[@'145]:='e';
   323  xchr[@'146]:='f';
   324  xchr[@'147]:='g';@/
   325  xchr[@'150]:='h';
   326  xchr[@'151]:='i';
   327  xchr[@'152]:='j';
   328  xchr[@'153]:='k';
   329  xchr[@'154]:='l';
   330  xchr[@'155]:='m';
   331  xchr[@'156]:='n';
   332  xchr[@'157]:='o';@/
   333  xchr[@'160]:='p';
   334  xchr[@'161]:='q';
   335  xchr[@'162]:='r';
   336  xchr[@'163]:='s';
   337  xchr[@'164]:='t';
   338  xchr[@'165]:='u';
   339  xchr[@'166]:='v';
   340  xchr[@'167]:='w';@/
   341  xchr[@'170]:='x';
   342  xchr[@'171]:='y';
   343  xchr[@'172]:='z';
   344  xchr[@'173]:='{';
   345  xchr[@'174]:='|';
   346  xchr[@'175]:='}';
   347  xchr[@'176]:='~';
   348  
   349  @ Here now is the system-dependent part of the character set.
   350  If \.{GFtoDVI} is being implemented on a garden-variety \PASCAL\ for which
   351  only standard ASCII codes will appear in the input and output files, you
   352  don't need to make any changes here. But if you have, for example, an extended
   353  character set like the one in Appendix~C of {\sl The \TeX book}, the first
   354  line 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...@>=
   360  for i:=0 to @'37 do xchr[i]:='?';
   361  for i:=@'177 to @'377 do xchr[i]:='?';
   362  
   363  @ The following system-independent code makes the |xord| array contain a
   364  suitable inverse to the information in |xchr|.
   365  
   366  @<Set init...@>=
   367  for i:=first_text_char to last_text_char do xord[chr(i)]:=" ";
   368  for i:=1 to @'377 do xord[xchr[i]]:=i;
   369  xord['?']:="?";
   370  
   371  @ The |input_ln| routine waits for the user to type a line at his or her
   372  terminal; then it puts ASCII-code equivalents for the characters on that line
   373  into the |buffer| array. The |term_in| file is used for terminal input.
   374  @^system dependencies@>
   375  
   376  Since the terminal is being used for both input and output, some systems
   377  need a special routine to make sure that the user can see a prompt message
   378  before waiting for input based on that message. (Otherwise the message
   379  may just be sitting in a hidden buffer somewhere, and the user will have
   380  no idea what the program is waiting for.) We shall call a system-dependent
   381  subroutine |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
   390  the line just read.
   391  @^system dependencies@>
   392  
   393  @p procedure input_ln; {inputs a line from the terminal}
   394  begin update_terminal; reset(term_in);
   395  if eoln(term_in) then read_ln(term_in);
   396  line_length:=0;
   397  while (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;
   400  end;
   401  
   402  @ The global variable |buf_ptr| is used while scanning each line of input;
   403  it 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.
   410  Before we get into the details of \.{GFtoDVI}, we need to know exactly
   411  what \.{DVI} files are. The form of such files was designed by David R.
   412  @^Fuchs, David Raymond@>
   413  Fuchs in 1979. Almost any reasonable typesetting device can be driven by
   414  a program that takes \.{DVI} files as input, and dozens of such
   415  \.{DVI}-to-whatever programs have been written. Thus, it is possible to
   416  print the output of document compilers like \TeX\ on many different kinds
   417  of equipment. (The following material has been copied almost verbatim from the
   418  program for \TeX.)
   419  
   420  A \.{DVI} file is a stream of 8-bit bytes, which may be regarded as a
   421  series of commands in a machine-like language. The first byte of each command
   422  is the operation code, and this code is followed by zero or more bytes
   423  that provide parameters to the command. The parameters themselves may consist
   424  of several consecutive bytes; for example, the `|set_rule|' command has two
   425  parameters, each of which is four bytes long. Parameters are usually
   426  regarded as nonnegative integers; but four-byte-long parameters,
   427  and shorter parameters that denote distances, can be
   428  either positive or negative. Such parameters are given in two's complement
   429  notation. For example, a two-byte-long distance parameter has a value between
   430  $-2^{15}$ and $2^{15}-1$.
   431  @.DVI {\rm files}@>
   432  
   433  Incidentally, when two or more 8-bit bytes are combined to form an integer of
   434  16 or more bits, the most significant bytes appear first in the file.
   435  This is called BigEndian order.
   436  @^BigEndian order@>
   437  
   438  A \.{DVI} file consists of a ``preamble,'' followed by a sequence of one
   439  or more ``pages,'' followed by a ``postamble.'' The preamble is simply a
   440  |pre| command, with its parameters that define the dimensions used in the
   441  file; this must come first.  Each ``page'' consists of a |bop| command,
   442  followed by any number of other commands that tell where characters are to
   443  be placed on a physical page, followed by an |eop| command. The pages
   444  appear in the order that they were generated, not in any particular
   445  numerical order. If we ignore |nop| commands and \\{fnt\_def} commands
   446  (which are allowed between any two commands in the file), each |eop|
   447  command is immediately followed by a |bop| command, or by a |post|
   448  command; in the latter case, there are no more pages in the file, and the
   449  remaining bytes form the postamble.  Further details about the postamble
   450  will be explained later.
   451  
   452  Some parameters in \.{DVI} commands are ``pointers.'' These are four-byte
   453  quantities that give the location number of some other byte in the file;
   454  the first byte is number~0, then comes number~1, and so on. For example,
   455  one of the parameters of a |bop| command points to the previous |bop|;
   456  this makes it feasible to read the pages in backwards order, in case the
   457  results are being directed to a device that stacks its output face up.
   458  Suppose the preamble of a \.{DVI} file occupies bytes 0 to 99. Now if the
   459  first page occupies bytes 100 to 999, say, and if the second
   460  page occupies bytes 1000 to 1999, then the |bop| that starts in byte 1000
   461  points to 100 and the |bop| that starts in byte 2000 points to 1000. (The
   462  very 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
   465  by a machine. Compactness is achieved by making most of the information
   466  implicit instead of explicit. When a \.{DVI}-reading program reads the
   467  commands for a page, it keeps track of several quantities: (a)~The current
   468  font |f| is an integer; this value is changed only
   469  by \\{fnt} and \\{fnt\_num} commands. (b)~The current position on the page
   470  is 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;
   472  moving to the right corresponds to increasing the horizontal coordinate, and
   473  moving down corresponds to increasing the vertical coordinate. Thus, the
   474  coordinates are essentially Cartesian, except that vertical directions are
   475  flipped; the Cartesian version of |(h,v)| would be |(h,-v)|.  (c)~The
   476  current spacing amounts are given by four numbers |w|, |x|, |y|, and |z|,
   477  where |w| and~|x| are used for horizontal spacing and where |y| and~|z|
   478  are 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
   480  change the current level of operation. Note that the current font~|f| is
   481  not pushed and popped; the stack contains only information about
   482  positioning.
   483  
   484  The values of |h|, |v|, |w|, |x|, |y|, and |z| are signed integers having up
   485  to 32 bits, including the sign. Since they represent physical distances,
   486  there is a small unit of measurement such that increasing |h| by~1 means
   487  moving a certain tiny distance to the right. The actual unit of
   488  measurement is variable, as explained below.
   489  
   490  @ Here is a list of all the commands that may appear in a \.{DVI} file. Each
   491  command 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
   493  by 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|
   497  such that the reference point of the character is at |(h,v)|. Then
   498  increase |h| by the width of that character. Note that a character may
   499  have zero or negative width, so one cannot be sure that |h| will advance
   500  after this command; but |h| usually does increase.
   501  
   502  \yskip\hang|set_char_1| through |set_char_127| (opcodes 1 to 127).
   503  Do the operations of |set_char_0|; but use the character whose number
   504  matches the opcode, instead of character~0.
   505  
   506  \yskip\hang|set1| 128 |c[1]|. Same as |set_char_0|, except that character
   507  number~|c| is typeset. \TeX82 uses this command for characters in the
   508  range |128<=c<256|.
   509  
   510  \yskip\hang|set2| 129 |c[2]|. Same as |set1|, except that |c|~is two
   511  bytes 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
   514  bytes long, so it can be as large as $2^{24}-1$. Not even the Chinese
   515  language has this many characters, but this command might prove useful
   516  in some yet unforeseen way.
   517  
   518  \yskip\hang|set4| 131 |c[4]|. Same as |set1|, except that |c|~is four
   519  bytes long, possibly even negative. Imagine that.
   520  
   521  \yskip\hang|set_rule| 132 |a[4]| |b[4]|. Typeset a solid black rectangle
   522  of height |a| and width |b|, with its bottom left corner at |(h,v)|. Then
   523  set |h:=h+b|. If either |a<=0| or |b<=0|, nothing should be typeset. Note
   524  that 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|
   527  such that the reference point of the character is at |(h,v)|. (The `put'
   528  commands are exactly like the `set' commands, except that they simply put out a
   529  character 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
   541  may occur between \.{DVI} commands, but a |nop| cannot be inserted between
   542  a 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
   545  of a page: Set |(h,v,w,x,y,z):=(0,0,0,0,0,0)| and set the stack empty. Set
   546  the current font |f| to an undefined value.  The ten $c_i$ parameters can
   547  be used to identify pages, if a user wants to print only part of a \.{DVI}
   548  file; \TeX82 gives them the values of \.{\\count0} $\ldots$ \.{\\count9}
   549  at the time \.{\\shipout} was invoked for this page.  The parameter |p|
   550  points to the previous |bop| command in the file, where the first |bop|
   551  has $p=-1$.
   552  
   553  \yskip\hang|eop| 140.  End of page: Print what you have read since the
   554  previous |bop|. At this point the stack should be empty. (The \.{DVI}-reading
   555  programs that drive most output devices will have kept a buffer of the
   556  material that appears on the page that has just ended. This material is
   557  largely, 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
   559  appropriate 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
   562  top of the stack; do not change any of these values. Note that |f| is
   563  not pushed.
   564  
   565  \yskip\hang|pop| 142. Pop the top six values off of the stack and assign
   566  them to |(h,v,w,x,y,z)|. The number of pops should never exceed the number
   567  of pushes, since it would be highly embarrassing if the stack were empty
   568  at the time of a |pop| command.
   569  
   570  \yskip\hang|right1| 143 |b[1]|. Set |h:=h+b|, i.e., move right |b| units.
   571  The parameter is a signed number in two's complement notation, |-128<=b<128|;
   572  if |b<0|, the reference point actually moves left.
   573  
   574  \yskip\hang|right2| 144 |b[2]|. Same as |right1|, except that |b| is a
   575  two-byte quantity in the range |-32768<=b<32768|.
   576  
   577  \yskip\hang|right3| 145 |b[3]|. Same as |right1|, except that |b| is a
   578  three-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
   581  four-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,
   584  this parameterless command will usually suffice, because the same kind of motion
   585  will 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
   589  signed quantity in two's complement notation, |-128<=b<128|. This command
   590  changes 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
   593  parameter, |-32768<=b<32768|.
   594  
   595  \yskip\hang|w3| 150 |b[3]|. Same as |w1|, but |b| is a three-byte-long
   596  parameter, |@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
   599  parameter, |@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|'
   602  commands are like the `|w|' commands except that they involve |x| instead
   603  of |w|.
   604  
   605  \yskip\hang|x1| 153 |b[1]|. Set |x:=b| and |h:=h+b|. The value of |b| is a
   606  signed quantity in two's complement notation, |-128<=b<128|. This command
   607  changes 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
   610  parameter, |-32768<=b<32768|.
   611  
   612  \yskip\hang|x3| 155 |b[3]|. Same as |x1|, but |b| is a three-byte-long
   613  parameter, |@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
   616  parameter, |@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.
   619  The parameter is a signed number in two's complement notation, |-128<=a<128|;
   620  if |a<0|, the reference point actually moves up.
   621  
   622  \yskip\hang|down2| 158 |a[2]|. Same as |down1|, except that |a| is a
   623  two-byte quantity in the range |-32768<=a<32768|.
   624  
   625  \yskip\hang|down3| 159 |a[3]|. Same as |down1|, except that |a| is a
   626  three-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
   629  four-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,
   632  this parameterless command will usually suffice, because the same kind of motion
   633  will 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
   637  signed quantity in two's complement notation, |-128<=a<128|. This command
   638  changes 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
   641  parameter, |-32768<=a<32768|.
   642  
   643  \yskip\hang|y3| 164 |a[3]|. Same as |y1|, but |a| is a three-byte-long
   644  parameter, |@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
   647  parameter, |@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
   650  are 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
   653  signed quantity in two's complement notation, |-128<=a<128|. This command
   654  changes 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
   657  parameter, |-32768<=a<32768|.
   658  
   659  \yskip\hang|z3| 169 |a[3]|. Same as |z1|, but |a| is a three-byte-long
   660  parameter, |@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
   663  parameter, |@t$-2^{31}$@><=a<@t$2^{31}$@>|.
   664  
   665  \yskip\hang|fnt_num_0| 171. Set |f:=0|. Font 0 must previously have been
   666  defined 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
   672  numbers in the range |64<=k<256|.
   673  
   674  \yskip\hang|fnt2| 236 |k[2]|. Same as |fnt1|, except that |k|~is two
   675  bytes long, so it is in the range |0<=k<65536|. \TeX82 never generates this
   676  command, but large font numbers may prove useful for specifications of
   677  color or texture, or they may be used for special fonts that have fixed
   678  numbers in some external coding scheme.
   679  
   680  \yskip\hang|fnt3| 237 |k[3]|. Same as |fnt1|, except that |k|~is three
   681  bytes 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
   684  bytes 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
   687  general; it functions as a $(k+2)$-byte |nop| unless special \.{DVI}-reading
   688  programs are being used. \TeX82 generates |xxx1| when a short enough
   689  \.{\\special} appears, setting |k| to the number of bytes being sent. It
   690  is recommended that |x| be a string having the form of a keyword followed
   691  by 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
   698  large. \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]|.
   701  Define 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]|.
   704  Define 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]|.
   707  Define 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]|.
   710  Define 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]|.
   713  Beginning of the preamble; this must come at the very beginning of the
   714  file. 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
   741  stated above, there are six parameters:
   742  $$\hbox{|@!i[1]| |@!num[4]| |@!den[4]| |@!mag[4]| |@!k[1]| |@!x[k]|.}$$
   743  The |i| byte identifies \.{DVI} format; currently this byte is always set
   744  to~2. (The value |i=3| is currently used for an extended format that
   745  allows a mixture of right-to-left and left-to-right typesetting.
   746  Some day we will set |i=4|, when \.{DVI} format makes another
   747  incompatible change---perhaps in the year 2048.)
   748  
   749  The next two parameters, |num| and |den|, are positive integers that define
   750  the units of measurement; they are the numerator and denominator of a
   751  fraction by which all dimensions in the \.{DVI} file could be multiplied
   752  in order to get lengths in units of $10^{-7}$ meters. (For example, there are
   753  exactly 7227 \TeX\ points in 254 centimeters, and \TeX82 works with scaled
   754  points where there are $2^{16}$ sp in a point, so \TeX82 sets |num=25400000|
   755  and $|den|=7227\cdot2^{16}=473628672$.)
   756  @^sp@>
   757  
   758  The |mag| parameter is what \TeX82 calls \.{\\mag}, i.e., 1000 times the
   759  desired magnification. The actual fraction by which dimensions are
   760  multiplied is therefore $|mag|\cdot|num|/1000|den|$. Note that if a \TeX\
   761  source document does not call for any `\.{true}' dimensions, and if you
   762  change it only by specifying a different \.{\\mag} setting, the \.{DVI}
   763  file that \TeX\ creates will be completely unchanged except for the value
   764  of |mag| in the preamble and postamble. (Fancy \.{DVI}-reading programs allow
   765  users to override the |mag|~setting when a \.{DVI} file is being printed.)
   766  
   767  Finally, |k| and |x| allow the \.{DVI} writer to include a comment, which is not
   768  interpreted 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]|.}$$
   774  The four-byte value |c| is the check sum that \TeX\ (or whatever program
   775  generated 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
   777  this \.{DVI} file.
   778  @^check sum@>
   779  
   780  Parameter |s| contains a fixed-point scale factor that is applied to the
   781  character widths in font |k|; font dimensions in \.{TFM} files and other
   782  font files are relative to this quantity, which is always positive and
   783  less than $2^{27}$. It is given in the same units as the other dimensions
   784  of the \.{DVI} file.  Parameter |d| is similar to |s|; it is the ``design
   785  size,'' and (like~|s|) it is given in \.{DVI} units. Thus, font |k| is to be
   786  used at $|mag|\cdot s/1000d$ times its normal size.
   787  
   788  The remaining part of a font definition gives the external name of the font,
   789  which is an ASCII string of length |a+l|. The number |a| is the length
   790  of the ``area'' or directory, and |l| is the length of the font name itself;
   791  the standard local system font area is supposed to be used when |a=0|.
   792  The |n| field contains the area in its first |a| bytes.
   793  
   794  Font definitions must appear before the first use of a particular font number.
   795  Once font |k| is defined, it must not be defined again; however, we
   796  shall see below that font definitions appear in the postamble as well as
   797  in the pages, so in this sense each font number is defined exactly twice,
   798  if at all. Like |nop| commands, font definitions can
   799  appear 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
   802  introduces the postamble, which summarizes important facts that \TeX\ has
   803  accumulated about the file, making it possible to print subsets of the data
   804  with 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}}$$
   809  Here |p| is a pointer to the final |bop| in the file. The next three
   810  parameters, |num|, |den|, and |mag|, are duplicates of the quantities that
   811  appeared in the preamble.
   812  
   813  Parameters |l| and |u| give respectively the height-plus-depth of the tallest
   814  page and the width of the widest page, in the same units as other dimensions
   815  of the file. These numbers might be used by a \.{DVI}-reading program to
   816  position individual ``pages'' on large sheets of film or paper; however,
   817  the standard convention for output on normal size paper is to position each
   818  page so that the upper left-hand corner is exactly one inch from the left
   819  and the top. Experience has shown that it is unwise to design \.{DVI}-to-printer
   820  software that attempts cleverly to center the output; a fixed position of
   821  the upper left corner is easiest for users to understand and to work with.
   822  Therefore |l| and~|u| are often ignored.
   823  
   824  Parameter |s| is the maximum stack depth (i.e., the largest excess of
   825  |push| commands over |pop| commands) needed to process this file. Then
   826  comes |t|, the total number of pages (|bop| commands) present.
   827  
   828  The postamble continues with font definitions, which are any number of
   829  \\{fnt\_def} commands as described above, possibly interspersed with |nop|
   830  commands. Each font number that is used in the \.{DVI} file must be defined
   831  exactly twice: Once before it is first selected by a \\{fnt} command, and once
   832  in the postamble.
   833  
   834  @ The last part of the postamble, following the |post_post| byte that
   835  signifies the end of the font definitions, contains |q|, a pointer to the
   836  |post| command that started the postamble.  An identification byte, |i|,
   837  comes next; this currently equals~2, as in the preamble.
   838  
   839  The |i| byte is followed by four or more bytes that are all equal to
   840  the decimal number 223 (i.e., @'337 in octal). \TeX\ puts out four to seven of
   841  these trailing bytes, until the total length of the file is a multiple of
   842  four bytes, since this works out best on machines that pack four bytes per
   843  word; but any number of 223's is allowed, as long as there are at least four
   844  of them. In effect, 223 is a sort of signature that is added at the very end.
   845  @^Fuchs, David Raymond@>
   846  
   847  This curious way to finish off a \.{DVI} file makes it feasible for
   848  \.{DVI}-reading programs to find the postamble first, on most computers,
   849  even though \TeX\ wants to write the postamble last. Most operating
   850  systems permit random access to individual words or bytes of a file, so
   851  the \.{DVI} reader can start at the end and skip backwards over the 223's
   852  until 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,
   854  contain the value 248 (|post|); now the postamble can be read, so the
   855  \.{DVI} reader can discover all the information needed for typesetting the
   856  pages. Note that it is also possible to skip through the \.{DVI} file at
   857  reasonably high speed to locate a particular page, if that proves
   858  desirable. This saves a lot of time, since \.{DVI} files used in production
   859  jobs tend to be large.
   860  
   861  Unfortunately, however, standard \PASCAL\ does not include the ability to
   862  @^system dependencies@>
   863  access a random position in a file, or even to determine the length of a file.
   864  Almost all systems nowadays provide the necessary capabilities, so \.{DVI}
   865  format has been designed to work most efficiently with modern operating systems.
   866  
   867  @* Generic font file format.
   868  The ``generic font'' (\.{GF}) input files that \.{GFtoDVI} must deal with
   869  have a structure that was inspired by \.{DVI} format, although the
   870  operation codes are quite different in most cases.  The term {\sl
   871  generic\/} indicates that this file format doesn't match the conventions
   872  of any name-brand manufacturer; but it is easy to convert \.{GF} files to
   873  the special format required by almost all digital phototypesetting
   874  equipment. 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
   876  notice that many of the paragraphs below are identical to their
   877  counterparts in the description of \.{DVI} already given. The following
   878  description has been lifted almost verbatim from the program for \MF.
   879  
   880  A \.{GF} file is a stream of 8-bit bytes that may be
   881  regarded as a series of commands in a machine-like language. The first
   882  byte of each command is the operation code, and this code is followed by
   883  zero or more bytes that provide parameters to the command. The parameters
   884  themselves may consist of several consecutive bytes; for example, the
   885  `|boc|' (beginning of character) command has six parameters, each of
   886  which is four bytes long. Parameters are usually regarded as nonnegative
   887  integers; but four-byte-long parameters can be either positive or
   888  negative, hence they range in value from $-2^{31}$ to $2^{31}-1$.
   889  As in \.{DVI} files, numbers that occupy
   890  more than one byte position appear in BigEndian order,
   891  and negative numbers appear in two's complement notation.
   892  
   893  A \.{GF} file consists of a ``preamble,'' followed by a sequence of one or
   894  more ``characters,'' followed by a ``postamble.'' The preamble is simply a
   895  |pre| command, with its parameters that introduce the file; this must come
   896  first.  Each ``character'' consists of a |boc| command, followed by any
   897  number of other commands that specify ``black'' pixels,
   898  followed by an |eoc| command. The characters appear in the order that \MF\
   899  generated them. If we ignore no-op commands (which are allowed between any
   900  two 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
   902  more characters in the file, and the remaining bytes form the postamble.
   903  Further details about the postamble will be explained later.
   904  
   905  Some parameters in \.{GF} commands are ``pointers.'' These are four-byte
   906  quantities that give the location number of some other byte in the file;
   907  the 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
   910  by a machine. Compactness is achieved by making most of the information
   911  relative instead of absolute. When a \.{GF}-reading program reads the
   912  commands for a character, it keeps track of two quantities: (a)~the current
   913  column number,~|m|; and (b)~the current row number,~|n|.  These are 32-bit
   914  signed integers, although most actual font formats produced from \.{GF}
   915  files will need to curtail this vast range because of practical
   916  limitations. (\MF\ output will never allow $\vert m\vert$ or $\vert
   917  n\vert$ to get extremely large, but the \.{GF} format tries to be more general.)
   918  
   919  How do \.{GF}'s row and column numbers correspond to the conventions
   920  of \TeX\ and \MF? Well, the ``reference point'' of a character, in \TeX's
   921  view, is considered to be at the lower left corner of the pixel in row~0
   922  and column~0. This point is the intersection of the baseline with the left
   923  edge of the type; it corresponds to location $(0,0)$ in \MF\ programs.
   924  Thus the pixel in \.{GF} row~0 and column~0 is \MF's unit square, comprising the
   925  region of the plane whose coordinates both lie between 0 and~1. The
   926  pixel in \.{GF} row~|n| and column~|m| consists of the points whose \MF\
   927  coordinates |(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
   929  point; negative values of |n| and~|y| correspond to rows of pixels {\sl
   930  below\/} the baseline.
   931  
   932  Besides |m| and |n|, there's also a third aspect of the current
   933  state, namely the @!|paint_switch|, which is always either \\{black} or
   934  \\{white}. Each \\{paint} command advances |m| by a specified amount~|d|,
   935  and blackens the intervening pixels if |paint_switch=black|; then
   936  the |paint_switch| changes to the opposite state. \.{GF}'s commands are
   937  designed so that |m| will never decrease within a row, and |n| will never
   938  increase within a character; hence there is no way to whiten a pixel that
   939  has been blackened.
   940  
   941  @ Here is a list of all the commands that may appear in a \.{GF} file. Each
   942  command 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
   944  by 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
   948  nothing 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).
   951  These are \\{paint} commands with |d=1| to~63, defined as follows: If
   952  |paint_switch=black|, blacken |d|~pixels of the current row~|n|,
   953  in columns |m| through |m+d-1| inclusive. Then, in any case,
   954  complement the |paint_switch| and advance |m| by~|d|.
   955  
   956  \yskip\hang|paint1| 64 |d[1]|. This is a \\{paint} command with a specified
   957  value 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
   960  as~65535.
   961  
   962  \yskip\hang|paint3| 66 |d[3]|. Same as |paint1|, but |d|~can be as high
   963  as $2^{24}-1$. \MF\ never needs this command, and it is hard to imagine
   964  anybody making practical use of it; surely a more compact encoding will be
   965  desirable when characters can be this large. But the command is there,
   966  anyway, 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
   971  this code number modulo 256.  (The pointer |p| is |-1| if there was no
   972  prior character with an equivalent code.) The values of registers |m| and |n|
   973  defined by the instructions that follow for this character must
   974  satisfy |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
   976  program sees a |boc|, it can use |min_m|, |max_m|, |min_n|, and |max_n| to
   977  initialize 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]|.
   981  Same as |boc|, but |p| is assumed to be~$-1$; also |del_m=max_m-min_m|
   982  and |del_n=max_n-min_n| are given instead of |min_m| and |min_n|.
   983  The 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
   987  constitute the pattern for this character. In particular, a completely
   988  blank 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,
   992  ready 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
   998  as 65535.
   999  
  1000  \yskip\hang|skip3| 73 |d[3]|. Same as |skip1|, but |d| can be as large
  1001  as $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,
  1005  ready 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
  1011  general; it functions as a $(k+2)$-byte |no_op| unless special \.{GF}-reading
  1012  programs are being used. \MF\ generates \\{xxx} commands when encountering
  1013  a \&{special} string; this occurs in the \.{GF} file only between
  1014  characters, after the preamble, and before the postamble. However,
  1015  \\{xxx} commands might appear within characters,
  1016  in \.{GF} files generated by other
  1017  processors. It is recommended that |x| be a string having the form of a
  1018  keyword 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
  1026  ridiculously large; |k| mustn't be negative.
  1027  
  1028  \yskip\hang|yyy| 243 |y[4]|. This command is undefined in general;
  1029  it functions as a 5-byte |no_op| unless special \.{GF}-reading programs
  1030  are being used. \MF\ puts |scaled| numbers into |yyy|'s, as a
  1031  result of \&{numspecial} commands; the intent is to provide numeric
  1032  parameters to \\{xxx} commands that immediately precede.
  1033  
  1034  \yskip\hang|no_op| 244. No operation, do nothing. Any number of |no_op|'s
  1035  may occur between \.{GF} commands, but a |no_op| cannot be inserted between
  1036  a 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]|.
  1039  This 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]|.
  1042  Same as |char_loc|, except that |dy| is assumed to be zero, and the value
  1043  of~|dx| is taken to be |65536*dm|, where |0<=dm<256|.
  1044  
  1045  \yskip\hang|pre| 247 |i[1]| |k[1]| |x[k]|.
  1046  Beginning of the preamble; this must come at the very beginning of the
  1047  file. Parameter |i| is an identifying number for \.{GF} format, currently
  1048  131. The other information is merely commentary; it is not given
  1049  special interpretation like \\{xxx} commands are. (Note that \\{xxx}
  1050  commands 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
  1083  introduces the postamble, which summarizes important facts that \MF\ has
  1084  accumulated. 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}}$$
  1090  Here |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);
  1092  it can be used to locate the beginning of \\{xxx} commands
  1093  that might have preceded the postamble. The |ds| and |cs| parameters
  1094  @^design size@> @^check sum@>
  1095  give the design size and check sum, respectively, of the font (see the
  1096  description of \.{TFM} format below).
  1097  Parameters |hppp| and |vppp| are the ratios of
  1098  pixels per point, horizontally and vertically, expressed as |scaled| integers
  1099  (i.e., multiplied by $2^{16}$); they can be used to correlate the font
  1100  with specific device resolutions, magnifications, and ``at sizes.''  Then
  1101  come |min_m|, |max_m|, |min_n|, and |max_n|, which bound the values that
  1102  registers |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
  1104  other hand, be tighter than the similar bounds in |boc| commands. For
  1105  example, some character may have |min_n=-100| in its |boc|, but it might
  1106  turn 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,
  1108  it's possible to have |min_m>max_m| and/or |min_n>max_n|.)
  1109  
  1110  @ Character locators are introduced by |char_loc| commands,
  1111  which specify a character residue~|c|, character escapements (|dx,dy|),
  1112  a character width~|w|, and a pointer~|p|
  1113  to the beginning of that character. (If two or more characters have the
  1114  same code~|c| modulo 256, only the last will be indicated; the others can be
  1115  located by following backpointers. Characters whose codes differ by a
  1116  multiple of 256 are assumed to share the same font metric information,
  1117  hence the \.{TFM} file contains only residues of character codes modulo~256.
  1118  This convention is intended for oriental languages, when there are many
  1119  character shapes but few distinct widths.)
  1120  @^oriental characters@>@^Chinese characters@>@^Japanese characters@>
  1121  
  1122  The character escapements (|dx,dy|) are the values of \MF's \&{chardx}
  1123  and \&{chardy} parameters; they are in units of |scaled| pixels;
  1124  i.e., |dx| is in horizontal pixel units times $2^{16}$, and |dy| is in
  1125  vertical pixel units times $2^{16}$.  This is the intended amount of
  1126  displacement after typesetting the character; for \.{DVI} files, |dy|
  1127  should be zero, but other document file formats allow nonzero vertical
  1128  escapement.
  1129  
  1130  The character width~|w| duplicates the information in the \.{TFM} file; it
  1131  is $2^{20}$ times the ratio of the true width to the font's design size.
  1132  
  1133  The backpointer |p| points to the character's |boc|, or to the first of
  1134  a sequence of consecutive \\{xxx} or |yyy| or |no_op| commands that
  1135  immediately precede the |boc|, if such commands exist; such ``special''
  1136  commands essentially belong to the characters, while the special commands
  1137  after the final character belong to the postamble (i.e., to the font
  1138  as a whole). This convention about |p| applies also to the backpointers
  1139  in |boc| commands, even though it wasn't explained in the description
  1140  of~|boc|. @^backpointers@>
  1141  
  1142  Pointer |p| might be |-1| if the character exists in the \.{TFM} file
  1143  but not in the \.{GF} file. This unusual situation can arise in \MF\ output
  1144  if the user had |proofing<0| when the character was being shipped out,
  1145  but 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
  1148  signifies the end of the character locators, contains |q|, a pointer to the
  1149  |post| command that started the postamble.  An identification byte, |i|,
  1150  comes next; this currently equals~131, as in the preamble.
  1151  
  1152  The |i| byte is followed by four or more bytes that are all equal to
  1153  the decimal number 223 (i.e., @'337 in octal). \MF\ puts out four to seven of
  1154  these trailing bytes, until the total length of the file is a multiple of
  1155  four bytes, since this works out best on machines that pack four bytes per
  1156  word; but any number of 223's is allowed, as long as there are at least four
  1157  of them. In effect, 223 is a sort of signature that is added at the very end.
  1158  @^Fuchs, David Raymond@>
  1159  
  1160  This curious way to finish off a \.{GF} file makes it feasible for
  1161  \.{GF}-reading programs to find the postamble first, on most computers,
  1162  even though \MF\ wants to write the postamble last. Most operating
  1163  systems permit random access to individual words or bytes of a file, so
  1164  the \.{GF} reader can start at the end and skip backwards over the 223's
  1165  until 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,
  1167  contain 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  
  1170  Unfortunately, however, standard \PASCAL\ does not include the ability to
  1171  @^system dependencies@>
  1172  access a random position in a file, or even to determine the length of a file.
  1173  Almost all systems nowadays provide the necessary capabilities, so \.{GF}
  1174  format has been designed to work most efficiently with modern operating systems.
  1175  But 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
  1177  be adequate for most applications. However, the postamble-first approach
  1178  would facilitate a program that merges two \.{GF} files, replacing data
  1179  from one that is overridden by corresponding data in the other.
  1180  
  1181  @* Extensions to the generic format.
  1182  The \\{xxx} and \\{yyy} instructions understood by \.{GFtoDVI} will be
  1183  listed now, so that we have a convenient reference to all of the special
  1184  assumptions made later.
  1185  
  1186  Each special instruction begins with an \\{xxx} command, which consists of
  1187  either a keyword by itself, or a keyword followed by a space followed
  1188  by arguments. This \\{xxx} command may then be followed by \\{yyy}
  1189  commands that are understood to be arguments.
  1190  
  1191  The keywords of special instructions that are intended to be used at
  1192  many different sites should be published as widely as possible in order
  1193  to minimize conflicts. The first person to establish a keyword presumably
  1194  has a right to define it; \.{GFtoDVI}, as the first program
  1195  to use extended \.{GF} commands, has the opportunity of choosing any
  1196  keywords it likes, and the responsibility of choosing reasonable ones.
  1197  Since labels are expected to account for the bulk of extended commands
  1198  in typical uses of \MF, the ``null'' keyword has been set aside to
  1199  denote 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
  1207  characters \.1, \.2, \.3,~\.4 respectively denote labels forced to be
  1208  at 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.
  1210  The character \.0 instructs \.{GFtoDVI} to choose one of the first four
  1211  possibilities, if there's no overlap with other labels or dots, otherwise
  1212  an ``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
  1214  label itself is the \string\ that follows. \MF\ coordinates of the
  1215  point that is to receive this label are given by arguments $x$ and~$y$,
  1216  in units of scaled pixels. (These arguments appear in \\{yyy} commands.)
  1217  (Precise definitions of the size and positioning of labels, and of the
  1218  notion 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
  1223  does this only if the line is either horizontal or vertical, or if its
  1224  slope matches the slope of the slant font.
  1225  
  1226  \smallskip\hang\noindent
  1227  \.{title\SP}\string. This command (which is output by \MF\
  1228  when it sees a ``title statement'') specifies a string that will appear
  1229  at the top of the next proofsheet to be output by \.{GFtoDVI}.
  1230  If more than one title is given, they will appear in sequence; titles
  1231  should 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
  1235  commands below, must precede the first |boc| in the \.{GF} file.
  1236  It overrides the current font used to
  1237  typeset the titles at the top of proofsheets. \.{GFtoDVI} has default
  1238  fonts that will be used if none other are specified; the ``current'' title
  1239  font is initially the default title font.
  1240  
  1241  \smallskip\hang\noindent
  1242  \.{titlefontarea\SP}\string. This command overrides the current
  1243  file area (or directory name) from which \.{GFtoDVI} will try to
  1244  find metric information for the title font.
  1245  
  1246  \smallskip\hang\noindent
  1247  \.{titlefontat} $s$. This command overrides the current ``at size'' that
  1248  will be used for the title font. (See the discussion of font metric files
  1249  below, for the meaning of ``at size'' versus ``design size.'') The
  1250  value 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
  1255  used to typeset the labels that are superimposed on proof figures.
  1256  (The label font is fairly arbitrary, but it should be dark enough to
  1257  stand out when superimposed on gray pixels, and it should contain at
  1258  least the decimal digits and the characters `\.(', `\.)', `\.=', `\.+',
  1259  `\.-', `\.,', and `\..'.)
  1260  
  1261  \smallskip\hang\noindent
  1262  \.{labelfontarea\SP}\string. This command overrides the current
  1263  file area (or directory name) from which \.{GFtoDVI} will try to
  1264  find metric information for the label font.
  1265  
  1266  \smallskip\hang\noindent
  1267  \.{labelfontat} $s$. This command overrides the current ``at size'' that
  1268  will be used for the label font.
  1269  
  1270  \okpagebreak
  1271  \smallskip\hang\noindent
  1272  \.{grayfont\SP}\string. This command overrides the current font
  1273  used to typeset the black pixels and the dots for labels. (Gray fonts
  1274  will be explained in detail later.)
  1275  @^gray fonts@>
  1276  
  1277  \smallskip\hang\noindent
  1278  \.{grayfontarea\SP}\string. This command overrides the current
  1279  file area (or directory name) from which \.{GFtoDVI} will try to
  1280  find metric information for the gray font.
  1281  
  1282  \smallskip\hang\noindent
  1283  \.{grayfontat} $s$. This command overrides the current ``at size'' that
  1284  will be used for the gray font.
  1285  
  1286  \okpagebreak
  1287  \smallskip\hang\noindent
  1288  \.{slantfont\SP}\string. This command overrides the current font
  1289  used to typeset rules that are neither horizontal nor vertical. (Slant
  1290  fonts will be explained in detail later.)
  1291  @^slant fonts@>
  1292  
  1293  \smallskip\hang\noindent
  1294  \.{slantfontarea\SP}\string. This command overrides the current
  1295  file area (or directory name) from which \.{GFtoDVI} will try to
  1296  find metric information for the slant font.
  1297  
  1298  \smallskip\hang\noindent
  1299  \.{slantfontat} $s$. This command overrides the current ``at size'' that
  1300  will be used for the slant font.
  1301  
  1302  \okpagebreak
  1303  \smallskip\hang\noindent
  1304  \.{rulethickness} $t$. This command overrides the current value used
  1305  for the thickness of rules. If the current value is negative, no rule
  1306  will be drawn; if the current value is zero, the rule thickness will
  1307  be specified by a parameter of the gray font. Each \.{rule} command
  1308  uses the rule thickness that is current at the time the command appears;
  1309  hence it is possible to get different thicknesses of rules on the same
  1310  figure. The value of $t$ is given in units of scaled points (\TeX's `\.{sp}').
  1311  At 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
  1315  that 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
  1317  of repositioning the figures on the pages; the title line always appears
  1318  in the same place, but the figure can be moved up, down, left, or right.
  1319  At 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
  1323  a character whose $x$~offset is nonzero. \.{GFtoDVI} adds the specified
  1324  amount to the $x$ coordinates of all dots, labels, and rules
  1325  in the following character.
  1326  
  1327  \smallskip\hang\noindent
  1328  \.{yoffset} $y$. This command is output by \MF\ just before shipping out
  1329  a character whose $y$~offset is nonzero. \.{GFtoDVI} adds the specified
  1330  amount to the $y$ coordinates of all dots, labels, and rules
  1331  in the following character.
  1332  
  1333  @* Font metric data.
  1334  Before we can get into the meaty details of \.{GFtoDVI}, we need to
  1335  deal with yet another esoteric binary file format, since \.{GFtoDVI}
  1336  also does elementary typesetting operations. Therefore it has to
  1337  read important information about the fonts it will be using.
  1338  The following material (again copied almost verbatim from \TeX)
  1339  describes the contents of so-called \TeX\ font metric (\.{TFM}) files.
  1340  
  1341  The idea behind \.{TFM} files is that typesetting routines
  1342  need a compact way to store the relevant information about
  1343  fonts, and computer centers need a compact way to store the
  1344  relevant information about several hundred fonts. \.{TFM} files are
  1345  compact, and most of the information they contain is highly relevant,
  1346  so they provide a solution to the problem. \.{GFtoDVI} uses only
  1347  four fonts, but interesting changes in its output will occur when
  1348  those fonts are varied.
  1349  
  1350  The information in a \.{TFM} file appears in a sequence of 8-bit bytes.
  1351  Since the number of bytes is always a multiple of 4, we could
  1352  also regard the file as a sequence of 32-bit words; but \TeX\ uses the
  1353  byte interpretation, and so does \.{GFtoDVI}. The individual bytes
  1354  are considered to be unsigned numbers.
  1355  
  1356  @ The first 24 bytes (6 words) of a \.{TFM} file contain twelve 16-bit
  1357  integers that give the lengths of the various subsequent portions
  1358  of 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}}$$
  1372  They are all nonnegative and less than $2^{15}$. We must have |bc-1<=ec<=255|,
  1373  and
  1374  $$\hbox{|lf=6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.}$$
  1375  Note that a font may contain as many as 256 characters (if |bc=0| and |ec=255|),
  1376  and as few as 0 characters (if |bc=ec+1|). When two or more 8-bit bytes are
  1377  combined to form an integer of 16 or more bits, the bytes appear in
  1378  BigEndian 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
  1386  arrays having the informal specification
  1387  $$\def\arr$[#1]#2${\&{array} $[#1]$ \&{of} #2}
  1388  \vbox{\halign{\hfil\\{#}&$\,:\,$\arr#\hfil\cr
  1389  header&|[0..lh-1]@t\\{stuff}@>|\cr
  1390  char\_info&|[bc..ec]char_info_word|\cr
  1391  width&|[0..nw-1]fix_word|\cr
  1392  height&|[0..nh-1]fix_word|\cr
  1393  depth&|[0..nd-1]fix_word|\cr
  1394  italic&|[0..ni-1]fix_word|\cr
  1395  lig\_kern&|[0..nl-1]lig_kern_command|\cr
  1396  kern&|[0..nk-1]fix_word|\cr
  1397  exten&|[0..ne-1]extensible_recipe|\cr
  1398  param&|[1..np]fix_word|\cr}}$$
  1399  The most important data type used here is a |@!fix_word|, which is
  1400  a 32-bit representation of a binary fraction. A |fix_word| is a signed
  1401  quantity, with the two's complement of the entire word used to represent
  1402  negation. Of the 32 bits in a |fix_word|, exactly 12 are to the left of the
  1403  binary point; thus, the largest |fix_word| value is $2048-2^{-20}$, and
  1404  the smallest is $-2048$. We will see below, however, that all but two of
  1405  the |fix_word| values must lie between $-16$ and $+16$.
  1406  
  1407  @ The first data array is a block of header information, which contains
  1408  general facts about the font. The header must contain at least two words,
  1409  and for \.{TFM} files to be used with Xerox printing software it must
  1410  contain at least 18 words, allocated as described below. When different
  1411  kinds of devices need to be interfaced, it may be necessary to add further
  1412  words 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}
  1416  file is printed, possibly on another computer, the actual font that gets
  1417  used 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
  1419  potential incompatibilities. (However, if the check sum is zero in either
  1420  the font file or the \.{TFM} file, no check is made.)  The actual relation
  1421  between this check sum and the rest of the \.{TFM} file is not important;
  1422  the check sum is simply an identification number with the property that
  1423  incompatible 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
  1427  font, in units of \TeX\ points (7227 \TeX\ points = 254 cm).  This number
  1428  must be at least 1.0; it is fairly arbitrary, but usually the design size
  1429  is 10.0 for a ``10 point'' font, i.e., a font that was designed to look
  1430  best at a 10-point size, whatever that really means. When a \TeX\ user
  1431  asks for a font `\.{at} $\delta$ \.{pt}', the effect is to override the
  1432  design size and replace it by $\delta$, and to multiply the $x$ and~$y$
  1433  coordinates of the points in the font image by a factor of $\delta$
  1434  divided by the design size.  Similarly, specific sizes can be substituted
  1435  for the design size by \.{GFtoDVI} commands like `\.{titlefontat}'.  {\sl
  1436  All other dimensions in the\/\ \.{TFM} file are |fix_word| numbers in
  1437  design-size units.} Thus, for example, the value of |param[6]|, one \.{em}
  1438  or \.{\\quad}, is often the |fix_word| value $2^{20}=1.0$, since many
  1439  fonts have a design size equal to one em.  The other dimensions must be
  1440  less 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
  1442  first 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
  1445  the character coding scheme. The first byte, which must be between 0 and
  1446  39, is the number of subsequent ASCII bytes actually relevant in this
  1447  string, which is intended to specify what character-code-to-symbol
  1448  convention is present in the font.  Examples are \.{ASCII} for standard
  1449  ASCII, \.{TeX text} for fonts like \.{cmr10} and \.{cmti9}, \.{TeX math
  1450  extension} for \.{cmex10}, \.{XEROX text} for Xerox fonts, \.{GRAPHIC} for
  1451  special-purpose non-alphabetic fonts, \.{GFGRAY} for \.{GFtoDVI}'s
  1452  gray fonts, \.{GFSLANT} for \.{GFtoDVI}'s slant fonts, \.{UNSPECIFIED} for
  1453  the default case when there is no information.  Parentheses should not
  1454  appear 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|
  1460  per character. Each |char_info_word| contains six fields packed into
  1461  four 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
  1470  The actual width of a character is \\{width}|[width_index]|, in design-size
  1471  units; this is a device for compressing information, since many characters
  1472  have the same width. Since it is quite common for many characters
  1473  to have the same height, depth, or italic correction, the \.{TFM} format
  1474  imposes a limit of 16 different heights, 16 different depths, and
  1475  64 different italic corrections.
  1476  
  1477  Incidentally, the relation $\\{width}[0]=\\{height}[0]=\\{depth}[0]=
  1478  \\{italic}[0]=0$ should always hold, so that an index of zero implies a
  1479  value of zero.  The |width_index| should never be zero unless the
  1480  character does not exist in the font, since a character is valid if and
  1481  only 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
  1484  interpret 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
  1488  program starting at |lig_kern[remainder]|.\par
  1489  \hang|tag=2| (|list_tag|) means that this character is part of a chain of
  1490  characters 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
  1493  extensible character, i.e., a character that is built up of smaller pieces
  1494  so 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
  1503  that 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
  1515  In a kern step, an
  1516  additional space equal to |kern[256*(op_byte-128)+remainder]| is inserted
  1517  between the current character and |next_char|. This amount is
  1518  often negative, so that the characters are brought closer together
  1519  by kerning; but it might be positive.
  1520  
  1521  There 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|;
  1524  then the current character is deleted if $b=0$, and |next_char| is
  1525  deleted if $c=0$; then we pass over $a$~characters to reach the next
  1526  current character (which may have a ligature/kerning program of its own).
  1527  
  1528  If the very first instruction of the |lig_kern| array has |skip_byte=255|,
  1529  the |next_char| byte is the so-called right boundary character of this font;
  1530  the value of |next_char| need not lie between |bc| and~|ec|.
  1531  If the very last instruction of the |lig_kern| array has |skip_byte=255|,
  1532  there is a special ligature/kerning program for a left boundary character,
  1533  beginning at location |256*op_byte+remainder|.
  1534  The interpretation is that \TeX\ puts implicit boundary characters
  1535  before and after each consecutive string of characters from the same font.
  1536  These implicit characters do not appear in the output, but they can affect
  1537  ligatures and kerning.
  1538  
  1539  If 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|
  1542  arrays, because the first instruction must otherwise
  1543  appear in a location |<=255|.
  1544  
  1545  Any 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
  1547  normal program execution, it denotes an unconditional halt; no ligature
  1548  or 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
  1554  consists of four bytes called |@!top|, |@!mid|, |@!bot|, and |@!rep| (in this
  1555  order). These bytes are the character codes of individual pieces used to
  1556  build up a large symbol.  If |top|, |mid|, or |bot| are zero, they are not
  1557  present in the built-up result. For example, an extensible vertical line is
  1558  like 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
  1561  sequence of |fix_word| values.
  1562  
  1563  \yskip\hang|param[1]=@!slant| is the amount of italic slant.
  1564  For example, |slant=.25| means that when you go
  1565  up one unit, you also go .25 units to the right. The |slant| is a pure
  1566  number; it's the only |fix_word| other than the design size itself that is
  1567  not scaled by the design size.
  1568  
  1569  \hang|param[2]=space| is the normal spacing between words in text.
  1570  Note that character |" "| in the font need not have anything to do with
  1571  blank 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
  1578  have 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
  1583  ends of sentences.
  1584  
  1585  When the character coding scheme is \.{GFGRAY} or \.{GFSLANT}, the font is
  1586  supposed to contain an additional parameter called
  1587  |default_rule_thickness|. Other special parameters go with other coding
  1588  schemes.
  1589  
  1590  @* Input from binary files.
  1591  We have seen that \.{GF} and \.{DVI} and \.{TFM} files are sequences of
  1592  8-bit bytes.  The bytes appear physically in what is called a `|packed
  1593  file of 0..255|' in \PASCAL\ lingo.
  1594  
  1595  Packing is system dependent, and many \PASCAL\ systems fail to implement
  1596  such files in a sensible way (at least, from the viewpoint of producing
  1597  good production software).  For example, some systems treat all
  1598  byte-oriented files as text, looking for end-of-line marks and such
  1599  things. Therefore some system-dependent code is often needed to deal with
  1600  binary files, even though most of the program in this section of
  1601  \.{GFtoDVI} is written in standard \PASCAL.
  1602  @^system dependencies@>
  1603  
  1604  One common way to solve the problem is to consider files of |integer|
  1605  numbers, and to convert an integer in the range $-2^{31}\L x<2^{31}$ to
  1606  a sequence of four bytes $(a,b,c,d)$ using the following code, which
  1607  avoids 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}}$$
  1615  The four bytes are then kept in a buffer and output one by one. (On 36-bit
  1616  computers, an additional division by 16 is necessary at the beginning.
  1617  Another 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
  1619  packed in the same place; {\sl caveat implementor!\/}) It is also desirable
  1620  in some cases to read a hundred or so integers at a time, maintaining a
  1621  larger buffer.
  1622  
  1623  We shall stick to simple \PASCAL\ in this program, for reasons of clarity,
  1624  even 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
  1631  input file that we are converting into a document; |dvi_file| is the main
  1632  output file that will specify that document; and |tfm_file| is
  1633  the current font metric file from which character-width information is
  1634  being 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|
  1642  them. An extension of \PASCAL\ is needed, since we want to associate
  1643  it with external files whose names are specified dynamically (i.e., not
  1644  known 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
  1646  variable that specifies the file name.
  1647  @^system dependencies@>
  1648  
  1649  @p procedure open_gf_file; {prepares to read packed bytes in |gf_file|}
  1650  begin reset(gf_file,name_of_file);
  1651  cur_loc:=0;
  1652  end;
  1653  @#
  1654  procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|}
  1655  begin reset(tfm_file,name_of_file);
  1656  end;
  1657  @#
  1658  procedure open_dvi_file; {prepares to write packed bytes in |dvi_file|}
  1659  begin rewrite(dvi_file,name_of_file);
  1660  end;
  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
  1664  variables: The integer |cur_loc| tells which byte of the input file will
  1665  be read next, and the string |name_of_file| will be set to the current
  1666  file 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
  1673  inputting from \.{TFM} files. The input goes into global variables
  1674  |b0|, |b1|, |b2|, and |b3|, with |b0| getting the first byte and |b3|
  1675  the 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
  1681  four bytes in the current \.{TFM} file.
  1682  @^system dependencies@>
  1683  
  1684  @p procedure read_tfm_word;
  1685  begin read(tfm_file,b0); read(tfm_file,b1);
  1686  read(tfm_file,b2); read(tfm_file,b3);
  1687  end;
  1688  
  1689  @ We shall use another set of simple functions to read the next byte or
  1690  bytes from |gf_file|. There are four possibilities, each of which is
  1691  treated as a separate function in order to minimize the overhead for
  1692  subroutine calls.
  1693  @^system dependencies@>
  1694  
  1695  @p function get_byte:integer; {returns the next byte, unsigned}
  1696  var b:eight_bits;
  1697  begin if eof(gf_file) then get_byte:=0
  1698  else  begin read(gf_file,b); incr(cur_loc); get_byte:=b;
  1699    end;
  1700  end;
  1701  @#
  1702  function get_two_bytes:integer; {returns the next two bytes, unsigned}
  1703  var a,@!b:eight_bits;
  1704  begin read(gf_file,a); read(gf_file,b);
  1705  cur_loc:=cur_loc+2;
  1706  get_two_bytes:=a*256+b;
  1707  end;
  1708  @#
  1709  function get_three_bytes:integer; {returns the next three bytes, unsigned}
  1710  var a,@!b,@!c:eight_bits;
  1711  begin read(gf_file,a); read(gf_file,b); read(gf_file,c);
  1712  cur_loc:=cur_loc+3;
  1713  get_three_bytes:=(a*256+b)*256+c;
  1714  end;
  1715  @#
  1716  function signed_quad:integer; {returns the next four bytes, signed}
  1717  var a,@!b,@!c,@!d:eight_bits;
  1718  begin read(gf_file,a); read(gf_file,b); read(gf_file,c); read(gf_file,d);
  1719  cur_loc:=cur_loc+4;
  1720  if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
  1721  else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
  1722  end;
  1723  
  1724  @* Reading the font information.
  1725  Now let's get down to brass tacks and consider the more substantial
  1726  routines that actually convert \.{TFM} data into a form suitable for
  1727  computation.  The routines in this part of the program have been borrowed
  1728  from \TeX, with slight changes, since \.{GFtoDVI} has to do some of the
  1729  things that \TeX\ does.
  1730  
  1731  The \.{TFM} data is stored in a large array called
  1732  |font_info|. Each item of |font_info| is a |memory_word|; the |fix_word|
  1733  data gets converted into |scaled| entries, while everything else goes into
  1734  words of type |four_quarters|. (These data structures are special cases of
  1735  the more general memory words of \TeX. On some machines it is necessary to
  1736  define |min_quarterword=-128| and |max_quarterword=127| in order to pack
  1737  four 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
  1771  into it, so that we can locate width and height information, etc.  For
  1772  example, 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
  1774  this 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...@>=
  1813  fmem_ptr:=0;
  1814  
  1815  @ Of course we want to define macros that suppress the detail of how font
  1816  information 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|}$$
  1818  too 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
  1821  the character's width; hence the long formula above is at least
  1822  abbreviated to
  1823  $$\hbox{|char_width(f)(char_info(f)(c))|.}$$
  1824  In practice we will try to fetch |q| first and look at several of its
  1825  fields at the same time.
  1826  
  1827  The 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
  1829  at the height and depth in a slightly different way, since we usually want
  1830  to 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
  1833  will write |char_height(f)(b)| and |char_depth(f)(b)| for the height and
  1834  depth of the character |c| for which |q=char_info(f)(c)|. Got that?
  1835  
  1836  The tag field will be called |char_tag(q)|; and the remainder byte will be
  1837  called |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.
  1858  We write |char_kern(f)(j)| to find the amount of kerning specified by
  1859  kerning 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
  1877  that the file has just been reset. Parameter~|f| tells which metric file is
  1878  being read (either |title_font| or |label_font| or |gray_font| or |slant_font|
  1879  or |logo_font|); parameter~|s| is the ``at'' size, which will be
  1880  substituted for the design size if it is positive.
  1881  
  1882  This routine does only limited checking of the validity of the file,
  1883  because another program (\.{TFtoPL}) is available to diagnose errors in
  1884  the 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}
  1890  label done,bad_tfm;
  1891  var 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}
  1900  begin @<Read and check the font data; |abend| if the \.{TFM} file is
  1901    malformed; otherwise |goto done|@>;
  1902  bad_tfm: print_nl('Bad TFM file for');
  1903  @.Bad TFM file...@>
  1904  case f of
  1905  title_font:abort('titles!');
  1906  label_font:abort('labels!');
  1907  gray_font:abort('pixels!');
  1908  slant_font:abort('slants!');
  1909  logo_font:abort('METAFONT logo!');
  1910  end; {there are no other cases}
  1911  done: {it might be good to close |tfm_file| now}
  1912  end;
  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@>=
  1929  begin read_two_halves(lf)(lh);
  1930  read_two_halves(bc)(ec);
  1931  if (bc>ec+1)or(ec>255) then abend;
  1932  if bc>255 then {|bc=256| and |ec=255|}
  1933    begin bc:=1; ec:=0;
  1934    end;
  1935  read_two_halves(nw)(nh);
  1936  read_two_halves(nd)(ni);
  1937  read_two_halves(nl)(nk);
  1938  read_two_halves(ne)(np);
  1939  if lf<>6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np then abend;
  1940  end
  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
  1944  subtracting |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@>=
  1948  lf:=lf-6-lh; {|lf| words should be loaded into |font_info|}
  1949  if np<8 then lf:=lf+8-np; {at least eight parameters will appear}
  1950  if fmem_ptr+lf>font_mem_size then abort('No room for TFM file!');
  1951  @.No room for TFM file@>
  1952  char_base[f]:=fmem_ptr-bc;
  1953  width_base[f]:=char_base[f]+ec+1;
  1954  height_base[f]:=width_base[f]+nw;
  1955  depth_base[f]:=height_base[f]+nh;
  1956  italic_base[f]:=depth_base[f]+nd;
  1957  lig_kern_base[f]:=italic_base[f]+ni;
  1958  kern_base[f]:=lig_kern_base[f]+nl;
  1959  exten_base[f]:=kern_base[f]+nk;
  1960  param_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@>=
  1971  begin if lh<2 then abend;
  1972  store_four_quarters(font_check[f]);
  1973  read_tfm_word;
  1974  if b0>127 then abend; {design size must be positive}
  1975  z:=((b0*256+b1)*256+b2)*16+(b3 div 16);
  1976  if z<unity then abend;
  1977  while lh>2 do
  1978    begin read_tfm_word; decr(lh); {ignore the rest of the header}
  1979    end;
  1980  font_dsize[f]:=z;
  1981  if s>0 then z:=s;
  1982  font_size[f]:=z;
  1983  end
  1984  
  1985  @ @<Read character data@>=
  1986  for 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
  1998  represents the number
  1999  $$x=\left\{\vcenter{\halign{$#$,\hfil\qquad&if $#$\hfil\cr
  2000  b_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
  2003  design-size units must be less than 16.)  We want to multiply this
  2004  quantity 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,
  2007  4, 8, or 16, to obtain a multiplier less than $2^{23}$, and we can
  2008  compensate 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$$
  2011  if $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@>=
  2019  begin @<Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$@>;
  2020  for k:=width_base[f] to lig_kern_base[f]-1 do
  2021    store_scaled(font_info[k].sc);
  2022  if font_info[width_base[f]].sc<>0 then abend; {\\{width}[0] must be zero}
  2023  if font_info[height_base[f]].sc<>0 then abend; {\\{height}[0] must be zero}
  2024  if font_info[depth_base[f]].sc<>0 then abend; {\\{depth}[0] must be zero}
  2025  if font_info[italic_base[f]].sc<>0 then abend; {\\{italic}[0] must be zero}
  2026  end
  2027  
  2028  @ @<Replace |z|...@>=
  2029  begin alpha:=16*z; beta:=16;
  2030  while z>=@'40000000 do
  2031    begin z:=z div 2; beta:=beta div 2;
  2032    end;
  2033  end
  2034  
  2035  @ @d check_byte_range(#)==begin if (#<bc)or(#>ec) then abend@+end
  2036  
  2037  @<Read ligature/kern program@>=
  2038  begin bch_label:=@'77777; bchar:=256;
  2039  if 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;
  2053  for k:=kern_base[f] to exten_base[f]-1 do
  2054    store_scaled(font_info[k].sc);
  2055  end
  2056  
  2057  @ @<Read extensible character recipes@>=
  2058  for 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@>=
  2067  begin 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);
  2075  for k:=np+1 to 8 do font_info[param_base[f]+k-1].sc:=0;
  2076  end
  2077  
  2078  @ Now to wrap it up, we have checked all the necessary things about the \.{TFM}
  2079  file, and all we need to do is put the finishing touches on the data for
  2080  the new font.
  2081  
  2082  @d adjust(#)==#[f]:=qo(#[f])
  2083    {correct for the excess |min_quarterword| that was added}
  2084  
  2085  @<Make final adjustments...@>=
  2086  font_bc[f]:=bc; font_ec[f]:=ec;
  2087  if bch_label<nl then bchar_label[f]:=bch_label+lig_kern_base[f]
  2088  else bchar_label[f]:=non_address;
  2089  font_bchar[f]:=qi(bchar);
  2090  adjust(width_base); adjust(lig_kern_base);
  2091  adjust(kern_base); adjust(exten_base);
  2092  decr(param_base[f]);
  2093  fmem_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
  2104  means of two global variables called |pool_ptr| and |str_ptr|. These are
  2105  periodically reset to their initial values when we move from one character
  2106  to 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}
  2116  macros instead of using \PASCAL\ procedures, because many of the
  2117  operations are done quite frequently and we want to avoid the
  2118  overhead of procedure calls. For example, here is
  2119  a 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|.
  2126  The macro called |append_char|, defined here, does not check to see if the
  2127  value of |pool_ptr| has gotten too high; that test is supposed to be
  2128  made before |append_char| is used.
  2129  
  2130  To test if there is room to append |l| more characters to |str_pool|,
  2131  we shall write |str_room(l)|, which aborts \.{GFtoDVI} and gives an
  2132  apologetic error message if there isn't enough room.
  2133  
  2134  @d append_char(#) == {put |ASCII_code| \# at the end of |str_pool|}
  2135  begin str_pool[pool_ptr]:=#; incr(pool_ptr);
  2136  end
  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
  2144  officially becomes a string when the function |make_string| is called.
  2145  This function returns the identification number of the new string as its
  2146  value.
  2147  
  2148  @p function make_string : str_number; {current string enters the pool}
  2149  begin if str_ptr=max_strings then
  2150    abort('Too many labels!');
  2151  @.Too many labels@>
  2152  incr(str_ptr); str_start[str_ptr]:=pool_ptr;
  2153  make_string:=str_ptr-1;
  2154  end;
  2155  
  2156  @ The first strings in the string pool are the keywords that \.{GFtoDVI}
  2157  recognizes in the \\{xxx} commands of a \.{GF} file. They are entered
  2158  into |str_pool| by means of a tedious bunch of assignment statements,
  2159  together 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);
  2178  begin if str_ptr<>c then abort('?'); {internal consistency check}
  2179  @.?@>
  2180  while l>0 do
  2181    begin append_char(buffer[l]); decr(l);
  2182    end;
  2183  incr(str_ptr); str_start[str_ptr]:=pool_ptr;
  2184  end;
  2185  
  2186  @ @<Glob...@>=
  2187  @!l:integer; {length of string being made by |first_string|}
  2188  
  2189  @ Here are the tedious assignments just promised.
  2190  String 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@>=
  2204  str_ptr:=0; pool_ptr:=0; str_start[0]:=0;@/
  2205  l:=0; init_str0(null_string);@/
  2206  l:=9; init_str9("t")("i")("t")("l")("e")("f")("o")("n")("t")(title_font);@/
  2207  l:=9; init_str9("l")("a")("b")("e")("l")("f")("o")("n")("t")(label_font);@/
  2208  l:=8; init_str8("g")("r")("a")("y")("f")("o")("n")("t")(gray_font);@/
  2209  l:=9; init_str9("s")("l")("a")("n")("t")("f")("o")("n")("t")(slant_font);@/
  2210  l:=13; init_str13("t")("i")("t")("l")("e")
  2211    ("f")("o")("n")("t")("a")("r")("e")("a")(title_font+area_code);@/
  2212  l:=13; init_str13("l")("a")("b")("e")("l")
  2213    ("f")("o")("n")("t")("a")("r")("e")("a")(label_font+area_code);@/
  2214  l:=12; init_str12("g")("r")("a")("y")
  2215    ("f")("o")("n")("t")("a")("r")("e")("a")(gray_font+area_code);@/
  2216  l:=13; init_str13("s")("l")("a")("n")("t")
  2217    ("f")("o")("n")("t")("a")("r")("e")("a")(slant_font+area_code);@/
  2218  l:=11; init_str11("t")("i")("t")("l")("e")
  2219    ("f")("o")("n")("t")("a")("t")(title_font+at_code);@/
  2220  l:=11; init_str11("l")("a")("b")("e")("l")
  2221    ("f")("o")("n")("t")("a")("t")(label_font+at_code);@/
  2222  l:=10; init_str10("g")("r")("a")("y")
  2223    ("f")("o")("n")("t")("a")("t")(gray_font+at_code);@/
  2224  l:=11; init_str11("s")("l")("a")("n")("t")
  2225    ("f")("o")("n")("t")("a")("t")(slant_font+at_code);@/
  2226  l:=4; init_str4("r")("u")("l")("e")(rule_code);@/
  2227  l:=5; init_str5("t")("i")("t")("l")("e")(title_code);@/
  2228  l:=13; init_str13("r")("u")("l")("e")
  2229    ("t")("h")("i")("c")("k")("n")("e")("s")("s")(rule_thickness_code);@/
  2230  l:=6; init_str6("o")("f")("f")("s")("e")("t")(offset_code);@/
  2231  l:=7; init_str7("x")("o")("f")("f")("s")("e")("t")(x_offset_code);@/
  2232  l:=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
  2235  default 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@>=
  2259  l:=3; init_str3(".")("g")("f")(gf_ext);@/
  2260  l:=4; init_str4(".")("d")("v")("i")(dvi_ext);@/
  2261  l:=4; init_str4(".")("t")("f")("m")(tfm_ext);@/
  2262  l:=7; init_str7(" ")(" ")("P")("a")("g")("e")(" ")(page_header);@/
  2263  l:=12; init_str12(" ")(" ")("C")("h")("a")("r")("a")("c")("t")("e")("r")(" ")
  2264    (char_header);@/
  2265  l:=6; init_str6(" ")(" ")("E")("x")("t")(" ")(ext_header);@/
  2266  l:=4; init_str4(" ")(" ")("`")("`")(left_quotes);@/
  2267  l:=2; init_str2("'")("'")(right_quotes);@/
  2268  l:=3; init_str3(" ")("=")(" ")(equals_sign);@/
  2269  l:=4; init_str4(" ")("+")(" ")("(")(plus_sign);@/
  2270  l:=4; init_str4("c")("m")("r")("8")(default_title_font);@/
  2271  l:=6; init_str6("c")("m")("t")("t")("1")("0")(default_label_font);@/
  2272  l:=4; init_str4("g")("r")("a")("y")(default_gray_font);@/
  2273  l:=5; init_str5("l")("o")("g")("o")("8")(logo_font_name);@/
  2274  l:=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,
  2277  the following procedure interprets its keyword. More precisely, we assume
  2278  that |cur_gf| contains an op-code byte just read from the \.{GF} file,
  2279  where |xxx1<=cur_gf<=no_op|. The |interpret_xxx| procedure will read the
  2280  rest 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
  2283  an unknown keyword, the bytes are simply read and ignored, and the
  2284  value |no_operation| is returned.
  2285  
  2286  \item{2)} If |cur_gf| is an \\{xxx} command (either |xxx1| or $\cdots$
  2287  or |xxx4|), and if the associated string matches a keyword exactly,
  2288  the 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
  2291  keyword and space, the string number of that keyword is returned, and
  2292  the remainder of the string is put into the string pool (where it will be
  2293  string number |cur_string|. Exception: If the keyword is |null_string|,
  2294  the character immediately following the blank space is put into the
  2295  global variable |label_type|, and the remaining characters go into the
  2296  string pool.
  2297  
  2298  \smallskip\noindent
  2299  In all cases, |cur_gf| will then be reset to the op-code byte that
  2300  immediately 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
  2313  after the preamble and just after |eoc| commands.
  2314  
  2315  @p function interpret_xxx:keyword_code;
  2316  label done,done1,not_found;
  2317  var @!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}
  2324  begin c:=no_operation; cur_string:=null_string;
  2325  case cur_gf of
  2326  no_op:goto done;
  2327  yyy:begin k:=signed_quad; goto done;
  2328    end;
  2329  xxx1:k:=get_byte;
  2330  xxx2:k:=get_two_bytes;
  2331  xxx3:k:=get_three_bytes;
  2332  xxx4:k:=signed_quad;
  2333  end; {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@>;
  2336  done: cur_gf:=get_byte; interpret_xxx:=c;
  2337  end;
  2338  
  2339  @ @<Read the next |k|...@>=
  2340  j:=0;@+if k<2 then goto not_found;
  2341  loop@+  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;
  2347  done1:@<If the keyword in |buffer[1..l]| is known, change |c| and |goto done|@>;
  2348  not_found: while j<k do
  2349    begin incr(j); cur_gf:=get_byte;
  2350    end
  2351  
  2352  @ @<If the keyword...@>=
  2353  for 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
  2372  that argument and puts the following byte into |cur_gf|.
  2373  
  2374  @p function get_yyy:scaled;
  2375  var @!v:scaled; {value just read}
  2376  begin if cur_gf<>yyy then get_yyy:=0
  2377  else  begin v:=signed_quad; cur_gf:=get_byte; get_yyy:=v;
  2378    end;
  2379  end;
  2380  
  2381  @ A simpler method is used for special commands between |boc| and |eoc|,
  2382  since \.{GFtoDVI} doesn't even look at them.
  2383  
  2384  @p procedure skip_nop;
  2385  label done;
  2386  var @!k:integer; {number of bytes in an \\{xxx} command}
  2387  @!j:integer; {number of bytes read so far}
  2388  begin case cur_gf of
  2389  no_op:goto done;
  2390  yyy:begin k:=signed_quad; goto done;
  2391    end;
  2392  xxx1:k:=get_byte;
  2393  xxx2:k:=get_two_bytes;
  2394  xxx3:k:=get_three_bytes;
  2395  xxx4:k:=signed_quad;
  2396  end; {there are no other cases}
  2397  for j:=1 to k do cur_gf:=get_byte;
  2398  done: cur_gf:=get_byte;
  2399  end;
  2400  
  2401  @* File names.
  2402  It'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
  2404  files. Three routines called |begin_name|, |more_name|, and |end_name| are
  2405  involved, so that the system-dependent parts of file naming conventions are
  2406  isolated 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
  2416  following structure:  If the name contains `\.>' or `\.:', the file area
  2417  consists of all characters up to and including the final such character;
  2418  otherwise the file area is null.  If the remaining file name contains
  2419  `\..', the file extension consists of all such characters from the first
  2420  remaining `\..' to the end, otherwise the file extension is null.
  2421  @^system dependencies@>
  2422  
  2423  We can scan such file names easily by using two global variables that keep track
  2424  of 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
  2431  explicitly are assumed to appear in a standard system area called
  2432  |home_font_area|.  This system area name will, of course, vary from place
  2433  to place. The program here sets it to `\.{TeXfonts:}'.
  2434  @^system dependencies@>
  2435  @.TeXfonts@>
  2436  
  2437  @<Initialize the strings@>=
  2438  l:=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;
  2444  begin area_delimiter:=0; ext_delimiter:=0;
  2445  end;
  2446  
  2447  @ And here's the second.
  2448  @^system dependencies@>
  2449  
  2450  @p function more_name(@!c:ASCII_code):boolean;
  2451  begin if c=" " then more_name:=false
  2452  else  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;
  2459  end;
  2460  
  2461  @ The third.
  2462  @^system dependencies@>
  2463  
  2464  @p procedure end_name;
  2465  begin if str_ptr+3>max_strings then
  2466    abort('Too many strings!');
  2467  @.Too many strings@>
  2468  if area_delimiter=0 then cur_area:=null_string
  2469  else  begin cur_area:=str_ptr; incr(str_ptr);
  2470    str_start[str_ptr]:=area_delimiter+1;
  2471    end;
  2472  if ext_delimiter=0 then
  2473    begin cur_ext:=null_string; cur_name:=make_string;
  2474    end
  2475  else  begin cur_name:=str_ptr; incr(str_ptr);
  2476    str_start[str_ptr]:=ext_delimiter; cur_ext:=make_string;
  2477    end;
  2478  end;
  2479  
  2480  @ Another system-dependent routine is needed to convert three strings
  2481  into the |name_of_file| value that is used to open files. The present code
  2482  allows 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);
  2490  var 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}
  2494  begin k:=0;
  2495  for j:=str_start[a] to str_start[a+1]-1 do append_to_name(str_pool[j]);
  2496  for j:=str_start[n] to str_start[n+1]-1 do append_to_name(str_pool[j]);
  2497  for j:=str_start[e] to str_start[e+1]-1 do append_to_name(str_pool[j]);
  2498  if k<=file_name_size then name_length:=k@+else name_length:=file_name_size;
  2499  for k:=name_length+1 to file_name_size do name_of_file[k]:=' ';
  2500  end;
  2501  
  2502  @ Now let's consider the routines by which \.{GFtoDVI} deals with file names
  2503  in a system-independent manner.
  2504  The global variable |job_name| contains the \.{GF} file name that is
  2505  being input. This name is extended by `\.{dvi}'
  2506  in 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
  2512  font file to be input. It opens the file, making sure that some input is
  2513  present; then it opens the output file.
  2514  
  2515  Although this routine is system-independent, it should probably be
  2516  modified to take the file name from the command line (without an initial
  2517  prompt), on systems that permit such things.
  2518  
  2519  @p procedure start_gf;
  2520  label found,done;
  2521  begin 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;
  2535  found:job_name:=cur_name; pack_file_name(job_name,null_string,dvi_ext);
  2536  open_dvi_file;
  2537  end;
  2538  
  2539  @ @<Scan the file name in the buffer@>=
  2540  if buffer[line_length-1]="/" then
  2541    begin interaction:=true; decr(line_length);
  2542    end;
  2543  begin_name;
  2544  loop@+  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;
  2548  done:end_name
  2549  
  2550  @ Special instructions found near the beginning of the \.{GF} file might
  2551  change the names, areas, and ``at'' sizes of the fonts that \.{GFtoDVI}
  2552  will be using. But when we reach the first |boc| instruction, we input
  2553  all of the \.{TFM} files. The global variable |interaction| is set |true|
  2554  if a |"/"| was removed at the end of the file name; this means that the
  2555  user will have a chance to issue special instructions online just before
  2556  the 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...@>=
  2568  interaction:=false; fonts_not_loaded:=true;
  2569  font_name[title_font]:=default_title_font;
  2570  font_name[label_font]:=default_label_font;
  2571  font_name[gray_font]:=default_gray_font;
  2572  font_name[slant_font]:=null_string;
  2573  font_name[logo_font]:=logo_font_name;
  2574  for 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
  2579  turning back; the fonts will have been firmly established in
  2580  \.{GFtoDVI}'s memory.
  2581  
  2582  @<Declare the procedure called |load_fonts|@>=
  2583  procedure load_fonts;
  2584  label done,continue,found,not_found;
  2585  var @!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}
  2591  begin if interaction then @<Get online special input@>;
  2592  fonts_not_loaded:=false;
  2593  for 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@>;
  2602  end;
  2603  
  2604  @ @<Get online special input@>=
  2605  loop@+  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;
  2615  done:
  2616  
  2617  @ @<Search buffer for valid keyword; if successful, |goto found|@>=
  2618  buf_ptr:=0; buffer[line_length]:=" ";
  2619  while buffer[buf_ptr]<>" " do incr(buf_ptr);
  2620  for 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@>=
  2629  incr(buf_ptr); str_room(line_length-buf_ptr);
  2630  while buf_ptr<line_length do
  2631    begin append_char(buffer[buf_ptr]); incr(buf_ptr);
  2632    end;
  2633  if m>area_code then font_area[m-area_code]:=make_string
  2634  else  begin font_name[m]:=make_string; font_area[m]:=null_string;
  2635    font_at[m]:=0;
  2636    end;
  2637  init_str_ptr:=str_ptr
  2638  
  2639  @* Shipping pages out.
  2640  The following routines are used to write the \.{DVI} file. They have
  2641  been copied from \TeX, but simplified; we don't have to handle
  2642  nearly as much generality as \TeX\ does.
  2643  
  2644  Statistics about the entire set of pages that will be shipped out must be
  2645  reported 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...@>=
  2655  total_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
  2658  to the output file. This makes it possible to reduce the overhead of
  2659  subroutine calls.
  2660  
  2661  The output buffer is divided into two parts of equal size; the bytes found
  2662  in |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
  2664  variable |dvi_ptr| points to the position that will receive the next
  2665  output byte. When |dvi_ptr| reaches |dvi_limit|, which is always equal
  2666  to one of the two values |half_buf| or |dvi_buf_size|, the half buffer that
  2667  is about to be invaded next is sent to the output and |dvi_limit| is
  2668  changed to its other value. Thus, there is always at least a half buffer's
  2669  worth of information present, except at the very beginning of the job.
  2670  
  2671  Bytes of the \.{DVI} file are numbered sequentially starting with 0;
  2672  the 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|
  2678  array, 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
  2690  after it first fills up.
  2691  
  2692  @<Set init...@>=
  2693  half_buf:=dvi_buf_size div 2; dvi_limit:=dvi_buf_size; dvi_ptr:=0;
  2694  dvi_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
  2698  multiples of 4 when |write_dvi(a,b)| is called; therefore it is possible on
  2699  many machines to use efficient methods to pack four bytes per word and to
  2700  output an array of words with one system call.
  2701  @^system dependencies@>
  2702  
  2703  @p procedure write_dvi(@!a,@!b:dvi_index);
  2704  var k:dvi_index;
  2705  begin for k:=a to b do write(dvi_file,dvi_buf[k]);
  2706  end;
  2707  
  2708  @ To put a byte in the buffer without paying the cost of invoking a procedure
  2709  each 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}
  2716  begin 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
  2720  else  begin write_dvi(half_buf,dvi_buf_size-1); dvi_limit:=dvi_buf_size;
  2721    end;
  2722  end;
  2723  
  2724  @ Here is how we clean out the buffer when \TeX\ is all through; |dvi_ptr|
  2725  will be a multiple of~4.
  2726  
  2727  @<Empty the last bytes out of |dvi_buf|@>=
  2728  if dvi_limit=half_buf then write_dvi(half_buf,dvi_buf_size-1);
  2729  if dvi_ptr>0 then write_dvi(0,dvi_ptr-1)
  2730  
  2731  @ The |dvi_four| procedure outputs four bytes in two's complement notation,
  2732  without risking arithmetic overflow.
  2733  
  2734  @p procedure dvi_four(@!x:integer);
  2735  begin if x>=0 then dvi_out(x div @'100000000)
  2736  else  begin x:=x+@'10000000000;
  2737    x:=x+@'10000000000;
  2738    dvi_out((x div @'100000000) + 128);
  2739    end;
  2740  x:=x mod @'100000000; dvi_out(x div @'200000);
  2741  x:=x mod @'200000; dvi_out(x div @'400);
  2742  dvi_out(x mod @'400);
  2743  end;
  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);
  2750  var k:integer; {index into |str_pool|}
  2751  begin dvi_out(fnt_def1);
  2752  dvi_out(f);@/
  2753  dvi_out(qo(font_check[f].b0));
  2754  dvi_out(qo(font_check[f].b1));
  2755  dvi_out(qo(font_check[f].b2));
  2756  dvi_out(qo(font_check[f].b3));@/
  2757  dvi_four(font_size[f]);
  2758  dvi_four(font_dsize[f]);@/
  2759  dvi_out(length(font_area[f]));
  2760  dvi_out(length(font_name[f]));
  2761  @<Output the font name whose internal number is |f|@>;
  2762  end;@/
  2763  @t\4@>@<Declare the procedure called |load_fonts|@>@;
  2764  
  2765  @ @<Output the font name whose internal number is |f|@>=
  2766  for k:=str_start[font_area[f]] to str_start[font_area[f]+1]-1 do
  2767    dvi_out(str_pool[k]);
  2768  for 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);
  2774  begin if c>=128 then dvi_out(set1);
  2775  dvi_out(c);
  2776  end;
  2777  
  2778  @ The |dvi_scaled| subroutine takes a |real| value |x| and outputs
  2779  a decimal approximation to |x/unity|, correct to one decimal place.
  2780  
  2781  @p procedure dvi_scaled(@!x:real);
  2782  var @!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|}
  2785  begin n:=round(x/6553.6);
  2786  if n<0 then
  2787    begin dvi_out("-"); n:=-n;
  2788    end;
  2789  m:=n div 10; k:=0;
  2790  repeat incr(k); buffer[k]:=(m mod 10)+"0"; m:=m div 10;
  2791  until m=0;
  2792  repeat dvi_out(buffer[k]); decr(k);
  2793  until k=0;
  2794  if n mod 10 <> 0 then
  2795    begin dvi_out("."); dvi_out((n mod 10)+"0");
  2796    end;
  2797  end;
  2798  
  2799  @ At the end of the program, we must finish things off by writing the
  2800  post\-amble. An integer variable~|k| will be declared for use by this routine.
  2801  
  2802  @<Finish the \.{DVI} file and |goto final_end|@>=
  2803  begin dvi_out(post); {beginning of the postamble}
  2804  dvi_four(last_bop); last_bop:=dvi_offset+dvi_ptr-5; {|post| location}
  2805  dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp}
  2806  dvi_four(1000); {magnification factor}
  2807  dvi_four(max_v); dvi_four(max_h);@/
  2808  dvi_out(0); dvi_out(3); {`\\{max\_push}' is said to be 3}@/
  2809  dvi_out(total_pages div 256); dvi_out(total_pages mod 256);@/
  2810  if 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);
  2813  dvi_out(post_post); dvi_four(last_bop); dvi_out(dvi_id_byte);@/
  2814  k:=4+((dvi_buf_size-dvi_ptr) mod 4); {the number of 223's}
  2815  while k>0 do
  2816    begin dvi_out(223); decr(k);
  2817    end;
  2818  @<Empty the last bytes out of |dvi_buf|@>;
  2819  goto final_end;
  2820  end
  2821  
  2822  @* Rudimentary typesetting.
  2823  One of \.{GFtoDVI}'s little duties is to be a mini-\TeX: It must be able
  2824  to typeset the equivalent of `\.{\\hbox\{}$\langle$string$\rangle$\.\}' for
  2825  a given string of ASCII characters, using either the title font or the
  2826  label font.
  2827  
  2828  The |hbox| procedure does this. The width, height, and depth of the
  2829  box defined by string~|s| in font~|f| are computed in global variables
  2830  |box_width|, |box_height|, and |box_depth|.
  2831  
  2832  The task would be trivial if it weren't for ligatures and kerns, which
  2833  are implemented here in full generality. (Infinite looping is possible
  2834  if the \.{TFM} file is malformed; \.{TFtoPL} will diagnose such problems.)
  2835  
  2836  We assume that |" "| is a space character; character code @'40 will not
  2837  be typeset unless it is accessed via a ligature.
  2838  
  2839  If parameter |send_it| is |false|, we merely want to know the box dimensions.
  2840  Otherwise typesetting commands are also sent to
  2841  the \.{DVI} file; we assume in this case that font |f| has already been
  2842  selected 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);
  2848  label continue, done;
  2849  var @!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}
  2860  begin box_width:=0; box_height:=0; box_depth:=0;@/
  2861  k:=str_start[s]; max_k:=str_start[s+1];
  2862  save_c:=str_pool[max_k]; str_pool[max_k]:=" ";
  2863  while 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;
  2869  continue: @<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;
  2878  str_pool[max_k]:=save_c;
  2879  end;
  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...@>=
  2890  dummy_info.b0:=qi(0); dummy_info.b1:=qi(0); dummy_info.b2:=qi(0);
  2891  dummy_info.b3:=qi(0);
  2892  
  2893  @ @<Typeset a space...@>=
  2894  begin box_width:=box_width+space(f);
  2895  if send_it then
  2896    begin dvi_out(right4); dvi_four(space(f));
  2897    end;
  2898  incr(k);
  2899  end
  2900  
  2901  @ @<If there's a ligature...@>=
  2902  if(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
  2906  else 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;
  2912  if suppress_lig then suppress_lig:=false
  2913  else 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;
  2925  done:
  2926  
  2927  @ At this point |i| contains |char_info| for |cur_l|.
  2928  
  2929  @<Typeset character...@>=
  2930  if 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...@>=
  2952  begin case op_byte(j) of
  2953  1,5:cur_l:=qo(rem_byte(j));
  2954  2,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;
  2962  3,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;
  2965  othercases 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
  2971  endcases;
  2972  if op_byte(j)>3 then goto done;
  2973  goto continue;
  2974  end
  2975  
  2976  @ @<Move the cursor to the right and |goto continue|...@>=
  2977  cur_l:=qo(cur_r);
  2978  if stack_ptr>0 then
  2979    begin pop_stack; goto continue;
  2980    end;
  2981  if k<end_k then
  2982    begin incr(k); set_cur_r; goto continue;
  2983    end
  2984  
  2985  @* Gray fonts.
  2986  A proof diagram constructed by \.{GFtoDVI}
  2987  can be regarded as an array of rectangles, where each rectangle is either
  2988  blank or filled with a special symbol that we shall call $x$. A blank
  2989  rectangle represents a white pixel, while $x$ represents a black pixel.
  2990  Additional labels and reference lines are often superimposed on this
  2991  array of rectangles; hence it is usually best to choose a symbol $x$ that
  2992  has a somewhat gray appearance, although any symbol can actually be used.
  2993  
  2994  In order to construct such proofs, \.{GFtoDVI} needs to work with
  2995  a special type of font known as a ``gray font''; it's possible to
  2996  obtain a wide variety of different sorts of proofs by using different
  2997  sorts of gray fonts. The next few paragraphs explain exactly what gray
  2998  fonts 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$
  3002  and another symbol that is used for dots that identify key points.
  3003  If proofs with relatively large pixels are desired, a two-character
  3004  gray font is all that's needed. However, if the pixel size is to be
  3005  relatively small, practical considerations make a two-character
  3006  font too inefficient, since it requires the typesetting of tens
  3007  of thousands of tiny little characters; printing device drivers
  3008  rarely work very well when they are presented with data that is
  3009  so different from ordinary text. Therefore a gray font with small
  3010  pixels usually has a number of characters that replicate $x$ in
  3011  such a way that comparatively few characters actually need to be
  3012  typeset.
  3013  
  3014  Since many printing devices are not able to cope with
  3015  arbitrarily large or complex characters, it is not possible for a
  3016  single gray font to work well on all machines. In fact,
  3017  $x$ must have a width that is an integer multiple of the printing
  3018  device's unit of horizontal position, since rounding the positions of grey
  3019  characters would otherwise produce unsightly streaks on proof output.
  3020  Thus, there is no way to make the gray font as device-independent as
  3021  the rest of the system, in the sense that we would expect approximately
  3022  identical output on machines with different resolution. Fortunately,
  3023  proof sheets are rarely considered to be final documents; hence
  3024  \.{GFtoDVI} is set up to provide results that adapt suitably to
  3025  local 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
  3029  appears in position~1. It must have positive height~$h$ and positive
  3030  width~$w$; its depth and italic correction are ignored.
  3031  
  3032  Positions 2--120 of a gray font are reserved for special combinations
  3033  of $x$'s and blanks, stacked on top of each other. None of these character
  3034  codes need be present in the font; but if they are, the slots should be
  3035  occupied by characters of width~$w$ that have certain configurations of
  3036  $x$'s and blanks, prescribed for each character position. For example,
  3037  position~3 of the font should either contain no character at all,
  3038  or it should contain a character consisting of two $x$'s, one above
  3039  the other; one of these $x$'s should appear immediately above the
  3040  baseline, and the other should appear immediately below.
  3041  
  3042  It will be convenient to use a horizontal notation like `\.{XOXXO}'
  3043  to stand for a vertical stack of $x$'s and blanks. The convention
  3044  will be that the stack is built from bottom to top, and the topmost
  3045  rectangle should sit on the baseline. Thus, `\.{XOXXO}' stands
  3046  actually for a character of depth~$4h$ that looks like this:
  3047  $$\vcenter{\halign{\hfil#\hfil\cr
  3048  blank\cr
  3049  $x$\rlap{\qquad\raise8pt\hbox{\smash{\hbox{$\longleftarrow$ baseline}}}}\cr
  3050  $x$\cr
  3051  blank\cr
  3052  $x$\cr
  3053  }}$$
  3054  (We use a horizontal notation instead of a vertical one in this explanation,
  3055  because column
  3056  vectors take too much space, and because the horizontal notation corresponds
  3057  to binary numbers in a convenient way.)
  3058  
  3059  Positions 1--63 of a gray font are reserved for the patterns \.X, \.{XO},
  3060  \.{XX}, \.{XOO}, \.{XOX}, \dots, \.{XXXXXX}, just as in the normal
  3061  binary notation of the numbers 1--63. Positions 64--70 are reserved for
  3062  the special patterns \.{XOOOOOO}, \.{XXOOOOO}, \dots, \.{XXXXXXO},
  3063  \.{XXXXXXX} of length seven; positions 71--78 are, similarly, reserved for
  3064  the length-eight patterns \.{XOOOOOOO} through \.{XXXXXXXX}. The
  3065  length-nine patterns \.{XOOOOOOOO} through \.{XXXXXXXXX} are assigned
  3066  to positions 79--87, the length-ten patterns to positions 88--97,
  3067  the length-eleven patterns to positions 98--108, and the length-twelve
  3068  patterns to positions 109--120.
  3069  
  3070  The following program sets a global array |c[1..120]| to the bit patterns
  3071  just described. Another array |d[1..120]| is set to contain only the next
  3072  higher bit; this determines the depth of the corresponding character.
  3073  
  3074  @<Set init...@>=
  3075  c[1]:=1; d[1]:=2; two_to_the[0]:=1; m:=1;
  3076  for k:=1 to 13 do two_to_the[k]:=2*two_to_the[k-1];
  3077  for k:=2 to 6 do @<Add a full set of |k|-bit characters@>;
  3078  for 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...@>=
  3086  begin n:=two_to_the[k-1];
  3087  for j:=0 to n-1 do
  3088    begin incr(m); c[m]:=m; d[m]:=n+n;
  3089    end;
  3090  end
  3091  
  3092  @ @<Add special |k|-bit...@>=
  3093  begin n:=two_to_the[k-1];
  3094  for 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;
  3099  end
  3100  
  3101  @ Position 0 of a gray font is reserved for the ``dot'' character, which
  3102  should have positive height~$h'$ and positive width~$w'$. When \.{GFtoDVI}
  3103  wants to put a dot at some place $(x,y)$ on the figure, it positions
  3104  the dot character so that its reference point is at $(x,y)$. The
  3105  dot will be considered to occupy a rectangle $(x+\delta,y+\epsilon)$
  3106  for $-w'\leq\delta\leq w'$ and $-h'\leq\epsilon\leq h'$; the rectangular
  3107  box 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)
  3110  are unreserved, in the sense that they have no predefined meaning.
  3111  But \.{GFtoDVI} may access them via the ``character list'' feature of
  3112  \.{TFM} files, starting with any of the characters in positions
  3113  1--120. In such a case each succeeding character in a list should be
  3114  equivalent to two of its predecessors, horizontally adjacent to each other.
  3115  For example, in a character list like
  3116  $$53,\;121,\;122,\;123$$
  3117  character 121 will stand for two 53's, character 122 for two 121's (i.e.,
  3118  four 53's), and character 123 for two 122's (i.e., eight 53's). Since
  3119  position~53 contains the pattern \.{XXOXOX}, character~123 in this example
  3120  would have height~$h$, depth~$5h$, and width~$8w$, and it would stand for
  3121  the pattern
  3122  $$\vcenter{\halign{&$\hfil#\hfil$\cr
  3123  x&x&x&x&x&x&x&x\cr
  3124  &&&&&&&\cr
  3125  x&x&x&x&x&x&x&x\cr
  3126  &&&&&&&\cr
  3127  x&x&x&x&x&x&x&x\cr
  3128  x&x&x&x&x&x&x&x\cr}}$$
  3129  Such a pattern is, of course, rather unlikely to occur in a \.{GF} file,
  3130  but \.{GFtoDVI} would be able to use if it were present. Designers
  3131  of gray fonts should provide characters only for patterns that they think
  3132  will occur often enough to make the doubling worthwhile. For example,
  3133  the character in position 120 (\.{XXXXXXXXXXXX}), or whatever is the
  3134  tallest stack of $x$'s present in the font, is a natural candidate for
  3135  repeated doubling.
  3136  
  3137  Here's how \.{GFtoDVI} decides what characters of the gray font will be used,
  3138  given a configuration of black and white pixels: If there are no black
  3139  pixels, stop. Otherwise look at the top row that contains at least one
  3140  black pixel, and the eleven rows that follow. For each such column,
  3141  find the largest~$k$ such that $1\leq k\leq120$ and the gray font contains
  3142  character~$k$ and the pattern assigned to position~$k$ appears in the
  3143  given column. Typeset character $k$ (unless no such character exists)
  3144  and erase the corresponding black pixels; use doubled characters,
  3145  if they are present in the gray font, if two or more consecutive equal
  3146  characters need to be typeset. Repeat the same process on the remaining
  3147  configuration, until all the black pixels have been erased.
  3148  
  3149  If all characters in positions 1--120 are present, this process is guaranteed to
  3150  take care of at least six rows each time; and it usually takes care of
  3151  twelve, since all patterns that contain at most one ``run'' of $x$'s
  3152  are 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
  3156  slant parameter~$s$, if nonzero, will cause \.{GFtoDVI} to skew its
  3157  output; in this case the character $x$ will presumably be a parallelogram
  3158  with a corresponding slant, rather than the usual rectangle. \MF's
  3159  coordinate $(x,y)$ will appear in physical position $(xw+yhs,yh)$
  3160  on the proofsheets.
  3161  
  3162  Parameter number~8 of a gray font specifies the thickness of rules
  3163  that go on the proofs. If this parameter is zero, \TeX's default
  3164  rule thickness (0.4\thinspace pt) will be used.
  3165  
  3166  The other parameters of a gray font are ignored by \.{GFtoDVI}, but
  3167  it is conventional to set the font space parameter to~$w$ and the
  3168  xheight parameter to~$h$.
  3169  
  3170  @ For best results the designer of a gray font should choose $h$ and~$w$
  3171  so that the user's \.{DVI}-to-hardcopy software will not make any
  3172  rounding errors. Furthermore, the dot should be an even number~$2m$ of
  3173  pixels in diameter, and the rule thickness should work out to an
  3174  even number~$2n$ of pixels; then the dots and rules will be centered on
  3175  the correct positions, in case of integer coordinates. Gray fonts
  3176  are almost always intended for particular output devices, even though
  3177  `\.{DVI}' stands for `device independent'; we use \.{DVI} files for \MF\
  3178  proofs 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
  3182  necessary 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  
  3185  A slant font should contain exactly $n$ characters, in positions 1 to~$n$,
  3186  where the character in position~$k$ represents a slanted line $k$ units
  3187  tall, starting at the baseline. These lines all have a fixed slant ratio~$s$.
  3188  
  3189  The following simple algorithm is used to typeset a rule that is $m$ units
  3190  high: Compute $q=\lceil m/n\rceil$; then typeset $q$~characters of
  3191  approximately 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$;
  3194  a 100-unit-high rule will be composed of 7~pieces, using characters
  3195  14,~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
  3205  need not be accurate about the heights of the other characters. (This is
  3206  fortunate, since \.{TFM} format allows at most 16 different heights per font.)
  3207  
  3208  The width of character~$k$ should be $k/n$ times $s$ times the height of
  3209  character~$n$.
  3210  
  3211  The slant parameter of a slant file should be $s$. It is customary to
  3212  set the |default_rule_thickness| parameter (number~8) to the thickness of
  3213  the slanted rules, but \.{GFtoDVI} doesn't look at it.
  3214  
  3215  @ For best results on a particular output device, it is usually wise to
  3216  choose the `unit' in the above discussion to be an integer number of pixels,
  3217  and to make it no larger than the default rule thickness in the gray font
  3218  being used.
  3219  
  3220  @ @<Initialize glob...@>=
  3221  if length(font_name[slant_font])=0 then rule_slant:=0.0
  3222  else  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;
  3227  slant_reported:=0.0;
  3228  
  3229  @ The following error message is given when an absent slant has been
  3230  requested.
  3231  
  3232  @p procedure slant_complaint(@!r:real);
  3233  begin 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;
  3238  end;
  3239  
  3240  @* Representation of rectangles.
  3241  OK---the preliminary spadework has now been done. We're ready at last
  3242  to concentrate on \.{GFtoDVI}'s {\sl raison d'\^^Detre}.
  3243  
  3244  One of the most interesting tasks remaining is to make
  3245  a ``map'' of the labels that have been allocated.
  3246  There usually aren't a great many labels, so we don't need fancy data
  3247  structures; but we do make use of linked nodes containing nine fields.
  3248  The nodes generally represent rectangular boxes according to the
  3249  following conventions:
  3250  \smallskip\hang\noindent
  3251  |xl|, |xr|, |yt|, and |yb| are the left, right, top, and bottom locations
  3252  of a rectangle, expressed in \.{DVI} coordinates. (This program uses
  3253  scaled points as \.{DVI} coordinates. Since \.{DVI} coordinates increase
  3254  as 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
  3257  typeset from this node, again in \.{DVI} coordinates.
  3258  \smallskip\hang\noindent
  3259  |prev| and |next| point to the predecessor and successor of this node.
  3260  Sometimes the nodes are singly linked and only |next| is relevant; otherwise
  3261  the nodes are doubly linked in order of their |yy| coordinates, so that we
  3262  can 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  
  3267  The nine fields of a node appear in nine global arrays.
  3268  Null 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;
  3288  begin incr(max_node);
  3289  if max_node=max_labels then abort('Too many labels and/or rules!');
  3290  @.Too many labels@>
  3291  get_avail:=max_node;
  3292  end;
  3293  
  3294  @ The doubly linked nodes are sorted by |yy| coordinates so that we don't have
  3295  to work too hard to find nearest neighbors or to determine if rectangles overlap.
  3296  The first node in the doubly linked rectangle list is always in location~0,
  3297  and the last node is always in location |max_labels|; the |yy| coordinates
  3298  of these nodes are very small and very large, respectively.
  3299  
  3300  @d end_of_list==max_labels
  3301  
  3302  @<Set init...@>=
  3303  yy[0]:=-@'10000000000; yy[end_of_list]:=@'10000000000;
  3304  
  3305  @ The |node_ins| procedure inserts a new rectangle, represented by node~|p|,
  3306  into the doubly linked list. There's a second parameter, |q|; node~|q| should
  3307  already be in the doubly linked list, preferably with |yy[q]| near |yy[p]|.
  3308  
  3309  @p procedure node_ins(@!p,@!q:node_pointer);
  3310  var @!r:node_pointer; {for tree traversal}
  3311  begin 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
  3315  else  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;
  3318  if yy[p]-yt[p]>max_height then max_height:=yy[p]-yt[p];
  3319  if yb[p]-yy[p]>max_depth then max_depth:=yb[p]-yy[p];
  3320  end;
  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@>=
  3326  max_node:=0; next[0]:=end_of_list; prev[end_of_list]:=0;
  3327  max_height:=0; max_depth:=0;
  3328  
  3329  @ The |overlap| subroutine determines whether or not the rectangle specified
  3330  in node~|p| has a nonempty intersection with some rectangle in the doubly
  3331  linked list. Again |q|~is a parameter that gives us a starting point
  3332  in 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;
  3335  label exit;
  3336  var @!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|}
  3339  begin 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@>;
  3342  overlap:=false;
  3343  exit: end;
  3344  
  3345  @ @<Look for overlaps in the successors of node |q|@>=
  3346  y_thresh:=y_bot+max_height; r:=next[q];
  3347  while 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@>=
  3356  y_thresh:=y_top-max_depth; r:=q;
  3357  while 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
  3366  constraints:
  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  
  3372  The |nearest_dot| subroutine finds a node whose reference point is as
  3373  close as possible to a given position, ignoring nodes that are too close.
  3374  More precisely, the ``nearest'' node
  3375  minimizes$$d(q,p)=\max\bigl(\vert |xx|[q]-|xx|[p]\vert,
  3376    \vert |yy|[q]-|yy|[p]\vert\bigr)$$ over all nodes~|q|
  3377  with |d(q,p)>=d0|. We call the subroutine |nearest_dot| because it is used only
  3378  when the doubly linked list contains nothing but dots.
  3379  
  3380  The routine also sets the global variable |twin| to |true|, if there is a
  3381  node |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;
  3388  otherwise a pointer to the nearest dot is returned.
  3389  
  3390  @p function nearest_dot(@!p:node_pointer; @!d0:scaled):node_pointer;
  3391  var @!best_q:node_pointer; {value to return}
  3392  @!d_min,@!d:scaled; {distances}
  3393  begin 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|@>;
  3396  nearest_dot:=best_q;
  3397  end;
  3398  
  3399  @ @<Search for the nearest dot in nodes following |p|@>=
  3400  q:=next[p];
  3401  while 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|@>=
  3412  q:=prev[p];
  3413  while 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.
  3424  Each ``character'' in the \.{GF} file is preceded by a number of special
  3425  commands that define labels, titles, rules, etc. We store these away,
  3426  to be considered later when the |boc| command appears. The |boc|
  3427  command establishes the size information by which labels and rules
  3428  can be positioned, so we spew out the label information as soon as
  3429  we see the |boc|. The gray pixels will be typeset after all the labels
  3430  for a particular character have been finished.
  3431  
  3432  @ Here is the part of \.{GFtoDVI} that stores information preceding a~|boc|.
  3433  It 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@>=
  3442  begin k:=interpret_xxx;
  3443  case k of
  3444  no_operation: do_nothing;
  3445  title_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);
  3447  title_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);
  3450  title_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);
  3453  rule_thickness_code:rule_thickness:=get_yyy;
  3454  rule_code:@<Store a rule@>;
  3455  offset_code:@<Override the offsets@>;
  3456  x_offset_code:x_offset:=get_yyy;
  3457  y_offset_code:y_offset:=get_yyy;
  3458  title_code:@<Store a title@>;
  3459  null_string:@<Store a label@>;
  3460  end; {there are no other cases}
  3461  end
  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@>=
  3475  rule_thickness:=0;
  3476  offset_x:=0; offset_y:=0; x_offset:=0; y_offset:=0;
  3477  pre_min_x:=@'2000000000; pre_max_x:=-@'2000000000;
  3478  pre_min_y:=@'2000000000; pre_max_y:=-@'2000000000;
  3479  
  3480  @ @<Override the offsets@>=
  3481  begin offset_x:=get_yyy; offset_y:=get_yyy;
  3482  end
  3483  
  3484  @ Rules that will need to be drawn are kept in a linked list accessible
  3485  via |rule_ptr|, in last-in-first-out order.  The nodes of this list will
  3486  never get into the doubly linked list, and indeed these nodes use different
  3487  field 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@>=
  3499  begin p:=get_avail; next[p]:=rule_ptr; rule_ptr:=p;@/
  3500  x0[p]:=get_yyy; y0[p]:=get_yyy; x1[p]:=get_yyy; y1[p]:=get_yyy;
  3501  if x0[p]<pre_min_x then pre_min_x:=x0[p];
  3502  if x0[p]>pre_max_x then pre_max_x:=x0[p];
  3503  if y0[p]<pre_min_y then pre_min_y:=y0[p];
  3504  if y0[p]>pre_max_y then pre_max_y:=y0[p];
  3505  if x1[p]<pre_min_x then pre_min_x:=x1[p];
  3506  if x1[p]>pre_max_x then pre_max_x:=x1[p];
  3507  if y1[p]<pre_min_y then pre_min_y:=y1[p];
  3508  if y1[p]>pre_max_y then pre_max_y:=y1[p];
  3509  rule_size[p]:=rule_thickness;
  3510  end
  3511  
  3512  @ Titles and labels are, likewise, stored temporarily in singly linked lists.
  3513  In this case the lists are first-in-first-out.
  3514  Variables |title_tail| and |label_tail| point to the most recently inserted
  3515  title or label; variables |title_head| and |label_head|
  3516  point to the beginning of the list. (A standard coding trick is used
  3517  for |label_head|, which is kept in |next[end_of_list]|; we have
  3518  |label_tail=end_of_list| when the list is empty.)
  3519  
  3520  The |prev| field in nodes of the temporary label list specifies the
  3521  type 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...@>=
  3533  rule_ptr:=null;
  3534  title_head:=null; title_tail:=null; label_head:=null; label_tail:=end_of_list;
  3535  first_dot:=max_labels;
  3536  
  3537  @ @<Store a title@>=
  3538  begin p:=get_avail; info[p]:=cur_string;
  3539  if title_head=null then title_head:=p
  3540  else next[title_tail]:=p;
  3541  title_tail:=p;
  3542  end
  3543  
  3544  @ We store the coordinates of each label in units of \MF\ pixels; they
  3545  will be converted to \.{DVI} coordinates later.
  3546  
  3547  @<Store a label@>=
  3548  if (label_type<"/")or(label_type>"8") then
  3549    print_nl('Bad label type precedes byte ',cur_loc:1,'!')
  3550  @.Bad label type...@>
  3551  else  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
  3561  when a |boc| command is sensed. The following steps are performed
  3562  at such times:
  3563  
  3564  @<Process a character@>=
  3565  begin 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@>;
  3569  print('[',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@>;
  3572  do_pixels;
  3573  dvi_out(eop); {finish the page}
  3574  @<Adjust the maximum page width@>;
  3575  print(']'); update_terminal;
  3576  end
  3577  
  3578  @ @<Finish reading the parameters of the |boc|@>=
  3579  if 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
  3590  else  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;
  3594  if 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
  3604  following routine. Real values |x_ratio|, |y_ratio|, and |slant_ratio|
  3605  will 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
  3607  of slanting and offsets, the \MF\ coordinates |(min_x,max_y+1)| will correspond
  3608  to the \.{DVI} coordinates $(0,50\,\rm pt)$.
  3609  
  3610  @p procedure convert(@!x,@!y:scaled);
  3611  begin x:=x+x_offset; y:=y+y_offset;
  3612  dvi_y:=-round(y_ratio*y)+delta_y;
  3613  dvi_x:=round(x_ratio*x+slant_ratio*y)+delta_x;
  3614  end;
  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@>=
  3627  i:=char_info(gray_font)(1);
  3628  if not char_exists(i) then abort('Missing pixel char!');
  3629  @.Missing pixel char@>
  3630  unsc_x_ratio:=char_width(gray_font)(i);
  3631  x_ratio:=unsc_x_ratio/unity;
  3632  unsc_y_ratio:=char_height(gray_font)(height_depth(i));
  3633  y_ratio:=unsc_y_ratio/unity;
  3634  unsc_slant_ratio:=slant(gray_font)*y_ratio;
  3635  slant_ratio:=unsc_slant_ratio/unity;
  3636  if x_ratio*y_ratio=0 then abort('Vanishing pixel size!');
  3637  @.Vanishing pixel size@>
  3638  fudge_factor:=(slant_ratio/x_ratio)/y_ratio;
  3639  
  3640  @ @<Get ready to convert...@>=
  3641  if pre_min_x<min_x*unity then offset_x:=offset_x+min_x*unity-pre_min_x;
  3642  if pre_max_y>max_y*unity then offset_y:=offset_y+max_y*unity-pre_max_y;
  3643  if pre_max_x>max_x*unity then pre_max_x:=pre_max_x div unity
  3644  else pre_max_x:=max_x;
  3645  if pre_min_y<min_y*unity then pre_min_y:=pre_min_y div unity
  3646  else pre_min_y:=min_y;
  3647  delta_y:=round(unsc_y_ratio*(max_y+1)-y_ratio*offset_y)+3276800;
  3648  delta_x:=round(x_ratio*offset_x-unsc_x_ratio*min_x);
  3649  if slant_ratio>=0 then
  3650    over_col:=round(unsc_x_ratio*pre_max_x+unsc_slant_ratio*max_y)
  3651  else over_col:=round(unsc_x_ratio*pre_max_x+unsc_slant_ratio*min_y);
  3652  over_col:=over_col+delta_x+10000000;
  3653  page_height:=round(unsc_y_ratio*(max_y+1-pre_min_y))+3276800-offset_y;
  3654  if page_height>max_v then max_v:=page_height;
  3655  page_width:=over_col-10000000
  3656  
  3657  @ The |dvi_goto| subroutine outputs bytes to the \.{DVI} file that
  3658  will initiate typesetting at given \.{DVI} coordinates, assuming that
  3659  the current position of the \.{DVI} reader is $(0,0)$. This subroutine
  3660  begins by outputting a |push| command; therefore, a |pop| command should
  3661  be given later. That |pop| will restore the \.{DVI} position to $(0,0)$.
  3662  
  3663  @p procedure dvi_goto(@!x,@!y:scaled);
  3664  begin dvi_out(push);
  3665  if x<>0 then
  3666    begin dvi_out(right4); dvi_four(x);
  3667    end;
  3668  if y<>0 then
  3669    begin dvi_out(down4); dvi_four(y);
  3670    end;
  3671  end;
  3672  
  3673  @ @<Output the |bop| and the title line@>=
  3674  dvi_out(bop); incr(total_pages); dvi_four(total_pages);
  3675  dvi_four(char_code); dvi_four(ext);
  3676  for k:=3 to 9 do dvi_four(0);
  3677  dvi_four(last_bop); last_bop:=dvi_offset+dvi_ptr-45;@/
  3678  dvi_goto(0,655360); {the top baseline is 10\thinspace pt down}
  3679  if use_logo then
  3680    begin select_font(logo_font); hbox(small_logo,logo_font,true);
  3681    end;
  3682  select_font(title_font); hbox(time_stamp,title_font,true);@/
  3683  hbox(page_header,title_font,true); dvi_scaled(total_pages*65536.0);@/
  3684  if (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;
  3690  if 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;
  3698  dvi_out(pop)
  3699  
  3700  @ @d tol==6554 {one tenth of a point, in \.{DVI} coordinates}
  3701  
  3702  @<Output all rules for the current character@>=
  3703  if rule_slant<>0 then select_font(slant_font);
  3704  while 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...@>=
  3721  gray_rule_thickness:=default_rule_thickness(gray_font);
  3722  if gray_rule_thickness=0 then gray_rule_thickness:=26214; {0.4\thinspace pt}
  3723  
  3724  @ @<Output a vertical rule@>=
  3725  begin if temp_y>dvi_y then
  3726    begin k:=temp_y; temp_y:=dvi_y; dvi_y:=k;
  3727    end;
  3728  dvi_goto(dvi_x-(rule_size[p] div 2), dvi_y);
  3729  dvi_out(put_rule); dvi_four(dvi_y-temp_y); dvi_four(rule_size[p]);
  3730  dvi_out(pop);
  3731  end
  3732  
  3733  @ @<Output a horizontal rule@>=
  3734  begin if temp_x<dvi_x then
  3735    begin k:=temp_x; temp_x:=dvi_x; dvi_x:=k;
  3736    end;
  3737  dvi_goto(dvi_x,dvi_y+(rule_size[p] div 2));
  3738  dvi_out(put_rule); dvi_four(rule_size[p]); dvi_four(temp_x-dvi_x);
  3739  dvi_out(pop);
  3740  end
  3741  
  3742  @ @<Try to output a diagonal rule@>=
  3743  if (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))
  3746  else  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|@>=
  3762  typeset(k); dy:=round(k*slant_unit); dvi_out(z4); dvi_four(-dy);
  3763  while q>1 do
  3764    begin typeset(k); dvi_out(z0); decr(q);
  3765    end
  3766  
  3767  @ @<Vertically typeset |p| copies of character |k+1|@>=
  3768  if 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
  3777  go through the stored labels and try to fit them in the illustration for
  3778  the current character, together with their associated dots.
  3779  
  3780  It would simplify font-switching slightly if we were to typeset the labels
  3781  first, but we find it desirable to typeset the dots first and then turn to the
  3782  labels. This procedure makes it possible for us to allow the dots to
  3783  overlap each other without allowing the labels to overlap. After the
  3784  dots 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
  3786  each other.
  3787  
  3788  @<Output all labels for the current character@>=
  3789  overflow_line:=1;
  3790  if 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
  3804  rectangle 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|,
  3806  and $\Delta$ is an additional amount of blank space that keeps labels from
  3807  coming too close to each other. (\.{GFtoDVI} arbitrarily defines $\Delta$
  3808  to be one half the width of a space in the label font.) This label is
  3809  centered over its dot, with its baseline $d+h'$ above the center of the dot;
  3810  here $h'=|dot_height|$ is the height of character~0 in the gray font.
  3811  
  3812  Similarly, a label that appears below its dot is considered to occupy
  3813  a rectangle of height~$h$, depth~$d+\Delta$, and width~$w+2\Delta$; the
  3814  baseline is $h+h'$ below the center of the dot.
  3815  
  3816  A label at the right of its dot is considered to occupy a rectangle of
  3817  height~$h+\Delta$, depth~$d+\Delta$, and width~$w+\Delta$. Its
  3818  reference point can be found by starting at the center of the dot and
  3819  moving right $w'=|dot_width|$ (i.e., the width of character~0 in the
  3820  gray font), then moving down by half the x-height of the label font.
  3821  A label at the left of its dot is similar.
  3822  
  3823  A dot is considered to occupy a rectangle of height $2h'$ and width~$2w'$,
  3824  centered on the dot.
  3825  
  3826  When the label type is |"1"| or more, the labels
  3827  are put into the doubly linked list unconditionally.
  3828   Otherwise they are put into the list
  3829  only if we can find a way to fit them in without
  3830  overlapping 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@>=
  3839  i:=char_info(gray_font)(0);
  3840  if not char_exists(i) then abort('Missing dot char!');
  3841  @.Missing dot char@>
  3842  dot_width:=char_width(gray_font)(i);
  3843  dot_height:=char_height(gray_font)(height_depth(i));
  3844  delta:=space(label_font) div 2;
  3845  thrice_x_height:=3*x_height(label_font);
  3846  half_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.
  3851  The coordinates of the dot's center are assumed given in |dvi_x|
  3852  and |dvi_y|; the |hbox| subroutine is assumed to have
  3853  already computed the height, width, and depth of the label box.
  3854  
  3855  @p procedure top_coords(@!p:node_pointer);
  3856  begin xx[p]:=dvi_x-(box_width div 2); xl[p]:=xx[p]-delta;
  3857  xr[p]:=xx[p]+box_width+delta;@/
  3858  yb[p]:=dvi_y-dot_height; yy[p]:=yb[p]-box_depth;
  3859  yt[p]:=yy[p]-box_height-delta;
  3860  end;
  3861  
  3862  @ The other three label positions are handled by similar routines.
  3863  
  3864  @p procedure bot_coords(@!p:node_pointer);
  3865  begin xx[p]:=dvi_x-(box_width div 2); xl[p]:=xx[p]-delta;
  3866  xr[p]:=xx[p]+box_width+delta;@/
  3867  yt[p]:=dvi_y+dot_height; yy[p]:=yt[p]+box_height;
  3868  yb[p]:=yy[p]+box_depth+delta;
  3869  end;
  3870  @#
  3871  procedure right_coords(@!p:node_pointer);
  3872  begin xl[p]:=dvi_x+dot_width; xx[p]:=xl[p]; xr[p]:=xx[p]+box_width+delta;@/
  3873  yy[p]:=dvi_y+half_x_height; yb[p]:=yy[p]+box_depth+delta;
  3874  yt[p]:=yy[p]-box_height-delta;
  3875  end;
  3876  @#
  3877  procedure left_coords(@!p:node_pointer);
  3878  begin xr[p]:=dvi_x-dot_width; xx[p]:=xr[p]-box_width; xl[p]:=xx[p]-delta;@/
  3879  yy[p]:=dvi_y+half_x_height; yb[p]:=yy[p]+box_depth+delta;
  3880  yt[p]:=yy[p]-box_height-delta;
  3881  end;
  3882  
  3883  @ @<Output all dots@>=
  3884  p:=label_head; first_dot:=max_node+1;
  3885  while 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...@>=
  3900  begin q:=get_avail; dot_for_label[p]:=q; label_for_dot[q]:=p;@/
  3901  xx[q]:=dvi_x; xl[q]:=dvi_x-dot_width; xr[q]:=dvi_x+dot_width;@/
  3902  yy[q]:=dvi_y; yt[q]:=dvi_y-dot_height; yb[q]:=dvi_y+dot_height;@/
  3903  node_ins(q,0);@/
  3904  dvi_goto(xx[q],yy[q]); dvi_out(0); dvi_out(pop);
  3905  end
  3906  
  3907  @ Prescribed labels are now taken out of the singly linked list and
  3908  inserted into the doubly linked list.
  3909  
  3910  @<Output all prescribed labels@>=
  3911  q:=end_of_list; {|label_head=next[q]|}
  3912  while 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...@>=
  3923  begin hbox(info[p],label_font,false); {Compute the size of this label}
  3924  dvi_x:=xx[p];  dvi_y:=yy[p];
  3925  if lab_typ[p]<"5" then r:=dot_for_label[p]@+else r:=0;
  3926  case 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);
  3931  end; {no other cases are possible}
  3932  node_ins(p,r);@/
  3933  dvi_goto(xx[p],yy[p]); hbox(info[p],label_font,true); dvi_out(pop);
  3934  end
  3935  
  3936  @ \.{GFtoDVI}'s algorithm for positioning the ``floating'' labels
  3937  was devised by Arthur~L. Samuel.
  3938  @^Samuel, Arthur Lee@>
  3939  It tries to place labels in a priority order, based on the position of
  3940  the nearest dot to a given dot. If that dot, for example, lies in the first
  3941  octant (i.e., east to northeast of the given dot), the given label will
  3942  be put into the west slot unless that slot is already blocked; then the
  3943  south slot will be tried, etc.
  3944  
  3945  First we need to compute the octants. We also note if two or more dots
  3946  are nearly coincident, since Samuel's algorithm modifies the priority
  3947  order 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@>=
  3952  p:=label_head;
  3953  while 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
  3960  code shown here. (Remember that |y|~coordinates increase downward
  3961  in 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|@>=
  3973  begin r:=dot_for_label[p]; q:=nearest_dot(r,10);
  3974  if twin then octant[p]:=8@+else octant[p]:=0;
  3975  if 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;
  3982  end
  3983  
  3984  @ A procedure called |place_label| will try to place the remaining
  3985  labels in turn. If it fails, we ``disconnect'' the dot from this
  3986  label so that an unlabeled dot will not appear as a reference in the
  3987  overflow column.
  3988  
  3989  @<Output all attachable labels@>=
  3990  q:=end_of_list; {now |next[q]=label_head|}
  3991  while 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
  4002  is inserted into the rectangle list and typeset.
  4003  
  4004  @p function place_label(@!p:node_pointer):boolean;
  4005  label exit, found;
  4006  var @!oct:0..15; {octant code}
  4007  @!dfl:node_pointer; {saved value of |dot_for_label[p]|}
  4008  begin hbox(info[p],label_font,false); {Compute the size of this label}
  4009  dvi_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|@>;
  4012  found:node_ins(p,dfl);@/
  4013  dvi_goto(xx[p],yy[p]); hbox(info[p],label_font,true); dvi_out(pop);
  4014  place_label:=true;
  4015  exit:end;
  4016  
  4017  @ @<Find non-overlapping coordinates, if possible...@>=
  4018  dfl:=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@>;
  4023  xx[p]:=dvi_x;  yy[p]:=dvi_y; dot_for_label[p]:=dfl; {no luck; restore the coordinates}
  4024  place_label:=false; return
  4025  
  4026  @ @<Try the first choice for label direction@>=
  4027  case oct of
  4028  first_octant,eighth_octant,second_octant+8,seventh_octant+8: left_coords(p);
  4029  second_octant,third_octant,first_octant+8,fourth_octant+8: bot_coords(p);
  4030  fourth_octant,fifth_octant,third_octant+8,sixth_octant+8: right_coords(p);
  4031  sixth_octant,seventh_octant,fifth_octant+8,eighth_octant+8: top_coords(p);
  4032  end;
  4033  if not overlap(p,dfl) then goto found
  4034  
  4035  @ @<Try the second choice for label direction@>=
  4036  case oct of
  4037  first_octant,fourth_octant,fifth_octant+8,eighth_octant+8: bot_coords(p);
  4038  second_octant,seventh_octant,third_octant+8,sixth_octant+8: left_coords(p);
  4039  third_octant,sixth_octant,second_octant+8,seventh_octant+8: right_coords(p);
  4040  fifth_octant,eighth_octant,first_octant+8,fourth_octant+8: top_coords(p);
  4041  end;
  4042  if not overlap(p,dfl) then goto found
  4043  
  4044  @ @<Try the third choice for label direction@>=
  4045  case oct of
  4046  first_octant,fourth_octant,sixth_octant+8,seventh_octant+8: top_coords(p);
  4047  second_octant,seventh_octant,fourth_octant+8,fifth_octant+8: right_coords(p);
  4048  third_octant,sixth_octant,first_octant+8,eighth_octant+8: left_coords(p);
  4049  fifth_octant,eighth_octant,second_octant+8,third_octant+8: bot_coords(p);
  4050  end;
  4051  if not overlap(p,dfl) then goto found
  4052  
  4053  @ @<Try the fourth choice for label direction@>=
  4054  case oct of
  4055  first_octant,eighth_octant,first_octant+8,eighth_octant+8: right_coords(p);
  4056  second_octant,third_octant,second_octant+8,third_octant+8: top_coords(p);
  4057  fourth_octant,fifth_octant,fourth_octant+8,fifth_octant+8: left_coords(p);
  4058  sixth_octant,seventh_octant,sixth_octant+8,seventh_octant+8: bot_coords(p);
  4059  end;
  4060  if 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@>;
  4064  p:=label_head;
  4065  while 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
  4071  to the preceding node that survives, so that we can use the |nearest_dot|
  4072  routine later. (This is a bit of a kludge.)
  4073  
  4074  @<Remove all rectangles from list, except for dots that have labels@>=
  4075  p:=next[0];
  4076  while 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
  4085  way |nearest_dot| works.
  4086  
  4087  @<Typeset an overflow label for |p|@>=
  4088  begin r:=next[dot_for_label[p]]; s:=next[r]; t:=next[p];
  4089  next[p]:=s; prev[s]:=p; next[r]:=p; prev[p]:=r;@/
  4090  q:=nearest_dot(p,0);@/
  4091  next[r]:=s; prev[s]:=r; next[p]:=t; {remove |p| again}
  4092  incr(overflow_line);
  4093  dvi_goto(over_col,overflow_line*thrice_x_height+655360);
  4094  hbox(info[p],label_font,true);
  4095  if 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;
  4104  dvi_out(pop);
  4105  end
  4106  
  4107  @ @<Adjust the maximum page width@>=
  4108  if overflow_line>1 then page_width:=over_col+10000000;
  4109    {overflow labels are estimated to occupy $10^7\,$sp}
  4110  if page_width>max_h then max_h:=page_width
  4111  
  4112  @* Doing the pixels.
  4113  The most interesting part of \.{GFtoDVI} is the way it makes use of a gray
  4114  font to typeset the pixels of a character. In fact, the author must admit having
  4115  great fun devising the algorithms below. Perhaps the reader will also
  4116  enjoy reading them.
  4117  
  4118  The basic idea will be to use an array of 12-bit integers to represent the next
  4119  twelve rows that need to be typeset. The binary expansions of these integers,
  4120  reading from least significant bit to most significant bit, will represent
  4121  pixels 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
  4125  present in a gray font; we shall now use those tables to compute
  4126  an auxiliary array |b[0..4095]|. Given a 12-bit number~$v$, the gray-font
  4127  character appropriate to $v$'s binary pattern will be~|b[v]|. If no
  4128  character should be typeset for this pattern in the current row,
  4129  |b[v]| will be~0.
  4130  
  4131  The array |b| can have many different configurations, depending on how
  4132  many characters are actually present in the gray font. But
  4133  it's not difficult to compute |b| by going through the existing characters
  4134  in increasing order and marking all patterns~$x$ to which they apply.
  4135  
  4136  @<Initialize glob...@>=
  4137  for k:=0 to 4095 do b[k]:=0;
  4138  for 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$
  4147  when |v| is an odd multiple of~$2^j$; we also set $\\{rho}[0]=2^{12}$.
  4148  
  4149  @<Initialize g...@>=
  4150  for 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;
  4155  rho[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
  4162  already contains instructions that have selected the gray font and moved
  4163  to the proper horizontal coordinate for the row that we wish to process next.
  4164  Let's suppose that 12-bit patterns have been set up in array~|a|, and that
  4165  the global variables |starting_col| and |finishing_col| are known such
  4166  that |a[j]| is zero unless |starting_col<=j<=finishing_col|. Here's what
  4167  we can do, assuming that appropriate local variables and labels have
  4168  been declared:
  4169  
  4170  @<Typeset the pixels of the current row@>=
  4171  j:=starting_col;
  4172  loop@+  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;
  4184  done:
  4185  
  4186  @ @<Move to column |j| in the \.{DVI} output@>=
  4187  dvi_out(right4);
  4188  dvi_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|@>=
  4193  reswitch: if k=1 then typeset(v)
  4194  else  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
  4207  array~|a|, and we need to be able to keep it up to date as new rows
  4208  scroll by. A moment's thought about the problem reveals that we will either
  4209  have to read an entire character from the \.{GF} file into memory,
  4210  or we'll need to adopt a coroutine-like approach: A single \\{skip}
  4211  command in the \.{GF} file might need to be processed in pieces, since
  4212  it might generate more rows of zeroes than we are ready to absorb
  4213  all at once into~|a|.
  4214  
  4215  The coroutine method actually turns out to be quite simple, so we shall
  4216  introduce a global variable |blank_rows|, which tells how many rows of
  4217  blanks should be generated before we read the \.{GF} instructions
  4218  for 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,
  4225  if we introduce another variable~|l| that is set initially to~1:
  4226  
  4227  @<Add more rows to |a|, until 12-bit entries are obtained@>=
  4228  repeat @<Put the bits for the next row, times |l|, into |a|@>;
  4229  l:=l+l; decr(y);
  4230  until l=4096;
  4231  
  4232  @ As before, |cur_gf| will contain the first \.{GF} command that has
  4233  not yet been interpreted.
  4234  
  4235  @<Put the bits...@>=
  4236  if blank_rows>0 then decr(blank_rows)
  4237  else 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...@>=
  4252  loop  @+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;
  4271  done1:
  4272  
  4273  @ @<Paint |k| bits and read another command@>=
  4274  if x+k>finishing_col then finishing_col:=x+k;
  4275  if paint_black then for j:=x to x+k-1 do a[j]:=a[j]+l;
  4276  paint_black:=not paint_black;
  4277  x:=x+k;
  4278  cur_gf:=get_byte
  4279  
  4280  @ When the current row has been typeset, all entries of |a| will be even;
  4281  we want to divide them by~2 and incorporate a new row with $l=2^{11}$.
  4282  However, if they are all multiples of~4, we actually want to divide by~4
  4283  and incorporate two new rows, with $l=2^{10}$ and $l=2^{11}$. In general,
  4284  we want to divide by the maximum possible power of~2 and add the corresponding
  4285  number 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@>=
  4289  l:=rho[a[starting_col]];
  4290  for j:=starting_col+1 to finishing_col do if l>rho[a[j]] then l:=rho[a[j]];
  4291  if 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
  4296  else  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;
  4303  it simply remains to glue them all together in the proper framework.
  4304  
  4305  @p procedure do_pixels;
  4306  label done,done1,reswitch,continue,exit;
  4307  var @!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}
  4313  begin select_font(gray_font);
  4314  delta_x:=delta_x+round(unsc_x_ratio*min_x);
  4315  for j:=0 to max_x-min_x do a[j]:=0;
  4316  l:=1; z:=0; starting_col:=0; finishing_col:=0; y:=max_y+12; paint_black:=false;
  4317  blank_rows:=0; cur_gf:=get_byte;
  4318  loop@+  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;
  4322  exit:end;
  4323  
  4324  @* The main program.
  4325  Now we are ready to put it all together. This is where \.{GFtoDVI} starts,
  4326  and where it ends.
  4327  
  4328  @p begin initialize; {get all variables initialized}
  4329  @<Initialize the strings@>;
  4330  start_gf; {open the input and output files}
  4331  @<Process the preamble@>;
  4332  cur_gf:=get_byte; init_str_ptr:=str_ptr;
  4333  loop@+  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;
  4341  final_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'|}$$
  4352  We copy this to the \.{DVI} file, but remove the `\.{METAFONT}' part so that
  4353  it can be replaced by its proper logo.
  4354  
  4355  @<Process the preamble@>=
  4356  if get_byte<>pre then bad_gf('No preamble');
  4357  @.No preamble@>
  4358  if get_byte<>gf_id_byte then bad_gf('Wrong ID');
  4359  @.Wrong ID@>
  4360  k:=get_byte; {|k| is the length of the initial string to be copied}
  4361  for m:=1 to k do append_char(get_byte);
  4362  dvi_out(pre); dvi_out(dvi_id_byte); {output the preamble}
  4363  dvi_four(25400000); dvi_four(473628672); {conversion ratio for sp}
  4364  dvi_four(1000); {magnification factor}
  4365  dvi_out(k); use_logo:=false; s:=str_start[str_ptr];
  4366  for m:=1 to k do dvi_out(str_pool[s+m-1]);
  4367  if 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}}
  4378  time_stamp:=make_string
  4379  
  4380  @* System-dependent changes.
  4381  This section should be replaced, if necessary, by changes to the program
  4382  that are necessary to make \.{GFtoDVI} work at a particular installation.
  4383  It is usually best to design your change file so that all changes to
  4384  previous sections preserve the section numbering; then everybody's version
  4385  will be consistent with the printed program. More extensive changes,
  4386  which introduce new sections, can be inserted here; then only the index
  4387  itself will get a new section number.
  4388  @^system dependencies@>
  4389  
  4390  @* Index.
  4391  Here is a list of the section numbers where each identifier is used.
  4392  Cross references to error messages and a few other tidbits of information
  4393  also appear.