modernc.org/knuth@v0.0.4/web/testdata/ctan.org/tex-archive/systems/knuth/local/mfware-sparc/pktype.web (about)

     1  % PKtype.web
     2  %
     3  %  PKtype verifies the correctness of a PK file.
     4  %
     5  % Preliminary 0.0 version:  May, 1985
     6  % First release, 0.9 version:  8 May 1985
     7  % Updated to reflect new pk format, 2.0 version: 25 July 1985
     8  % Updated again for new pk format, 2.1 version: 15 August 1985
     9  % Docmentation updated, 2.2 version: 17 November 1987
    10  %
    11  % slight editing to correspond with MFware report -- don, 21 Oct 89
    12  % additional editing suggested by P Breitenlohner -- don, 18 Nov 89
    13  %  Corrected two typos -- 21 Dec 96 (don)
    14  
    15  \def\versiondate{18 November 1989}
    16  %
    17  \def\hang{\hangindent 3em\noindent\ignorespaces}
    18  \font\ninerm=cmr9
    19  \font\logo=logo10 % font used for the METAFONT logo
    20  \def\MF{{\logo META}\-{\logo FONT}}
    21  \def\PASCAL{Pascal}
    22  \def\tamu{Texas A\char38 M}
    23  \def\(#1){} % this is used to make section names sort themselves better
    24  \def\9#1{} % this is used for sort keys in the index
    25  \def\title{PKtype}
    26  \def\contentspagenumber{0}
    27  \def\topofcontents{\null
    28    \def\titlepage{F} % include headline on the contents page
    29    \def\rheader{\mainfont\hfil \contentspagenumber}
    30    \vfill
    31    \centerline{\titlefont The {\ttitlefont PKtype} processor}
    32    \vskip 15pt
    33    \centerline{(Version 2.3, \versiondate)}
    34    \vfill}
    35  \def\botofcontents{\vfill
    36    \centerline{\hsize 5in\baselineskip9pt
    37      \vbox{\ninerm\noindent
    38      The preparation of this report
    39      was supported in part by the National Science
    40      Foundation under grants IST-8201926 and MCS-8300984,
    41      and by the System Development Foundation. `\TeX' is a
    42      trademark of the American Mathematical Society.}}}
    43  \pageno=\contentspagenumber \advance\pageno by 1
    44  
    45  @* Introduction.
    46  This program reads a \.{PK} file, verifies that it is in the correct
    47  format, and writes it in textual format.
    48  
    49  @ The |banner| string defined here should be changed whenever \.{PKtype}
    50  gets modified.
    51  
    52  @d banner=='This is PKtype, Version 2.3' {printed when the program starts}
    53  
    54  @ This program is written in standard \PASCAL, except where it is necessary
    55  to use extensions; for example, \.{PKtype} must read files whose names
    56  are dynamically specified, and that would be impossible in pure \PASCAL.
    57  
    58  @d othercases == others: {default for cases not listed explicitly}
    59  @d endcases == @+end {follows the default case in an extended |case| statement}
    60  @f othercases == else
    61  @f endcases == end
    62  
    63  @ Both the input and output come from binary files.  On line interaction
    64  is handled through \PASCAL's standard |input| and |output| files.  Two macros
    65  are used to write to the type file, so this output can easily be redirected.
    66  
    67  @d print_ln(#)==write_ln(output,#)
    68  @d print(#)==write(output,#)
    69  @d t_print_ln(#)==write_ln(typ_file,#)
    70  @d t_print(#)==write(typ_file,#)
    71  
    72  @p program PKtype(@!input,@!output);
    73  label @<Labels in the outer block@>@/
    74  const @<Constants in the outer block@>@/
    75  type @<Types in the outer block@>@/
    76  var @<Globals in the outer block@>@/
    77  procedure initialize; {this procedure gets things started properly}
    78    var i:integer; {loop index for initializations}
    79    begin print_ln(banner);@/
    80    @<Set initial values@>@/
    81    end;
    82  
    83  @ If the program has to stop prematurely, it goes to the
    84  `|final_end|'.
    85  
    86  @d final_end=9999 {label for the end of it all}
    87  
    88  @<Labels...@>=final_end;
    89  
    90  @ These constants determine the maximum length of a file name and the length
    91  of the terminal line, as well as the widest character that can be translated.
    92  @^system dependencies@>
    93  
    94  @<Constants...@>=
    95  @!name_length=80; {maximum length of a file name}
    96  @!terminal_line_length=132; {maximum length of an input line}
    97  
    98  @ Here are some macros for common programming idioms.
    99  
   100  @d incr(#) == #:=#+1 {increase a variable by unity}
   101  @d decr(#) == #:=#-1 {decrease a variable by unity}
   102  @d do_nothing == {empty statement}
   103  
   104  @ It is possible that a malformed packed file (heaven forbid!) or some other
   105  error might be detected by this program.  Such errors might occur in a deeply
   106  nested procedure, so the procedure called |jump_out| has been added to transfer
   107  to the very end of the program with an error message.
   108  
   109  @d abort(#)==begin print_ln(' ',#); t_print_ln(' ',#); jump_out; end
   110  
   111  @p procedure jump_out;
   112  begin goto final_end;
   113  end;
   114  
   115  @* The character set.
   116  Like all programs written with the  \.{WEB} system, \.{PKtype} can be
   117  used with any character set. But it uses ASCII code internally, because
   118  the programming for portable input-output is easier when a fixed internal
   119  code is used.
   120  
   121  The next few sections of \.{PKtype} have therefore been copied from the
   122  analogous ones in the \.{WEB} system routines. They have been considerably
   123  simplified, since \.{PKtype} need not deal with the controversial
   124  ASCII codes less than @'40 or greater than @'176.
   125  
   126  @<Types...@>=
   127  @!ASCII_code=" ".."~"; {a subrange of the integers}
   128  
   129  @ The original \PASCAL\ compiler was designed in the late 60s, when six-bit
   130  character sets were common, so it did not make provision for lower case
   131  letters. Nowadays, of course, we need to deal with both upper and lower case
   132  alphabets in a convenient way, especially in a program like \.{PKtype}.
   133  So we shall assume that the \PASCAL\ system being used for \.{PKtype}
   134  has a character set containing at least the standard visible characters
   135  of ASCII code (|"!"| through |"~"|).
   136  
   137  Some \PASCAL\ compilers use the original name |char| for the data type
   138  associated with the characters in text files, while other \PASCAL s
   139  consider |char| to be a 64-element subrange of a larger data type that has
   140  some other name.  In order to accommodate this difference, we shall use
   141  the name |text_char| to stand for the data type of the characters in the
   142  output file.  We shall also assume that |text_char| consists of
   143  the elements |chr(first_text_char)| through |chr(last_text_char)|,
   144  inclusive. The following definitions should be adjusted if necessary.
   145  @^system dependencies@>
   146  
   147  @d text_char == char {the data type of characters in text files}
   148  @d first_text_char=0 {ordinal number of the smallest element of |text_char|}
   149  @d last_text_char=127 {ordinal number of the largest element of |text_char|}
   150  
   151  @<Types...@>=
   152  @!text_file=packed file of text_char;
   153  
   154  @ The \.{PKtype} processor converts between ASCII code and
   155  the user's external character set by means of arrays |xord| and |xchr|
   156  that are analogous to \PASCAL's |ord| and |chr| functions.
   157  
   158  @<Globals...@>=
   159  @!xord: array [text_char] of ASCII_code;
   160    {specifies conversion of input characters}
   161  @!xchr: array [0..255] of text_char;
   162    {specifies conversion of output characters}
   163  
   164  @ Under our assumption that the visible characters of standard ASCII are
   165  all present, the following assignment statements initialize the
   166  |xchr| array properly, without needing any system-dependent changes.
   167  
   168  @<Set init...@>=
   169  for i:=0 to @'37 do xchr[i]:='?';
   170  xchr[@'40]:=' ';
   171  xchr[@'41]:='!';
   172  xchr[@'42]:='"';
   173  xchr[@'43]:='#';
   174  xchr[@'44]:='$';
   175  xchr[@'45]:='%';
   176  xchr[@'46]:='&';
   177  xchr[@'47]:='''';@/
   178  xchr[@'50]:='(';
   179  xchr[@'51]:=')';
   180  xchr[@'52]:='*';
   181  xchr[@'53]:='+';
   182  xchr[@'54]:=',';
   183  xchr[@'55]:='-';
   184  xchr[@'56]:='.';
   185  xchr[@'57]:='/';@/
   186  xchr[@'60]:='0';
   187  xchr[@'61]:='1';
   188  xchr[@'62]:='2';
   189  xchr[@'63]:='3';
   190  xchr[@'64]:='4';
   191  xchr[@'65]:='5';
   192  xchr[@'66]:='6';
   193  xchr[@'67]:='7';@/
   194  xchr[@'70]:='8';
   195  xchr[@'71]:='9';
   196  xchr[@'72]:=':';
   197  xchr[@'73]:=';';
   198  xchr[@'74]:='<';
   199  xchr[@'75]:='=';
   200  xchr[@'76]:='>';
   201  xchr[@'77]:='?';@/
   202  xchr[@'100]:='@@';
   203  xchr[@'101]:='A';
   204  xchr[@'102]:='B';
   205  xchr[@'103]:='C';
   206  xchr[@'104]:='D';
   207  xchr[@'105]:='E';
   208  xchr[@'106]:='F';
   209  xchr[@'107]:='G';@/
   210  xchr[@'110]:='H';
   211  xchr[@'111]:='I';
   212  xchr[@'112]:='J';
   213  xchr[@'113]:='K';
   214  xchr[@'114]:='L';
   215  xchr[@'115]:='M';
   216  xchr[@'116]:='N';
   217  xchr[@'117]:='O';@/
   218  xchr[@'120]:='P';
   219  xchr[@'121]:='Q';
   220  xchr[@'122]:='R';
   221  xchr[@'123]:='S';
   222  xchr[@'124]:='T';
   223  xchr[@'125]:='U';
   224  xchr[@'126]:='V';
   225  xchr[@'127]:='W';@/
   226  xchr[@'130]:='X';
   227  xchr[@'131]:='Y';
   228  xchr[@'132]:='Z';
   229  xchr[@'133]:='[';
   230  xchr[@'134]:='\';
   231  xchr[@'135]:=']';
   232  xchr[@'136]:='^';
   233  xchr[@'137]:='_';@/
   234  xchr[@'140]:='`';
   235  xchr[@'141]:='a';
   236  xchr[@'142]:='b';
   237  xchr[@'143]:='c';
   238  xchr[@'144]:='d';
   239  xchr[@'145]:='e';
   240  xchr[@'146]:='f';
   241  xchr[@'147]:='g';@/
   242  xchr[@'150]:='h';
   243  xchr[@'151]:='i';
   244  xchr[@'152]:='j';
   245  xchr[@'153]:='k';
   246  xchr[@'154]:='l';
   247  xchr[@'155]:='m';
   248  xchr[@'156]:='n';
   249  xchr[@'157]:='o';@/
   250  xchr[@'160]:='p';
   251  xchr[@'161]:='q';
   252  xchr[@'162]:='r';
   253  xchr[@'163]:='s';
   254  xchr[@'164]:='t';
   255  xchr[@'165]:='u';
   256  xchr[@'166]:='v';
   257  xchr[@'167]:='w';@/
   258  xchr[@'170]:='x';
   259  xchr[@'171]:='y';
   260  xchr[@'172]:='z';
   261  xchr[@'173]:='{';
   262  xchr[@'174]:='|';
   263  xchr[@'175]:='}';
   264  xchr[@'176]:='~';
   265  for i:=@'177 to 255 do xchr[i]:='?';
   266  
   267  @ The following system-independent code makes the |xord| array contain a
   268  suitable inverse to the information in |xchr|.
   269  
   270  @<Set init...@>=
   271  for i:=first_text_char to last_text_char do xord[chr(i)]:=@'40;
   272  for i:=" " to "~" do xord[xchr[i]]:=i;
   273  
   274  @* Packed file format.
   275  The packed file format is a compact representation of the data contained in a
   276  \.{GF} file.  The information content is the same, but packed (\.{PK}) files
   277  are almost always less than half the size of their \.{GF} counterparts.  They
   278  are also easier to convert into a raster representation because they do not
   279  have a profusion of \\{paint}, \\{skip}, and \\{new\_row} commands to be
   280  separately interpreted.  In addition, the \.{PK} format expressly forbids
   281  \&{special} commands within a character.  The minimum bounding box for each
   282  character is explicit in the format, and does not need to be scanned for as in
   283  the \.{GF} format.  Finally, the width and escapement values are combined with
   284  the raster information into character ``packets'', making it simpler in many
   285  cases to process a character.
   286  
   287  A \.{PK} file is organized as a stream of 8-bit bytes.  At times, these bytes
   288  might be split into 4-bit nybbles or single bits, or combined into multiple
   289  byte parameters.  When bytes are split into smaller pieces, the `first' piece
   290  is always the most significant of the byte.  For instance, the first bit of
   291  a byte is the bit with value 128; the first nybble can be found by dividing
   292  a byte by 16.  Similarly, when bytes are combined into multiple byte
   293  parameters, the first byte is the most significant of the parameter.  If the
   294  parameter is signed, it is represented by two's-complement notation.
   295  
   296  The set of possible eight-bit values is separated into two sets, those that
   297  introduce a character definition, and those that do not.  The values that
   298  introduce a character definition range from 0 to 239; byte values
   299  above 239 are interpreted as commands.  Bytes that introduce character
   300  definitions are called flag bytes, and various fields within the byte indicate
   301  various things about how the character definition is encoded.  Command bytes
   302  have zero or more parameters, and can never appear within a character
   303  definition or between parameters of another command, where they would be
   304  interpeted as data.
   305  
   306  A \.{PK} file consists of a preamble, followed by a sequence of one or more
   307  character definitions, followed by a postamble.  The preamble command must
   308  be the first byte in the file, followed immediately by its parameters.
   309  Any number of character definitions may follow, and any command but the
   310  preamble command and the postamble command may occur between character
   311  definitions.  The very last command in the file must be the postamble.
   312  
   313  @ The packed file format is intended to be easy to read and interpret by
   314  device drivers.  The small size of the file reduces the input/output overhead
   315  each time a font is loaded.  For those drivers that load and save each font
   316  file into memory, the small size also helps reduce the memory requirements.
   317  The length of each character packet is specified, allowing the character raster
   318  data to be loaded into memory by simply counting bytes, rather than
   319  interpreting each command; then, each character can be interpreted on a demand
   320  basis.  This also makes it possible for a driver to skip a particular
   321  character quickly if it knows that the character is unused.
   322  
   323  @ First, the command bytes will be presented; then the format of the
   324  character definitions will be defined.  Eight of the possible sixteen
   325  commands (values 240 through 255) are currently defined; the others are
   326  reserved for future extensions.  The commands are listed below.  Each command
   327  is specified by its symbolic name (e.g., \\{pk\_no\_op}), its opcode byte,
   328  and any parameters.  The parameters are followed by a bracketed number
   329  telling how many bytes they occupy, with the number preceded by a plus sign if
   330  it is a signed quantity.  (Four byte quantities are always signed, however.)
   331  
   332  \yskip\hang|pk_xxx1| 240 |k[1]| |x[k]|.  This command is undefined in general;
   333  it functions as a $(k+2)$-byte \\{no\_op} unless special \.{PK}-reading
   334  programs are being used.  \MF\ generates \\{xxx} commands when encountering
   335  a \&{special} string.  It is recommended that |x| be a string having the form
   336  of a keyword followed by possible parameters relevant to that keyword.
   337  
   338  \yskip\hang\\{pk\_xxx2} 241 |k[2]| |x[k]|.  Like |pk_xxx1|, but |0<=k<65536|.
   339  
   340  \yskip\hang\\{pk\_xxx3} 242 |k[3]| |x[k]|.  Like |pk_xxx1|, but
   341  |0<=k<@t$2^{24}$@>|.  \MF\ uses this when sending a \&{special} string whose
   342  length exceeds~255.
   343  
   344  \yskip\hang\\{pk\_xxx4} 243 |k[4]| |x[k]|.  Like |pk_xxx1|, but |k| can be
   345  ridiculously large; |k| musn't be negative.
   346  
   347  \yskip\hang|pk_yyy| 244 |y[4]|.  This command is undefined in general; it
   348  functions as a five-byte \\{no\_op} unless special \.{PK} reading programs
   349  are being used.  \MF\ puts |scaled| numbers into |yyy|'s, as a result of
   350  \&{numspecial} commands; the intent is to provide numeric parameters to
   351  \\{xxx} commands that immediately precede.
   352  
   353  \yskip\hang|pk_post| 245.  Beginning of the postamble.  This command is
   354  followed by enough |pk_no_op| commands to make the file a multiple
   355  of four bytes long.  Zero through three bytes are usual, but any number
   356  is allowed.
   357  This should make the file easy to read on machines that pack four bytes to
   358  a word.
   359  
   360  \yskip\hang|pk_no_op| 246.  No operation, do nothing.  Any number of
   361  |pk_no_op|'s may appear between \.{PK} commands, but a |pk_no_op| cannot be
   362  inserted between a command and its parameters, between two parameters, or
   363  inside a character definition.
   364  
   365  \yskip\hang|pk_pre| 247 |i[1]| |k[1]| |x[k]| |ds[4]| |cs[4]| |hppp[4]|
   366  |vppp[4]|.  Preamble command.  Here, |i| is the identification byte of the
   367  file, currently equal to 89.  The string |x| is merely a comment, usually
   368  indicating the source of the \.{PK} file.  The parameters |ds| and |cs| are
   369  the design size of the file in $1/2^{20}$ points, and the checksum of the
   370  file, respectively.  The checksum should match the \.{TFM} file and the
   371  \.{GF} files for this font.  Parameters |hppp| and |vppp| are the ratios
   372  of pixels per point, horizontally and vertically, multiplied by $2^{16}$; they
   373  can be used to correlate the font with specific device resolutions,
   374  magnifications, and ``at sizes''.  Usually, the name of the \.{PK} file is
   375  formed by concatenating the font name (e.g., cmr10) with the resolution at
   376  which the font is prepared in pixels per inch multiplied by the magnification
   377  factor, and the letters \.{pk}. For instance, cmr10 at 300 dots per inch
   378  should be named \.{cmr10.300pk}; at one thousand dots per inch and magstephalf,
   379  it should be named \.{cmr10.1095pk}.
   380  
   381  @ We put a few of the above opcodes into definitions for symbolic use by
   382  this program.
   383  
   384  @d pk_id = 89 {the version of \.{PK} file described}
   385  @d pk_xxx1 = 240 {\&{special} commands}
   386  @d pk_yyy = 244 {\&{numspecial} commands}
   387  @d pk_post = 245 {postamble}
   388  @d pk_no_op = 246 {no operation}
   389  @d pk_pre = 247 {preamble}
   390  @d pk_undefined == 248, 249, 250, 251, 252, 253, 254, 255
   391  
   392  @ The \.{PK} format has two conflicting goals: to pack character raster and
   393  size information as compactly as possible, while retaining ease of translation
   394  into raster and other forms.  A suitable compromise was found in the use of
   395  run-encoding of the raster information.  Instead of packing the individual
   396  bits of the character, we instead count the number of consecutive `black' or
   397  `white' pixels in a horizontal raster row, and then encode this number.  Run
   398  counts are found for each row from left to right, traversing rows from the
   399  top to bottom. This is essentially the way the \.{GF} format works.
   400  Instead of presenting each row individually, however, we concatenate all
   401  of the horizontal raster rows into one long string of pixels, and encode this
   402  row.  With knowledge of the width of the bit-map, the original character glyph
   403  can easily be reconstructed.  In addition, we do not need special commands to
   404  mark the end of one row and the beginning of the next.
   405  
   406  Next, we place the burden of finding the minimum bounding box on the part
   407  of the font generator, since the characters will usually be used much more
   408  often than they are generated.  The minimum bounding box is the smallest
   409  rectangle that encloses all `black' pixels of a character.  We also
   410  eliminate the need for a special end of character marker, by supplying
   411  exactly as many bits as are required to fill the minimum bounding box, from
   412  which the end of the character is implicit.
   413  
   414  Let us next consider the distribution of the run counts.  Analysis of several
   415  dozen pixel files at 300 dots per inch yields a distribution peaking at four,
   416  falling off slowly until ten, then a bit more steeply until twenty, and then
   417  asymptotically approaching the horizontal.  Thus, the great majority of our
   418  run counts will fit in a four-bit nybble.  The eight-bit byte is attractive for
   419  our run-counts, as it is the standard on many systems; however, the wasted four
   420  bits in the majority of cases seem a high price to pay.  Another possibility
   421  is to use a Huffman-type encoding scheme with a variable number of bits for
   422  each run-count; this was rejected because of the overhead in fetching and
   423  examining individual bits in the file.  Thus, the character raster definitions
   424  in the \.{PK} file format are based on the four-bit nybble.
   425  
   426  @ An analysis of typical pixel files yielded another interesting statistic:
   427  Fully 37\char`\%\
   428  of the raster rows were duplicates of the previous row.  Thus, the \.{PK}
   429  format allows the specification of repeat counts, which indicate how many times
   430  a horizontal raster row is to be repeated.  These repeated rows are taken out
   431  of the character glyph before individual rows are concatenated into the long
   432  string of pixels.
   433  
   434  For elegance, we disallow a run count of zero.  The case of a null raster
   435  description should be gleaned from the character width and height being equal
   436  to zero, and no raster data should be read.  No other zero counts are ever
   437  necessary.  Also, in the absence of repeat counts, the repeat value is set to
   438  be zero (only the original row is sent.)  If a repeat count is seen, it takes
   439  effect on the current row.  The current row is defined as the row on which the
   440  first pixel of the next run count will lie.  The repeat count is set back to
   441  zero when the last pixel in the current row is seen, and the row is sent out.
   442  
   443  This poses a problem for entirely black and entirely white rows, however.  Let
   444  us say that the current row ends with four white pixels, and then we have five
   445  entirely empty rows, followed by a black pixel at the beginning of the next
   446  row, and the character width is ten pixels.  We would like to use a repeat
   447  count, but there is no legal place to put it.  If we put it before the white
   448  run count, it will apply to the current row.  If we put it after, it applies
   449  to the row with the black pixel at the beginning.  Thus, entirely white or
   450  entirely black repeated rows are always packed as large run counts (in this
   451  case, a white run count of 54) rather than repeat counts.
   452  
   453  @ Now we turn our attention to the actual packing of the run counts and
   454  repeat counts into nybbles.  There are only sixteen possible nybble values.
   455  We need to indicate run counts and repeat counts.  Since the run counts are
   456  much more common, we will devote the majority of the nybble values to them.
   457  We therefore indicate a repeat count by a nybble of 14 followed by a packed
   458  number, where a packed number will be explained later.  Since the repeat
   459  count value of one is so common, we indicate a repeat one command by a single
   460  nybble of 15.  A 14 followed by the packed number 1 is still legal for a
   461  repeat one count.  The run counts are coded directly as packed
   462  numbers.
   463  
   464  For packed numbers, therefore, we have the nybble values 0 through 13.  We
   465  need to represent the positive integers up to, say, $2^{31}-1$.  We would
   466  like the more common smaller numbers to take only one or two nybbles, and
   467  the infrequent large numbers to take three or more.  We could therefore
   468  allocate one nybble value to indicate a large run count taking three or more
   469  nybbles.  We do this with the value 0.
   470  
   471  @ We are left with the values 1 through 13.  We can allocate some of these, say
   472  |dyn_f|, to be one-nybble run counts.
   473  These will work for the run counts |1..dyn_f|.  For subsequent run
   474  counts, we will use a nybble greater than |dyn_f|, followed by a second nybble,
   475  whose value can run from 0 through 15.  Thus, the two-nybble values will
   476  run from |dyn_f+1..(13-dyn_f)*16+dyn_f|.  We have our definition of large run
   477  count values now, being all counts greater than |(13-dyn_f)*16+dyn_f|.
   478  
   479  We can analyze our several dozen pixel files and determine an optimal value of
   480  |dyn_f|, and use this value for all of the characters.  Unfortunately, values
   481  of |dyn_f| that pack small characters well tend to pack the large characters
   482  poorly, and values that pack large characters well are not efficient for the
   483  smaller characters.  Thus, we choose the optimal |dyn_f| on a character basis,
   484  picking the value that will pack each individual character in the smallest
   485  number of nybbles.  Legal values of |dyn_f| run from 0 (with no one-nybble run
   486  counts) to 13 (with no two-nybble run counts).
   487  
   488  @ Our only remaining task in the coding of packed numbers is the large run
   489  counts.  We use a scheme suggested by D.~E.~Knuth
   490  @^Knuth, Donald Ervin@>
   491  that simply and elegantly represents arbitrarily large values.  The
   492  general scheme to represent an integer |i| is to write its hexadecimal
   493  representation, with leading zeros removed.  Then we count the number of
   494  digits, and prepend one less than that many zeros before the hexadecimal
   495  representation.  Thus, the values from one to fifteen occupy one nybble;
   496  the values sixteen through 255 occupy three, the values 256 through 4095
   497  require five, etc.
   498  
   499  For our purposes, however, we have already represented the numbers one
   500  through |(13-dyn_f)*16+dyn_f|.  In addition, the one-nybble values have
   501  already been taken by our other commands, which means that only the values
   502  from sixteen up are available to us for long run counts.  Thus, we simply
   503  normalize our long run counts, by subtracting |(13-dyn_f)*16+dyn_f+1| and
   504  adding 16, and then we represent the result according to the scheme above.
   505  
   506  @ The final algorithm for decoding the run counts based on the above scheme
   507  looks like this, assuming that a procedure called \\{get\_nyb} is available
   508  to get the next nybble from the file, and assuming that the global
   509  |repeat_count| indicates whether a row needs to be repeated.  Note that this
   510  routine is recursive, but since a repeat count can never directly follow
   511  another repeat count, it can only be recursive to one level.
   512  
   513  @<Packed number procedure@>=
   514  function pk_packed_num : integer ;
   515  var i, @!j : integer ;
   516  begin
   517     i := get_nyb ;
   518     if i = 0 then begin
   519        repeat j := get_nyb ; incr(i) ; until j <> 0 ;
   520        while i > 0 do begin j := j * 16 + get_nyb ; decr(i) ; end ;
   521        pk_packed_num := j - 15 + (13-dyn_f)*16 + dyn_f ;
   522     end else if i <= dyn_f then
   523        pk_packed_num := i
   524     else if i < 14 then
   525        pk_packed_num := (i-dyn_f-1)*16+get_nyb+dyn_f+1
   526     else begin
   527        if repeat_count <> 0 then abort('Second repeat count for this row!') ;
   528  @.Second repeat count...@>
   529        repeat_count := 1; {prevent recursion more than one level}
   530        if i = 14 then repeat_count := pk_packed_num;
   531        send_out(true, repeat_count) ;
   532        pk_packed_num := pk_packed_num ;
   533     end ;
   534  end ;
   535  
   536  @ For low resolution fonts, or characters with `gray' areas, run encoding can
   537  often make the character many times larger.  Therefore, for those characters
   538  that cannot be encoded efficiently with run counts, the \.{PK} format allows
   539  bit-mapping of the characters.  This is indicated by a |dyn_f| value of
   540  14.  The bits are packed tightly, by concatenating all of the horizontal raster
   541  rows into one long string, and then packing this string eight bits to a byte.
   542  The number of bytes required can be calculated by |(width*height+7) div 8|.
   543  This format should only be used when packing the character by run counts takes
   544  more bytes than this, although, of course, it is legal for any character.
   545  Any extra bits in the last byte should be set to zero.
   546  
   547  @ At this point, we are ready to introduce the format for a character
   548  descriptor.  It consists of three parts: a flag byte, a character preamble,
   549  and the raster data.  The most significant four bits of the flag byte
   550  yield the |dyn_f| value for that character.  (Notice that only values of
   551  0 through 14 are legal for |dyn_f|, with 14 indicating a bit mapped character;
   552  thus, the flag bytes do not conflict with the command bytes, whose upper nybble
   553  is always 15.)  The next bit (with weight 8) indicates whether the first run
   554  count is a black count or a white count, with a one indicating a black count.
   555  For bit-mapped characters, this bit should be set to a zero.  The next bit
   556  (with weight 4) indicates whether certain later parameters (referred to as size
   557  parameters) are given in one-byte or two-byte quantities, with a one indicating
   558  that they are in two-byte quantities.  The last two bits are concatenated on to
   559  the beginning of the packet-length parameter in the character preamble,
   560  which will be explained below.
   561  
   562  However, if the last three bits of the flag byte are all set (normally
   563  indicating that the size parameters are two-byte values and that a 3 should be
   564  prepended to the length parameter), then a long format of the character
   565  preamble should be used instead of one of the short forms.
   566  
   567  Therefore, there are three formats for the character preamble; the one that
   568  is used depends on the least significant three bits of the flag byte.  If the
   569  least significant three bits are in the range zero through three, the short
   570  format is used.  If they are in the range four through six, the extended short
   571  format is used.  Otherwise, if the least significant bits are all set, then
   572  the long form of the character preamble is used.  The preamble formats are
   573  explained below.
   574  
   575  \yskip\hang Short form: |flag[1]| |pl[1]| |cc[1]| |tfm[3]| |dm[1]| |w[1]|
   576  |h[1]| |hoff[+1]| |voff[+1]|.
   577  If this format of the character preamble is used, the above
   578  parameters must all fit in the indicated number of bytes, signed or unsigned
   579  as indicated.  Almost all of the standard \TeX\ font characters fit; the few
   580  exceptions are fonts such as \.{cminch}.
   581  
   582  \yskip\hang Extended short form: |flag[1]| |pl[2]| |cc[1]| |tfm[3]| |dm[2]|
   583  |w[2]| |h[2]| |hoff[+2]| |voff[+2]|.  Larger characters use this extended
   584  format.
   585  
   586  \yskip\hang Long form: |flag[1]| |pl[4]| |cc[4]| |tfm[4]| |dx[4]| |dy[4]|
   587  |w[4]| |h[4]| |hoff[4]| |voff[4]|.  This is the general format that
   588  allows all of the
   589  parameters of the \.{GF} file format, including vertical escapement.
   590  \vskip\baselineskip
   591  The |flag| parameter is the flag byte.  The parameter |pl| (packet length)
   592  contains the offset
   593  of the byte following this character descriptor, with respect to the beginning
   594  of the |tfm| width parameter.  This is given so a \.{PK} reading program can,
   595  once it has read the flag byte, packet length, and character code (|cc|), skip
   596  over the character by simply reading this many more bytes.  For the two short
   597  forms of the character preamble, the last two bits of the flag byte should be
   598  considered the two most-significant bits of the packet length.  For the short
   599  format, the true packet length might be calculated as |(flag mod 4)*256+pl|;
   600  for the short extended format, it might be calculated as
   601  |(flag mod 4)*65536+pl|.
   602  
   603  The |w| parameter is the width and the |h| parameter is the height in pixels
   604  of the minimum bounding box.  The |dx| and |dy| parameters are the horizontal
   605  and vertical escapements, respectively.  In the short formats, |dy| is assumed
   606  to be zero and |dm| is |dx| but in pixels;
   607  in the long format, |dx| and |dy| are both
   608  in pixels multiplied by $2^{16}$.  The |hoff| is the horizontal offset from the
   609  upper left pixel to the reference pixel; the |voff| is the vertical offset.
   610  They are both given in pixels, with right and down being positive.  The
   611  reference pixel is the pixel that occupies the unit square in \MF; the
   612  \MF\ reference point is the lower left hand corner of this pixel.  (See the
   613  example below.)
   614  
   615  @ \TeX\ requires all characters that have the same character codes
   616  modulo 256 to have also the same |tfm| widths and escapement values.  The \.{PK}
   617  format does not itself make this a requirement, but in order for the font to
   618  work correctly with the \TeX\ software, this constraint should be observed.
   619  (The standard version of \TeX\ cannot output character codes greater
   620  than 255, but extended versions do exist.)
   621  
   622  Following the character preamble is the raster information for the
   623  character, packed by run counts or by bits, as indicated by the flag byte.
   624  If the character is packed by run counts and the required number of nybbles
   625  is odd, then the last byte of the raster description should have a zero
   626  for its least significant nybble.
   627  
   628  @ As an illustration of the \.{PK} format, the character \char4\ from the font
   629  amr10 at 300 dots per inch will be encoded.  This character was chosen
   630  because it illustrates some
   631  of the borderline cases.  The raster for the character looks like this (the
   632  row numbers are chosen for convenience, and are not \MF's row numbers.)
   633  
   634  \vskip\baselineskip
   635  {\def\smbox{\vrule height 7pt width 7pt depth 0pt \hskip 3pt}%
   636  \catcode`\*=\active \let*=\smbox
   637  \centerline{\vbox{\baselineskip=10pt
   638  \halign{\hfil#\quad&&\hfil#\hfil\cr
   639  0& & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\cr
   640  1& & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\cr
   641  2& & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\cr
   642  3& & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\cr
   643  4& & &*&*& & & & & & & & & & & & & & & & &*&*\cr
   644  5& & &*&*& & & & & & & & & & & & & & & & &*&*\cr
   645  6& & &*&*& & & & & & & & & & & & & & & & &*&*\cr
   646  7\cr
   647  8\cr
   648  9& & & & &*&*& & & & & & & & & & & & &*&*& & \cr
   649  10& & & & &*&*& & & & & & & & & & & & &*&*& & \cr
   650  11& & & & &*&*& & & & & & & & & & & & &*&*& & \cr
   651  12& & & & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*& & \cr
   652  13& & & & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*& & \cr
   653  14& & & & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*& & \cr
   654  15& & & & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*& & \cr
   655  16& & & & &*&*& & & & & & & & & & & & &*&*& & \cr
   656  17& & & & &*&*& & & & & & & & & & & & &*&*& & \cr
   657  18& & & & &*&*& & & & & & & & & & & & &*&*& & \cr
   658  19\cr
   659  20\cr
   660  21\cr
   661  22& & &*&*& & & & & & & & & & & & & & & & &*&*\cr
   662  23& & &*&*& & & & & & & & & & & & & & & & &*&*\cr
   663  24& & &*&*& & & & & & & & & & & & & & & & &*&*\cr
   664  25& & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\cr
   665  26& & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\cr
   666  27& & &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\cr
   667  28&+& &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\cr
   668  &\hphantom{*}&\hphantom{*}\cr
   669  }}}}
   670  The width of the minimum bounding box for this character is 20; its height
   671  is 29.  The `+' represents the reference pixel; notice how it lies outside the
   672  minimum bounding box.  The |hoff| value is $-2$, and the |voff| is~28.
   673  
   674  The first task is to calculate the run counts and repeat counts.  The repeat
   675  counts are placed at the first transition (black to white or white to black)
   676  in a row, and are enclosed in brackets.  White counts are enclosed in
   677  parentheses.  It is relatively easy to generate the counts list:
   678  \vskip\baselineskip
   679  \centerline{82 [2] (16) 2 (42) [2] 2 (12) 2 (4) [3]}
   680  \centerline{16 (4) [2] 2 (12) 2 (62) [2] 2 (16) 82}
   681  \vskip\baselineskip
   682  Note that any duplicated rows that are not all white or all black are removed
   683  before the run counts are calculated.  The rows thus removed are rows 5, 6,
   684  10, 11, 13, 14, 15, 17, 18, 23, and 24.
   685  
   686  @ The next step in the encoding of this character is to calculate the optimal
   687  value of |dyn_f|.  The details of how this calculation is done are not
   688  important here; suffice it to say that there is a simple algorithm that can
   689  determine the best value of |dyn_f| in one pass over the count list.  For this
   690  character, the optimal value turns out to be 8 (atypically low).  Thus, all
   691  count values less than or equal to 8 are packed in one nybble; those from
   692  nine to $(13-8)*16+8$ or 88 are packed in two nybbles.  The run encoded values
   693  now become (in hex, separated according to the above list):
   694  \vskip\baselineskip
   695  \centerline{\tt D9 E2 97 2 B1 E2 2 93 2 4 E3}
   696  \centerline{\tt 97 4 E2 2 93 2 C5 E2 2 97 D9}
   697  \vskip\baselineskip\noindent
   698  which comes to 36 nybbles, or 18 bytes.  This is shorter than the 73 bytes
   699  required for the bit map, so we use the run count packing.
   700  
   701  @ The short form of the character preamble is used because all of the
   702  parameters fit in their respective lengths.  The packet length is therefore
   703  18 bytes for the raster, plus
   704  eight bytes for the character preamble parameters following the character
   705  code, or 26.  The |tfm| width for this character is 640796, or {\tt 9C71C} in
   706  hexadecimal.  The horizontal escapement is 25 pixels.  The flag byte is
   707  88 hex, indicating the short preamble, the black first count, and the
   708  |dyn_f| value of 8.  The final total character packet, in hexadecimal, is:
   709  \vskip\baselineskip
   710  $$\vbox{\halign{\hfil #\quad&&{\tt #\ }\cr
   711  Flag byte&88\cr
   712  Packet length&1A\cr
   713  Character code&04\cr
   714  |tfm| width&09&C7&1C\cr
   715  Horizontal escapement (pixels)&19\cr
   716  Width of bit map&14\cr
   717  Height of bit map&1D\cr
   718  Horizontal offset (signed)&FE\cr
   719  Vertical offset&1C\cr
   720  Raster data&D9&E2&97\cr
   721  &2B&1E&22\cr
   722  &93&24&E3\cr
   723  &97&4E&22\cr
   724  &93&2C&5E\cr
   725  &22&97&D9\cr}}$$
   726  
   727  @* Input and output.
   728  There are two types of files that this program must deal with---standard
   729  text files and files of bytes (packed files.)
   730  For our purposes, we shall consider an eight-bit byte to consist of the
   731  values |0..255|.  If your system does not pack these values to a byte, it is
   732  no major difficulty; you must only insure that the input function
   733  |pk_byte| can read packed bytes.
   734  
   735  @<Types...@>=
   736  @!eight_bits=0..255; {packed file byte}
   737  @!byte_file=packed file of eight_bits ; {for packed file words}
   738  @^system dependencies@>
   739  
   740  @ @<Glob...@>=
   741  @!pk_file:byte_file;  {where the input comes from}
   742  @!typ_file:text_file; {where the final output goes}
   743  @^system dependencies@>
   744  
   745  @ To prepare these files for input and output, we |reset| and |rewrite| them.
   746  An extension of \PASCAL\ is needed, since we want to associate files
   747  with external names that are specified dynamically (i.e., not
   748  known at compile time). The following code assumes that `|reset(f,s)|'
   749  does this, when |f| is a file variable and |s| is a string variable that
   750  specifies the file name. If |eof(f)| is true immediately after
   751  |reset(f,s)| has acted, we assume that no file named |s| is accessible.
   752  @^system dependencies@>
   753  
   754  @p procedure open_pk_file; {prepares the input for reading}
   755  begin reset(pk_file,pk_name);
   756  pk_loc := 0 ;
   757  end;
   758  @#
   759  procedure open_typ_file; {prepares to write text data to the |typ_file|}
   760  begin rewrite(typ_file,typ_name);
   761  end;
   762  
   763  @ We need a place to store the names of the input and output file, as well
   764  as a byte counter for the output file.
   765  
   766  @<Glob...@>=
   767  @!pk_name,@!typ_name:packed array[1..name_length] of char; {name of input
   768      and output files}
   769  @!pk_loc:integer; {how many bytes have we read?}
   770  
   771  @ We also need a function that will get a single byte from the \.{pk} file.
   772  
   773  @p function pk_byte : eight_bits ;
   774  var temp : eight_bits ;
   775  begin
   776     temp := pk_file^ ;
   777     get(pk_file) ;
   778     incr(pk_loc) ;
   779     pk_byte := temp ;
   780  end ;
   781  
   782  @ Now we are ready to open the files.
   783  
   784  @<Open files@>=
   785  open_pk_file ;
   786  open_typ_file ;
   787  t_print_ln(banner) ;
   788  t_print('Input file: ') ;
   789  i := 1 ;
   790  while pk_name[i] <> ' ' do begin
   791     t_print(pk_name[i]) ; incr(i) ;
   792  end ;
   793  t_print_ln(' ')
   794  
   795  @ As we are reading the packed file, we often need to fetch 16 and 32 bit
   796  quantities.  Here we have two procedures to do this.
   797  
   798  @p function get_16 : integer ;
   799  var a : integer ;
   800  begin a := pk_byte ; get_16 := a * 256 + pk_byte ; end ;
   801  @#
   802  function get_32 : integer ;
   803  var a : integer ;
   804  begin a := get_16 ; if a > 32767 then a := a - 65536 ;
   805  get_32 := a * 65536 + get_16 ; end ;
   806  
   807  @ We still need the |term_pos| variable.
   808  
   809  @<Glob...@>=
   810  @!term_pos : integer ; {current terminal position}
   811  
   812  @ Now we read and check the preamble of the \.{PK} file.  In the preamble, we
   813  find the |hppp|, |design_size|, |checksum|.
   814  
   815  @<Read preamble@>=
   816  if pk_byte <> pk_pre then abort('Bad PK file:  pre command missing!') ;
   817  @.pre command missing@>
   818  if pk_byte <> pk_id then abort('Wrong version of PK file!') ;
   819  @.Wrong version of PK file@>
   820  j := pk_byte ;
   821  t_print('''') ;
   822  for i := 1 to j do t_print(xchr[pk_byte]) ;
   823  t_print_ln('''') ;
   824  design_size := get_32 ;
   825  t_print_ln('Design size = ',design_size:1) ;
   826  checksum := get_32 ;
   827  t_print_ln('Checksum = ',checksum:1) ;
   828  hppp := get_32 ; vppp := get_32 ;
   829  t_print('Resolution: horizontal = ',hppp:1,'  vertical = ',vppp:1) ;
   830  magnification := round(hppp * 72.27 / 65536) ;
   831  t_print_ln('  (',magnification:1,' dpi)') ;
   832  if hppp <> vppp then print_ln('Warning:  aspect ratio not 1:1!')
   833  
   834  @ Of course, we need to define the above variables.
   835  
   836  @<Glob...@>=
   837  @!magnification : integer ; {resolution at which pixel file is prepared}
   838  @!design_size : integer ; {design size in FIXes}
   839  @!checksum : integer ; {checksum of pixel file}
   840  @!hppp, @!vppp : integer ; {horizontal and vertical points per inch}
   841  
   842  @* Character unpacking.
   843  Here we simply unpack the character, writing the information we glean to the
   844  |typ_file|.
   845  
   846  @<Unpack and write character@>=
   847  t_print((pk_loc-1):1,':  Flag byte = ',flag_byte:1) ;
   848  dyn_f := flag_byte div 16 ;
   849  flag_byte := flag_byte mod 16 ;
   850  turn_on := flag_byte >= 8 ;
   851  if turn_on then flag_byte := flag_byte - 8 ;
   852  if flag_byte = 7 then
   853     @<Read long character preamble@>
   854  else if flag_byte > 3 then
   855     @<Read extended short character preamble@>
   856  else
   857     @<Read short character preamble@> ;
   858  t_print_ln('  Character = ',car:1,'  Packet length = ',
   859     packet_length:1) ;
   860  t_print_ln('  Dynamic packing variable = ',dyn_f:1) ;
   861  t_print('  TFM width = ',tfm_width:1,'  dx = ',dx:1) ;
   862  if dy <> 0 then t_print_ln('  dy = ',dy:1) else t_print_ln(' ') ;
   863  t_print_ln('  Height = ',height:1,'  Width = ',width:1,'  X-offset = ',
   864     x_off:1, '  Y-offset = ',y_off:1) ;
   865  @<Read and translate raster description@> ;
   866  if end_of_packet <> pk_loc then abort('Bad PK file: Bad packet length!')
   867  @.Bad packet length@>
   868  
   869  @ We need a whole lot of globals used but not defined up there.
   870  
   871  @<Glob...@>=
   872  @!i, @!j : integer ; {index pointers}
   873  @!flag_byte : integer ; {the byte that introduces the character definition}
   874  @!end_of_packet : integer ; {where we expect the end of the packet to be}
   875  @!width, @!height : integer ; {width and height of character}
   876  @!x_off, @!y_off : integer ; {x and y offsets of character}
   877  @!tfm_width : integer ; {character tfm width}
   878  @!tfms : array [0..255] of integer ; {character tfm widths}
   879  @!dx, @!dy : integer ; {escapement values}
   880  @!dxs, @!dys : array [0..255] of integer ; {escapement values}
   881  @!status : array[0..255] of boolean ; {has the character been seen?}
   882  @!dyn_f : integer ; {dynamic packing variable}
   883  @!car : integer ; {the character we are reading}
   884  @!packet_length : integer ; {the length of the character packet}
   885  
   886  @ Now, the preamble reading modules.  First, we have the general case: the
   887  long character preamble format.
   888  
   889  @<Read long character preamble@>=
   890  begin
   891     packet_length := get_32 ; car := get_32 ;
   892     end_of_packet := packet_length + pk_loc ;
   893     packet_length := packet_length + 9 ;
   894     tfm_width := get_32 ;
   895     dx := get_32 ; dy := get_32 ;
   896     width := get_32 ;
   897     height := get_32 ;
   898     x_off := get_32 ; y_off := get_32 ;
   899  end
   900  
   901  @ This module reads the character preamble with double byte parameters.
   902  
   903  @<Read extended short character preamble@>=
   904  begin
   905     packet_length := (flag_byte - 4) * 65536 + get_16 ;
   906     car := pk_byte ;
   907     end_of_packet := packet_length + pk_loc ;
   908     packet_length := packet_length + 4 ;
   909     i := pk_byte ;
   910     tfm_width := i * 65536 + get_16 ;
   911     dx := get_16 * 65536 ;
   912     dy := 0 ;
   913     width := get_16 ;
   914     height := get_16 ;
   915     x_off := get_16 ; y_off := get_16 ;
   916     if x_off > 32767 then x_off := x_off - 65536 ;
   917     if y_off > 32767 then y_off := y_off - 65536 ;
   918  end
   919  
   920  @ Here we read the most common character preamble, that with single byte
   921  parameters.
   922  
   923  @<Read short character preamble@>=
   924  begin
   925     packet_length := flag_byte * 256 + pk_byte ;
   926     car := pk_byte ;
   927     end_of_packet := packet_length + pk_loc ;
   928     packet_length := packet_length + 3 ;
   929     i := pk_byte ;
   930     tfm_width := i * 65536 + get_16 ;
   931     dx := pk_byte * 65536 ;
   932     dy := 0 ;
   933     width := pk_byte ;
   934     height := pk_byte ;
   935     x_off := pk_byte ; y_off := pk_byte ;
   936     if x_off > 127 then x_off := x_off - 256 ;
   937     if y_off > 127 then y_off := y_off - 256 ;
   938  end
   939  
   940  @ Now we have the most important part of the program, where we actually
   941  interpret the commands in the raster description.  First of all, we need
   942  a procedure to get a single nybble from the file, as well as one to get
   943  a single bit.
   944  
   945  @p function get_nyb : integer ;
   946  var temp : eight_bits ;
   947  begin
   948     if bit_weight = 0 then begin
   949        input_byte := pk_byte ;
   950        bit_weight := 16 ;
   951     end ;
   952     temp := input_byte div bit_weight ;
   953     input_byte := input_byte - temp * bit_weight ;
   954     bit_weight := bit_weight div 16 ;
   955     get_nyb := temp ;
   956  end ;
   957  @#
   958  function get_bit : boolean ;
   959  var temp : boolean ;
   960  begin
   961     bit_weight := bit_weight div 2 ;
   962     if bit_weight = 0 then begin
   963        input_byte := pk_byte ;
   964        bit_weight := 128 ;
   965     end ;
   966     temp := input_byte >= bit_weight ;
   967     if temp then
   968        input_byte := input_byte - bit_weight ;
   969     get_bit := temp ;
   970  end ;
   971  
   972  @ We also need a function to write output to the screen.  We put as many
   973  counts on a line as possible, to reduce the volume of output.  Each count
   974  will appear as a number, with white counts enclosed by parentheses and repeat
   975  counts by brackets.
   976  
   977  @p procedure send_out(@!repeat_count: boolean ; @!value : integer ) ;
   978  var i, len : integer ;
   979  begin
   980     i := 10 ; len := 1 ;
   981     while value >= i do begin incr(len) ; i := i * 10 ; end ;
   982     if repeat_count or not turn_on then len := len + 2 ;
   983     if term_pos + len > 78 then begin
   984        term_pos := len + 2 ; t_print_ln(' ') ; t_print('  ') ;
   985     end else term_pos := term_pos + len ;
   986     if repeat_count then t_print('[', value:1, ']')
   987     else if turn_on then t_print(value:1)
   988     else t_print('(', value:1, ')') ;
   989  end ;
   990  @<Packed number procedure@>
   991  
   992  @ Now, the globals to help communication between these procedures.
   993  
   994  @<Glob...@>=
   995  @!input_byte : eight_bits ; {the byte we are currently decimating}
   996  @!bit_weight : eight_bits ; {weight of the current bit}
   997  @!nybble : eight_bits ; {the current nybble}
   998  
   999  @ And the main procedure.
  1000  
  1001  @<Read and translate raster description@>=
  1002  bit_weight := 0 ;
  1003  if dyn_f = 14 then
  1004     @<Get raster by bits@>
  1005  else @<Create normally packed raster@>
  1006  
  1007  @ If |dyn_f=14|, then we need to get the raster representation
  1008  one bit at a time.
  1009  
  1010  @<Get raster by bits@>=
  1011  begin
  1012  for i := 1 to height do begin
  1013     t_print('  ') ;
  1014     for j := 1 to width do
  1015        if get_bit then t_print('*')
  1016        else t_print('.') ;
  1017     t_print_ln(' ') ;
  1018  end;
  1019  end
  1020  
  1021  @ Otherwise, we translate the bit counts into the raster rows.  |count|
  1022  contains the number of bits of the current color, and |turn_on| indicates
  1023  whether or not they should be black.  |rows_left| contains the number of
  1024  rows to be sent.
  1025  
  1026  @<Create normally packed raster@>=
  1027  begin
  1028  term_pos := 2 ;
  1029  t_print('  ') ;
  1030  rows_left := height ;
  1031  h_bit := width ;
  1032  repeat_count := 0 ;
  1033  while rows_left > 0 do begin
  1034     count := pk_packed_num ;
  1035     send_out(false, count) ;
  1036     if count >= h_bit then begin
  1037        rows_left := rows_left - repeat_count - 1 ;
  1038        repeat_count := 0 ;
  1039        count := count - h_bit ;
  1040        h_bit := width ;
  1041        rows_left := rows_left - count div width ;
  1042        count := count mod width ;
  1043     end ;
  1044     h_bit := h_bit - count ;
  1045     turn_on := not turn_on ;
  1046  end ;
  1047  t_print_ln(' ') ;
  1048  if (rows_left <> 0) or (h_bit <> width) then
  1049     abort('Bad PK file: More bits than required!');
  1050  @.More bits than required@>
  1051  end
  1052  
  1053  @ We need to declare the repeat flag, bit counter, and color flag here.
  1054  
  1055  @<Glob...@>=
  1056  @!repeat_count : integer ; {how many times to repeat the next row?}
  1057  @!rows_left : integer ; {how many rows left?}
  1058  @!turn_on : boolean ; {are we black here?}
  1059  @!h_bit : integer ; {what is our horizontal position?}
  1060  @!count : integer ; {how many bits of current color left?}
  1061  
  1062  @ If any specials are found, we write them out here.
  1063  
  1064  @d four_cases(#)==#,#+1,#+2,#+3
  1065  
  1066  @p procedure skip_specials ;
  1067  var @!i, @!j: integer ;
  1068  begin
  1069     repeat
  1070        flag_byte := pk_byte ;
  1071        if flag_byte >= 240 then
  1072           case flag_byte of
  1073              four_cases(pk_xxx1):
  1074  begin
  1075     t_print((pk_loc-1):1,':  Special: ''') ;
  1076     i := 0 ;
  1077     for j := pk_xxx1 to flag_byte do i := 256 * i + pk_byte ;
  1078     for j := 1 to i do t_print(xchr[pk_byte]) ;
  1079     t_print_ln('''') ;
  1080  end ;
  1081            pk_yyy : t_print_ln((pk_loc-1):1,':  Num special: ',get_32:1) ;
  1082           pk_post : t_print_ln((pk_loc-1):1,':  Postamble') ;
  1083          pk_no_op : t_print_ln((pk_loc-1):1,':  No op') ;
  1084      pk_pre, pk_undefined : abort('Unexpected ', flag_byte:1,'!') ;
  1085  @.Unexpected bbb@>
  1086           endcases ;
  1087     until (flag_byte < 240) or (flag_byte = pk_post) ;
  1088  end ;
  1089  
  1090  @* Terminal communication.
  1091  We must get the file names and determine whether input is to be in
  1092  hexadecimal or binary.  To do this, we use the standard input path
  1093  name.  We need a procedure to flush the input buffer.  For most systems,
  1094  this will be an empty statement.  For other systems, a |print_ln| will
  1095  provide a quick fix.  We also need a routine to get a line of input from
  1096  the terminal.  On some systems, a simple |read_ln| will do.  Finally,
  1097  a macro to print a string to the first blank is required.
  1098  
  1099  @d flush_buffer == begin end
  1100  @d get_line(#) == if eoln(input) then read_ln(input) ;
  1101     i := 1 ;
  1102     while not (eoln(input) or eof(input)) do begin
  1103        #[i] := input^ ;
  1104        incr(i) ;
  1105        get(input) ;
  1106     end ;
  1107     #[i] := ' '
  1108  
  1109  @ @p procedure dialog ;
  1110  var i : integer ; {index variable}
  1111  buffer : packed array [1..name_length] of char; {input buffer}
  1112  begin
  1113     for i := 1 to name_length do begin
  1114        typ_name[i] := ' ' ;
  1115        pk_name[i] := ' ' ;
  1116     end;
  1117     print('Input file name:  ') ;
  1118     flush_buffer ;
  1119     get_line(pk_name) ;
  1120     print('Output file name:  ') ;
  1121     flush_buffer ;
  1122     get_line(typ_name) ;
  1123  end ;
  1124  
  1125  @* The main program.
  1126  Now that we have all the pieces written, let us put them together.
  1127  
  1128  @p begin
  1129  initialize ;
  1130  dialog ;
  1131  @<Open files@> ;
  1132  @<Read preamble@> ;
  1133  skip_specials ;
  1134  while flag_byte <> pk_post do begin
  1135     @<Unpack and write character@> ;
  1136     skip_specials ;
  1137  end ;
  1138  j := 0 ;
  1139  while not eof(pk_file) do begin
  1140     i := pk_byte ;
  1141     if i <> pk_no_op then abort('Bad byte at end of file: ',i:1) ;
  1142  @.Bad byte at end of file@>
  1143     t_print_ln((pk_loc-1):1,':  No op') ;
  1144     incr(j) ;
  1145  end ;
  1146  t_print_ln(pk_loc:1,' bytes read from packed file.');
  1147  final_end :
  1148  end .
  1149  
  1150  @* System-dependent changes.
  1151  This section should be replaced, if necessary, by changes to the program
  1152  that are necessary to make \.{PKtype} work at a particular installation.
  1153  Any additional routines should be inserted here.
  1154  @^system dependencies@>
  1155  
  1156  @* Index.
  1157  Pointers to error messages appear here together with the section numbers
  1158  where each ident\-i\-fier is used.