summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/gftype.web
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/texk/web2c/gftype.web
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/gftype.web')
-rw-r--r--Build/source/texk/web2c/gftype.web1394
1 files changed, 0 insertions, 1394 deletions
diff --git a/Build/source/texk/web2c/gftype.web b/Build/source/texk/web2c/gftype.web
deleted file mode 100644
index df530672b0d..00000000000
--- a/Build/source/texk/web2c/gftype.web
+++ /dev/null
@@ -1,1394 +0,0 @@
-% This program by D. R. Fuchs is not copyrighted and can be used freely.
-% Version 0 was implemented in March 1984, before METAFONT itself was complete.
-% Version 1.0 incorporated refinements for the TRAP test (August 1984).
-% Version 1.1 fixed a trivial bug in the stated initial y value (August 1984).
-% Version 1.2 clarified the pixel coordinates (September 1984).
-% Version 2.0 changed over to new GF format (December 1984).
-% Version 2.1 changed over to newer GF format (February 1985).
-% Version 2.2 changed `family' to `extension' (October 1985).
-% Version 3.0 changed the default prompts (April 1989).
-% Version 3.1 checked character locators (Breitenlohner, March 1991).
-
-% Here is TeX material that gets inserted after \input webmac
-\def\hang{\hangindent 3em\noindent\ignorespaces}
-\def\textindent#1{\hangindent2.5em\noindent\hbox to2.5em{\hss#1 }\ignorespaces}
-\font\ninerm=cmr9
-\let\mc=\ninerm % medium caps for names like SAIL
-\font\tenss=cmss10 % for `The METAFONTbook'
-\def\PASCAL{Pascal}
-\def\ph{\hbox{Pascal-H}}
-\font\logo=manfnt % font used for the METAFONT logo
-\def\MF{{\logo META}\-{\logo FONT}}
-\def\<#1>{$\langle#1\rangle$}
-\def\section{\mathhexbox278}
-\let\swap=\leftrightarrow
-\def\round{\mathop{\rm round}\nolimits}
-
-\def\(#1){} % this is used to make section names sort themselves better
-\def\9#1{} % this is used for sort keys in the index via @@:sort key}{entry@@>
-
-\def\title{GFtype}
-\def\contentspagenumber{101}
-\def\topofcontents{\null
- \titlefalse % include headline on the contents page
- \def\rheader{\mainfont\hfil \contentspagenumber}
- \vfill
- \centerline{\titlefont The {\ttitlefont GFtype} processor}
- \vskip 15pt
- \centerline{(Version 3.1, March 1991)}
- \vfill}
-\def\botofcontents{\vfill
- \centerline{\hsize 5in\baselineskip9pt
- \vbox{\ninerm\noindent
- The preparation of this report
- was supported in part by the National Science
- Foundation under grants IST-8201926, MCS-8300984, and
- CCR-8610181,
- and by the System Development Foundation. `\TeX' is a
- trademark of the American Mathematical Society.
- `{\logo hijklmnj}\kern1pt' is a trademark of Addison-Wesley
- Publishing Company.}}}
-\pageno=\contentspagenumber \advance\pageno by 1
-
-@* Introduction.
-The \.{GFtype} utility program reads binary generic-font (``\.{GF}'')
-files that are produced by font compilers such as \MF, and converts them
-into symbolic form. This program has three chief purposes:
-(1)~It can be used to look at the pixels of a font, with one pixel per
-character in a text file; (2)~it can be used to
-determine whether a \.{GF} file is valid or invalid, when diagnosing
-compiler errors; and (3)~it serves as an example of a program that reads
-\.{GF} files correctly, for system programmers who are developing
-\.{GF}-related software.
-
-The original version of this program was written by David R. Fuchs in
-March, 1984. Donald E. Knuth made a few modifications later that year as
-\MF\ was taking shape.
-@^Fuchs, David Raymond@>
-@^Knuth, Donald Ervin@>
-
-The |banner| string defined here should be changed whenever \.{GFtype}
-gets modified.
-
-@d banner=='This is GFtype, Version 3.1' {printed when the program starts}
-
-@ This program is written in standard \PASCAL, except where it is
-necessary to use extensions; for example, one extension is to use a
-default |case| as in \.{TANGLE}, \.{WEAVE}, etc. All places where
-nonstandard constructions are used have been listed in the index under
-``system dependencies.''
-@!@^system dependencies@>
-
-@d othercases == others: {default for cases not listed explicitly}
-@d endcases == @+end {follows the default case in an extended |case| statement}
-@f othercases == else
-@f endcases == end
-
-@ The binary input comes from |gf_file|, and the symbolic output is written
-on \PASCAL's standard |output| file. The term |print| is used instead of
-|write| when this program writes on |output|, so that all such output
-could easily be redirected if desired.
-
-@d print(#)==write(#)
-@d print_ln(#)==write_ln(#)
-@d print_nl==write_ln
-
-@p program GF_type(@!gf_file,@!output);
-label @<Labels in the outer block@>@/
-const @<Constants in the outer block@>@/
-type @<Types in the outer block@>@/
-var @<Globals in the outer block@>@/
-procedure initialize; {this procedure gets things started properly}
- var i:integer; {loop index for initializations}
- begin print_ln(banner);@/
- @<Set initial values@>@/
- end;
-
-@ If the program has to stop prematurely, it goes to the
-`|final_end|'.
-
-@d final_end=9999 {label for the end of it all}
-
-@<Labels...@>=final_end;
-
-@ Four parameters can be changed at compile time to extend or
-reduce \.{GFtype}'s capacity.
-Note that the total number of bits in the main |image_array| will be
-$$\hbox{$(|max_row|+1)\;\times\;(|max_col|+1)$}.$$
-(\MF's full pixel range is rarely implemented, because it would require
-8~megabytes of memory.)
-
-@<Constants...@>=
-@!terminal_line_length=150; {maximum number of characters input in a single
- line of input from the terminal}
-@!line_length=79; {\\{xxx} strings will not produce lines longer than this}
-@!max_row=79; {vertical extent of pixel image array}
-@!max_col=79; {horizontal extent of pixel image array}
-
-@ Here are some macros for common programming idioms.
-
-@d incr(#) == #:=#+1 {increase a variable by unity}
-@d decr(#) == #:=#-1 {decrease a variable by unity}
-@d negate(#) == #:=-# {change the sign of a variable}
-
-@ If the \.{GF} file is badly malformed, the whole process must be aborted;
-\.{GFtype} will give up, after issuing an error message about the symptoms
-that were noticed.
-
-Such errors might be discovered inside of subroutines inside of subroutines,
-so a procedure called |jump_out| has been introduced. This procedure, which
-simply transfers control to the label |final_end| at the end of the program,
-contains the only non-local |goto| statement in \.{GFtype}.
-@^system dependencies@>
-
-@d abort(#)==begin print(' ',#); jump_out;
- end
-@d bad_gf(#)==abort('Bad GF file: ',#,'!')
-@.Bad GF file@>
-
-@p procedure jump_out;
-begin goto final_end;
-end;
-
-@* The character set.
-Like all programs written with the \.{WEB} system, \.{GFtype} can be
-used with any character set. But it uses ASCII code internally, because
-the programming for portable input-output is easier when a fixed internal
-code is used.
-
-The next few sections of \.{GFtype} have therefore been copied from the
-analogous ones in the \.{WEB} system routines. They have been considerably
-simplified, since \.{GFtype} need not deal with the controversial
-ASCII codes less than @'40 or greater than @'176.
-If such codes appear in the \.{GF} file,
-they will be printed as question marks.
-
-@<Types...@>=
-@!ASCII_code=" ".."~"; {a subrange of the integers}
-
-@ The original \PASCAL\ compiler was designed in the late 60s, when six-bit
-character sets were common, so it did not make provision for lower case
-letters. Nowadays, of course, we need to deal with both upper and lower case
-alphabets in a convenient way, especially in a program like \.{GFtype}.
-So we shall assume that the \PASCAL\ system being used for \.{GFtype}
-has a character set containing at least the standard visible characters
-of ASCII code (|"!"| through |"~"|).
-
-Some \PASCAL\ compilers use the original name |char| for the data type
-associated with the characters in text files, while other \PASCAL s
-consider |char| to be a 64-element subrange of a larger data type that has
-some other name. In order to accommodate this difference, we shall use
-the name |text_char| to stand for the data type of the characters in the
-output file. We shall also assume that |text_char| consists of
-the elements |chr(first_text_char)| through |chr(last_text_char)|,
-inclusive. The following definitions should be adjusted if necessary.
-@^system dependencies@>
-
-@d text_char == char {the data type of characters in text files}
-@d first_text_char=0 {ordinal number of the smallest element of |text_char|}
-@d last_text_char=127 {ordinal number of the largest element of |text_char|}
-
-@<Types...@>=
-@!text_file=packed file of text_char;
-
-@ The \.{GFtype} processor converts between ASCII code and
-the user's external character set by means of arrays |xord| and |xchr|
-that are analogous to \PASCAL's |ord| and |chr| functions.
-
-@<Globals...@>=
-@!xord: array [text_char] of ASCII_code;
- {specifies conversion of input characters}
-@!xchr: array [0..255] of text_char;
- {specifies conversion of output characters}
-
-@ Under our assumption that the visible characters of standard ASCII are
-all present, the following assignment statements initialize the
-|xchr| array properly, without needing any system-dependent changes.
-
-@<Set init...@>=
-for i:=0 to @'37 do xchr[i]:='?';
-xchr[@'40]:=' ';
-xchr[@'41]:='!';
-xchr[@'42]:='"';
-xchr[@'43]:='#';
-xchr[@'44]:='$';
-xchr[@'45]:='%';
-xchr[@'46]:='&';
-xchr[@'47]:='''';@/
-xchr[@'50]:='(';
-xchr[@'51]:=')';
-xchr[@'52]:='*';
-xchr[@'53]:='+';
-xchr[@'54]:=',';
-xchr[@'55]:='-';
-xchr[@'56]:='.';
-xchr[@'57]:='/';@/
-xchr[@'60]:='0';
-xchr[@'61]:='1';
-xchr[@'62]:='2';
-xchr[@'63]:='3';
-xchr[@'64]:='4';
-xchr[@'65]:='5';
-xchr[@'66]:='6';
-xchr[@'67]:='7';@/
-xchr[@'70]:='8';
-xchr[@'71]:='9';
-xchr[@'72]:=':';
-xchr[@'73]:=';';
-xchr[@'74]:='<';
-xchr[@'75]:='=';
-xchr[@'76]:='>';
-xchr[@'77]:='?';@/
-xchr[@'100]:='@@';
-xchr[@'101]:='A';
-xchr[@'102]:='B';
-xchr[@'103]:='C';
-xchr[@'104]:='D';
-xchr[@'105]:='E';
-xchr[@'106]:='F';
-xchr[@'107]:='G';@/
-xchr[@'110]:='H';
-xchr[@'111]:='I';
-xchr[@'112]:='J';
-xchr[@'113]:='K';
-xchr[@'114]:='L';
-xchr[@'115]:='M';
-xchr[@'116]:='N';
-xchr[@'117]:='O';@/
-xchr[@'120]:='P';
-xchr[@'121]:='Q';
-xchr[@'122]:='R';
-xchr[@'123]:='S';
-xchr[@'124]:='T';
-xchr[@'125]:='U';
-xchr[@'126]:='V';
-xchr[@'127]:='W';@/
-xchr[@'130]:='X';
-xchr[@'131]:='Y';
-xchr[@'132]:='Z';
-xchr[@'133]:='[';
-xchr[@'134]:='\';
-xchr[@'135]:=']';
-xchr[@'136]:='^';
-xchr[@'137]:='_';@/
-xchr[@'140]:='`';
-xchr[@'141]:='a';
-xchr[@'142]:='b';
-xchr[@'143]:='c';
-xchr[@'144]:='d';
-xchr[@'145]:='e';
-xchr[@'146]:='f';
-xchr[@'147]:='g';@/
-xchr[@'150]:='h';
-xchr[@'151]:='i';
-xchr[@'152]:='j';
-xchr[@'153]:='k';
-xchr[@'154]:='l';
-xchr[@'155]:='m';
-xchr[@'156]:='n';
-xchr[@'157]:='o';@/
-xchr[@'160]:='p';
-xchr[@'161]:='q';
-xchr[@'162]:='r';
-xchr[@'163]:='s';
-xchr[@'164]:='t';
-xchr[@'165]:='u';
-xchr[@'166]:='v';
-xchr[@'167]:='w';@/
-xchr[@'170]:='x';
-xchr[@'171]:='y';
-xchr[@'172]:='z';
-xchr[@'173]:='{';
-xchr[@'174]:='|';
-xchr[@'175]:='}';
-xchr[@'176]:='~';
-for i:=@'177 to 255 do xchr[i]:='?';
-
-@ The following system-independent code makes the |xord| array contain a
-suitable inverse to the information in |xchr|.
-
-@<Set init...@>=
-for i:=first_text_char to last_text_char do xord[chr(i)]:=@'40;
-for i:=" " to "~" do xord[xchr[i]]:=i;
-
-@* Generic font file format.
-The most important output produced by a typical run of \MF\ is the
-``generic font'' (\.{GF}) file that specifies the bit patterns of the
-characters that have been drawn. The term {\sl generic\/} indicates that
-this file format doesn't match the conventions of any name-brand manufacturer;
-but it is easy to convert \.{GF} files to the special format required by
-almost all digital phototypesetting equipment. There's a strong analogy
-between the \.{DVI} files written by \TeX\ and the \.{GF} files written
-by \MF; and, in fact, the file formats have a lot in common.
-It is therefore not surprising that \.{GFtype} is identical in many
-respects to the \.{DVItype} program.
-
-A \.{GF} file is a stream of 8-bit bytes that may be
-regarded as a series of commands in a machine-like language. The first
-byte of each command is the operation code, and this code is followed by
-zero or more bytes that provide parameters to the command. The parameters
-themselves may consist of several consecutive bytes; for example, the
-`|boc|' (beginning of character) command has six parameters, each of
-which is four bytes long. Parameters are usually regarded as nonnegative
-integers; but four-byte-long parameters can be either positive or
-negative, hence they range in value from $-2^{31}$ to $2^{31}-1$.
-As in \.{TFM} files, numbers that occupy
-more than one byte position appear in BigEndian order,
-and negative numbers appear in two's complement notation.
-
-A \.{GF} file consists of a ``preamble,'' followed by a sequence of one or
-more ``characters,'' followed by a ``postamble.'' The preamble is simply a
-|pre| command, with its parameters that introduce the file; this must come
-first. Each ``character'' consists of a |boc| command, followed by any
-number of other commands that specify ``black'' pixels,
-followed by an |eoc| command. The characters appear in the order that \MF\
-generated them. If we ignore no-op commands (which are allowed between any
-two commands in the file), each |eoc| command is immediately followed by a
-|boc| command, or by a |post| command; in the latter case, there are no
-more characters in the file, and the remaining bytes form the postamble.
-Further details about the postamble will be explained later.
-
-Some parameters in \.{GF} commands are ``pointers.'' These are four-byte
-quantities that give the location number of some other byte in the file;
-the first file byte is number~0, then comes number~1, and so on.
-
-@ The \.{GF} format is intended to be both compact and easily interpreted
-by a machine. Compactness is achieved by making most of the information
-relative instead of absolute. When a \.{GF}-reading program reads the
-commands for a character, it keeps track of two quantities: (a)~the current
-column number,~|m|; and (b)~the current row number,~|n|. These are 32-bit
-signed integers, although most actual font formats produced from \.{GF}
-files will need to curtail this vast range because of practical
-limitations. (\MF\ output will never allow $\vert m\vert$ or $\vert
-n\vert$ to get extremely large, but the \.{GF} format tries to be more general.)
-
-How do \.{GF}'s row and column numbers correspond to the conventions
-of \TeX\ and \MF? Well, the ``reference point'' of a character, in \TeX's
-view, is considered to be at the lower left corner of the pixel in row~0
-and column~0. This point is the intersection of the baseline with the left
-edge of the type; it corresponds to location $(0,0)$ in \MF\ programs.
-Thus the pixel in \.{GF} row~0 and column~0 is \MF's unit square, comprising the
-region of the plane whose coordinates both lie between 0 and~1. The
-pixel in \.{GF} row~|n| and column~|m| consists of the points whose \MF\
-coordinates |(x,y)| satisfy |m<=x<=m+1| and |n<=y<=n+1|. Negative values of
-|m| and~|x| correspond to columns of pixels {\sl left\/} of the reference
-point; negative values of |n| and~|y| correspond to rows of pixels {\sl
-below\/} the baseline.
-
-Besides |m| and |n|, there's also a third aspect of the current
-state, namely the @!|paint_switch|, which is always either \\{black} or
-\\{white}. Each \\{paint} command advances |m| by a specified amount~|d|,
-and blackens the intervening pixels if |paint_switch=black|; then
-the |paint_switch| changes to the opposite state. \.{GF}'s commands are
-designed so that |m| will never decrease within a row, and |n| will never
-increase within a character; hence there is no way to whiten a pixel that
-has been blackened.
-
-@ Here is a list of all the commands that may appear in a \.{GF} file. Each
-command is specified by its symbolic name (e.g., |boc|), its opcode byte
-(e.g., 67), and its parameters (if any). The parameters are followed
-by a bracketed number telling how many bytes they occupy; for example,
-`|d[2]|' means that parameter |d| is two bytes long.
-
-\yskip\hang|paint_0| 0. This is a \\{paint} command with |d=0|; it does
-nothing but change the |paint_switch| from \\{black} to \\{white} or vice~versa.
-
-\yskip\hang\\{paint\_1} through \\{paint\_63} (opcodes 1 to 63).
-These are \\{paint} commands with |d=1| to~63, defined as follows: If
-|paint_switch=black|, blacken |d|~pixels of the current row~|n|,
-in columns |m| through |m+d-1| inclusive. Then, in any case,
-complement the |paint_switch| and advance |m| by~|d|.
-
-\yskip\hang|paint1| 64 |d[1]|. This is a \\{paint} command with a specified
-value of~|d|; \MF\ uses it to paint when |64<=d<256|.
-
-\yskip\hang|@!paint2| 65 |d[2]|. Same as |paint1|, but |d|~can be as high
-as~65535.
-
-\yskip\hang|@!paint3| 66 |d[3]|. Same as |paint1|, but |d|~can be as high
-as $2^{24}-1$. \MF\ never needs this command, and it is hard to imagine
-anybody making practical use of it; surely a more compact encoding will be
-desirable when characters can be this large. But the command is there,
-anyway, just in case.
-
-\yskip\hang|boc| 67 |c[4]| |p[4]| |min_m[4]| |max_m[4]| |min_n[4]|
-|max_n[4]|. Beginning of a character: Here |c| is the character code, and
-|p| points to the previous character beginning (if any) for characters having
-this code number modulo 256. (The pointer |p| is |-1| if there was no
-prior character with an equivalent code.) The values of registers |m| and |n|
-defined by the instructions that follow for this character must
-satisfy |min_m<=m<=max_m| and |min_n<=n<=max_n|. (The values of |max_m| and
-|min_n| need not be the tightest bounds possible.) When a \.{GF}-reading
-program sees a |boc|, it can use |min_m|, |max_m|, |min_n|, and |max_n| to
-initialize the bounds of an array. Then it sets |m:=min_m|, |n:=max_n|, and
-|paint_switch:=white|.
-
-\yskip\hang|boc1| 68 |c[1]| |@!del_m[1]| |max_m[1]| |@!del_n[1]| |max_n[1]|.
-Same as |boc|, but |p| is assumed to be~$-1$; also |del_m=max_m-min_m|
-and |del_n=max_n-min_n| are given instead of |min_m| and |min_n|.
-The one-byte parameters must be between 0 and 255, inclusive.
-\ (This abbreviated |boc| saves 19~bytes per character, in common cases.)
-
-\yskip\hang|eoc| 69. End of character: All pixels blackened so far
-constitute the pattern for this character. In particular, a completely
-blank character might have |eoc| immediately following |boc|.
-
-\yskip\hang|skip0| 70. Decrease |n| by 1 and set |m:=min_m|,
-|paint_switch:=white|. \ (This finishes one row and begins another,
-ready to whiten the leftmost pixel in the new row.)
-
-\yskip\hang|skip1| 71 |d[1]|. Decrease |n| by |d+1|, set |m:=min_m|, and set
-|paint_switch:=white|. This is a way to produce |d| all-white rows.
-
-\yskip\hang|@!skip2| 72 |d[2]|. Same as |skip1|, but |d| can be as large
-as 65535.
-
-\yskip\hang|@!skip3| 73 |d[3]|. Same as |skip1|, but |d| can be as large
-as $2^{24}-1$. \MF\ obviously never needs this command.
-
-\yskip\hang|new_row_0| 74. Decrease |n| by 1 and set |m:=min_m|,
-|paint_switch:=black|. \ (This finishes one row and begins another,
-ready to {\sl blacken\/} the leftmost pixel in the new row.)
-
-\yskip\hang|@!new_row_1| through |@!new_row_164| (opcodes 75 to 238). Same as
-|new_row_0|, but with |m:=min_m+1| through |min_m+164|, respectively.
-
-\yskip\hang|xxx1| 239 |k[1]| |x[k]|. This command is undefined in
-general; it functions as a $(k+2)$-byte |no_op| unless special \.{GF}-reading
-programs are being used. \MF\ generates \\{xxx} commands when encountering
-a \&{special} string; this occurs in the \.{GF} file only between
-characters, after the preamble, and before the postamble. However,
-\\{xxx} commands might appear within characters,
-in \.{GF} files generated by other
-processors. It is recommended that |x| be a string having the form of a
-keyword followed by possible parameters relevant to that keyword.
-
-\yskip\hang|@!xxx2| 240 |k[2]| |x[k]|. Like |xxx1|, but |0<=k<65536|.
-
-\yskip\hang|xxx3| 241 |k[3]| |x[k]|. Like |xxx1|, but |0<=k<@t$2^{24}$@>|.
-\MF\ uses this when sending a \&{special} string whose length exceeds~255.
-
-\yskip\hang|@!xxx4| 242 |k[4]| |x[k]|. Like |xxx1|, but |k| can be
-ridiculously large; |k| mustn't be negative.
-
-\yskip\hang|yyy| 243 |y[4]|. This command is undefined in general;
-it functions as a 5-byte |no_op| unless special \.{GF}-reading programs
-are being used. \MF\ puts |scaled| numbers into |yyy|'s, as a
-result of \&{numspecial} commands; the intent is to provide numeric
-parameters to \\{xxx} commands that immediately precede.
-
-\yskip\hang|no_op| 244. No operation, do nothing. Any number of |no_op|'s
-may occur between \.{GF} commands, but a |no_op| cannot be inserted between
-a command and its parameters or between two parameters.
-
-\yskip\hang|char_loc| 245 |c[1]| |dx[4]| |dy[4]| |w[4]| |p[4]|.
-This command will appear only in the postamble, which will be explained shortly.
-
-\yskip\hang|@!char_loc0| 246 |c[1]| |@!dm[1]| |w[4]| |p[4]|.
-Same as |char_loc|, except that |dy| is assumed to be zero, and the value
-of~|dx| is taken to be |65536*dm|, where |0<=dm<256|.
-
-\yskip\hang|pre| 247 |i[1]| |k[1]| |x[k]|.
-Beginning of the preamble; this must come at the very beginning of the
-file. Parameter |i| is an identifying number for \.{GF} format, currently
-131. The other information is merely commentary; it is not given
-special interpretation like \\{xxx} commands are. (Note that \\{xxx}
-commands may immediately follow the preamble, before the first |boc|.)
-
-\yskip\hang|post| 248. Beginning of the postamble, see below.
-
-\yskip\hang|post_post| 249. Ending of the postamble, see below.
-
-\yskip\noindent Commands 250--255 are undefined at the present time.
-
-@d gf_id_byte=131 {identifies the kind of \.{GF} files described here}
-
-@ Here are the opcodes that \.{GFtype} actually refers to.
-
-@d paint_0=0 {beginning of the \\{paint} commands}
-@d paint1=64 {move right a given number of columns, then
- black${}\swap{}$white}
-@d boc=67 {beginning of a character}
-@d boc1=68 {abbreviated |boc|}
-@d eoc=69 {end of a character}
-@d skip0=70 {skip no blank rows}
-@d skip1=71 {skip over blank rows}
-@d new_row_0=74 {move down one row and then right}
-@d xxx1=239 {for \&{special} strings}
-@d yyy=243 {for \&{numspecial} numbers}
-@d no_op=244 {no operation}
-@d char_loc=245 {character locators in the postamble}
-@d pre=247 {preamble}
-@d post=248 {postamble beginning}
-@d post_post=249 {postamble ending}
-@d undefined_commands==250,251,252,253,254,255
-
-@ The last character in a \.{GF} file is followed by `|post|'; this command
-introduces the postamble, which summarizes important facts that \MF\ has
-accumulated. The postamble has the form
-$$\vbox{\halign{\hbox{#\hfil}\cr
- |post| |p[4]| |@!ds[4]| |@!cs[4]| |@!hppp[4]| |@!vppp[4]|
- |min_m[4]| |max_m[4]| |min_n[4]| |max_n[4]|\cr
- $\langle\,$character locators$\,\rangle$\cr
- |post_post| |q[4]| |i[1]| 223's$[{\G}4]$\cr}}$$
-Here |p| is a pointer to the byte following the final |eoc| in the file
-(or to the byte following the preamble, if there are no characters);
-it can be used to locate the beginning of \\{xxx} commands
-that might have preceded the postamble. The |ds| and |cs| parameters
-@^design size@> @^check sum@>
-give the design size and check sum, respectively, which are exactly the
-values put into the header of any \.{TFM} file that shares information with this
-\.{GF} file. Parameters |hppp| and |vppp| are the ratios of
-pixels per point, horizontally and vertically, expressed as |scaled| integers
-(i.e., multiplied by $2^{16}$); they can be used to correlate the font
-with specific device resolutions, magnifications, and ``at sizes.'' Then
-come |min_m|, |max_m|, |min_n|, and |max_n|, which bound the values that
-registers |m| and~|n| assume in all characters in this \.{GF} file.
-(These bounds need not be the best possible; |max_m| and |min_n| may, on the
-other hand, be tighter than the similar bounds in |boc| commands. For
-example, some character may have |min_n=-100| in its |boc|, but it might
-turn out that |n| never gets lower than |-50| in any character; then
-|min_n| can have any value |<=-50|. If there are no characters in the file,
-it's possible to have |min_m>max_m| and/or |min_n>max_n|.)
-
-@ Character locators are introduced by |char_loc| commands,
-which specify a character residue~|c|, character escapements (|dx,dy|),
-a character width~|w|, and a pointer~|p|
-to the beginning of that character. (If two or more characters have the
-same code~|c| modulo 256, only the last will be indicated; the others can be
-located by following backpointers. Characters whose codes differ by a
-multiple of 256 are assumed to share the same font metric information,
-hence the \.{TFM} file contains only residues of character codes modulo~256.
-This convention is intended for oriental languages, when there are many
-character shapes but few distinct widths.)
-@^oriental characters@>@^Chinese characters@>@^Japanese characters@>
-
-The character escapements (|dx,dy|) are the values of \MF's \&{chardx}
-and \&{chardy} parameters; they are in units of |scaled| pixels;
-i.e., |dx| is in horizontal pixel units times $2^{16}$, and |dy| is in
-vertical pixel units times $2^{16}$. This is the intended amount of
-displacement after typesetting the character; for \.{DVI} files, |dy|
-should be zero, but other document file formats allow nonzero vertical
-escapement.
-
-The character width~|w| duplicates the information in the \.{TFM} file; it
-is $2^{20}$ times the ratio of the true width to the font's design size.
-
-The backpointer |p| points to the character's |boc|, or to the first of
-a sequence of consecutive \\{xxx} or |yyy| or |no_op| commands that
-immediately precede the |boc|, if such commands exist; such ``special''
-commands essentially belong to the characters, while the special commands
-after the final character belong to the postamble (i.e., to the font
-as a whole). This convention about |p| applies also to the backpointers
-in |boc| commands, even though it wasn't explained in the description
-of~|boc|. @^backpointers@>
-
-Pointer |p| might be |-1| if the character exists in the \.{TFM} file
-but not in the \.{GF} file. This unusual situation can arise in \MF\ output
-if the user had |proofing<0| when the character was being shipped out,
-but then made |proofing>=0| in order to get a \.{GF} file.
-
-@ The last part of the postamble, following the |post_post| byte that
-signifies the end of the character locators, contains |q|, a pointer to the
-|post| command that started the postamble. An identification byte, |i|,
-comes next; this currently equals~131, as in the preamble.
-
-The |i| byte is followed by four or more bytes that are all equal to
-the decimal number 223 (i.e., @"DF in hexadecimal).
-@^Fuchs, David Raymond@>
-\MF\ puts out four to seven of
-these trailing bytes, until the total length of the file is a multiple of
-four bytes, since this works out best on machines that pack four bytes per
-word; but any number of 223's is allowed, as long as there are at least four
-of them. In effect, 223 is a sort of signature that is added at the very end.
-
-This curious way to finish off a \.{GF} file makes it feasible for
-\.{GF}-reading programs to find the postamble first, on most computers,
-even though \MF\ wants to write the postamble last. Most operating
-systems permit random access to individual words or bytes of a file, so
-the \.{GF} reader can start at the end and skip backwards over the 223's
-until finding the identification byte. Then it can back up four bytes, read
-|q|, and move to byte |q| of the file. This byte should, of course,
-contain the value 248 (|post|); now the postamble can be read, so the
-\.{GF} reader can discover all the information needed for individual characters.
-
-Unfortunately, however, standard \PASCAL\ does not include the ability to
-@^system dependencies@>
-access a random position in a file, or even to determine the length of a file.
-Almost all systems nowadays provide the necessary capabilities, so \.{GF}
-format has been designed to work most efficiently with modern operating systems.
-But if \.{GF} files have to be processed under the restrictions of standard
-\PASCAL, one can simply read them from front to back. This will
-be adequate for most applications. However, the postamble-first approach
-would facilitate a program that merges two \.{GF} files, replacing data
-from one that is overridden by corresponding data in the other.
-
-@* Input from binary files.
-We have seen that a \.{GF} file is a sequence of 8-bit bytes. The bytes
-appear physically in what is called a `|packed file of 0..255|'
-in \PASCAL\ lingo.
-
-Packing is system dependent, and many \PASCAL\ systems fail to implement
-such files in a sensible way (at least, from the viewpoint of producing
-good production software). For example, some systems treat all
-byte-oriented files as text, looking for end-of-line marks and such
-things. Therefore some system-dependent code is often needed to deal with
-binary files, even though most of the program in this section of
-\.{GFtype} is written in standard \PASCAL.
-@^system dependencies@>
-
-We shall stick to simple \PASCAL\ in this program, for reasons of clarity,
-even if such simplicity is sometimes unrealistic.
-
-@<Types...@>=
-@!eight_bits=0..255; {unsigned one-byte quantity}
-@!byte_file=packed file of eight_bits; {files that contain binary data}
-
-@ The program deals with one binary file variable: |gf_file| is the main
-input file that we are translating into symbolic form.
-
-@<Glob...@>=
-@!gf_file:byte_file; {the stuff we are \.{GF}typing}
-
-@ To prepare this file for input, we |reset| it.
-
-@p procedure open_gf_file; {prepares to read packed bytes in |gf_file|}
-begin reset(gf_file);
-cur_loc:=0;
-end;
-
-@ If you looked carefully at the preceding code, you probably asked,
-``What is |cur_loc|?'' Good question. It's a global variable that holds
-the number of the byte about to be read next from |gf_file|.
-
-@<Glob...@>=
-@!cur_loc:integer; {where we are about to look, in |gf_file|}
-
-@ We shall use a set of simple functions to read the next byte or
-bytes from |gf_file|. There are four possibilities, each of which is
-treated as a separate function in order to minimize the overhead for
-subroutine calls.
-@^system dependencies@>
-
-@p function get_byte:integer; {returns the next byte, unsigned}
-var b:eight_bits;
-begin if eof(gf_file) then get_byte:=0
-else begin read(gf_file,b); incr(cur_loc); get_byte:=b;
- end;
-end;
-@#
-function get_two_bytes:integer; {returns the next two bytes, unsigned}
-var a,@!b:eight_bits;
-begin read(gf_file,a); read(gf_file,b);
-cur_loc:=cur_loc+2;
-get_two_bytes:=a*256+b;
-end;
-@#
-function get_three_bytes:integer; {returns the next three bytes, unsigned}
-var a,@!b,@!c:eight_bits;
-begin read(gf_file,a); read(gf_file,b); read(gf_file,c);
-cur_loc:=cur_loc+3;
-get_three_bytes:=(a*256+b)*256+c;
-end;
-@#
-function signed_quad:integer; {returns the next four bytes, signed}
-var a,@!b,@!c,@!d:eight_bits;
-begin read(gf_file,a); read(gf_file,b); read(gf_file,c); read(gf_file,d);
-cur_loc:=cur_loc+4;
-if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
-else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
-end;
-
-@* Optional modes of output.
-\.{GFtype} will print different quantities of information based on some
-options that the user must specify: We set |wants_mnemonics| if the
-user wants to see a mnemonic dump of the \.{GF} file; and we set
-|wants_pixels| if the user wants to see a pixel image of each
-character.
-
-When \.{GFtype} begins, it engages the user in a brief dialog so that the
-options will be specified. This part of \.{GFtype} requires nonstandard
-\PASCAL\ constructions to handle the online interaction; so it may be
-preferable in some cases to omit the dialog and simply to produce the maximum
-possible output (|wants_mnemonics=wants_pixels=true|). On other hand, the
-necessary system-dependent routines are not complicated, so they can be
-introduced without terrible trauma.
-@^system dependencies@>
-
-@<Glob...@>=
-@!wants_mnemonics: boolean; {controls mnemonic output}
-@!wants_pixels: boolean; {controls pixel output}
-
-@ @<Set init...@>=
-wants_mnemonics:=true; wants_pixels:=true;
-
-@ The |input_ln| routine waits for the user to type a line at his or her
-terminal; then it puts ASCII-code equivalents for the characters on that line
-into the |buffer| array. The |term_in| file is used for terminal input,
-and |term_out| for terminal output.
-@^system dependencies@>
-
-@<Glob...@>=
-@!buffer:array[0..terminal_line_length] of ASCII_code;
-@!term_in:text_file; {the terminal, considered as an input file}
-@!term_out:text_file; {the terminal, considered as an output file}
-
-@ Since the terminal is being used for both input and output, some systems
-need a special routine to make sure that the user can see a prompt message
-before waiting for input based on that message. (Otherwise the message
-may just be sitting in a hidden buffer somewhere, and the user will have
-no idea what the program is waiting for.) We shall invoke a system-dependent
-subroutine |update_terminal| in order to avoid this problem.
-@^system dependencies@>
-
-@d update_terminal == break(term_out) {empty the terminal output buffer}
-
-@ During the dialog, extensions of \.{GFtype} might treat the first blank
-space in a line as the end of that line. Therefore |input_ln| makes sure
-that there is always at least one blank space in |buffer|.
-
-(This routine is more complex than the present implementation needs, but
-it has been copied from \.{DVItype} so that system-dependent changes that
-worked before will work again.)
-@^system dependencies@>
-
-@p procedure input_ln; {inputs a line from the terminal}
-var k:0..terminal_line_length;
-begin update_terminal; reset(term_in);
-if eoln(term_in) then read_ln(term_in);
-k:=0;
-while (k<terminal_line_length)and not eoln(term_in) do
- begin buffer[k]:=xord[term_in^]; incr(k); get(term_in);
- end;
-buffer[k]:=" ";
-end;
-
-@ This is humdrum.
-
-@p function lower_casify(@!c:ASCII_code):ASCII_code;
-begin
-if (c>="A") and (c<="Z") then lower_casify:=c+"a"-"A"
-else lower_casify:=c;
-end;
-
-@ The selected options are put into global variables by the |dialog|
-procedure, which is called just as \.{GFtype} begins.
-@^system dependencies@>
-
-@p procedure dialog;
-label 1,2;
-begin rewrite(term_out); {prepare the terminal for output}
-write_ln(term_out,banner);@/
-@<Determine whether the user |wants_mnemonics|@>;
-@<Determine whether the user |wants_pixels|@>;
-@<Print all the selected options@>;
-end;
-
-@ @<Determine whether the user |wants_mnemonics|@>=
-1: write(term_out,'Mnemonic output? (default=no, ? for help): ');
-@.Mnemonic output?@>
-input_ln;
-buffer[0]:=lower_casify(buffer[0]);
-if buffer[0]<>"?" then
- wants_mnemonics:=(buffer[0]="y")or(buffer[0]="1")or(buffer[0]="t")
-else begin write(term_out,'Type Y for complete listing,');
- write_ln(term_out,' N for errors/images only.');
- goto 1;
- end
-
-@ @<Determine whether the user |wants_pixels|@>=
-2: write(term_out,'Pixel output? (default=yes, ? for help): ');
-@.Pixel output?@>
-input_ln;
-buffer[0]:=lower_casify(buffer[0]);
-if buffer[0]<>"?" then
- wants_pixels:=(buffer[0]="y")or(buffer[0]="1")or(buffer[0]="t")
- or(buffer[0]=" ")
-else begin write(term_out,'Type Y to list characters pictorially');
- write_ln(term_out,' with *''s, N to omit this option.');
- goto 2;
- end
-
-@ After the dialog is over, we print the options so that the user
-can see what \.{GFtype} thought was specified.
-
-@<Print all the selected options@>=
-print('Options selected: Mnemonic output = ');
-@.Options selected@>
-if wants_mnemonics then print('true')@+else print('false');
-print('; pixel output = ');
-if wants_pixels then print('true')@+else print('false');
-print_ln('.')
-
-@* The image array.
-The definition of \.{GF} files refers to two registers,
-|m| and~|n|, which hold integer column and row numbers. We actually
-keep the values $m'=m-|min_m|$ and $n'=|max_n|-n$ instead, so that
-our internal image array always has |m,n>=0|. We also
-need to remember |paint_switch|, whose value is either |black|
-or |white|.
-
-@<Glob...@>=
-@!m,@!n:integer; {current state values, modified by |min_m| and |max_n|}
-@!paint_switch: pixel;
-
-@ We'll need a big array of pixels to hold the character image. Each
-pixel should be represented as a single bit in order to save space.
-Some systems may prefer the following definitions, while others
-may do better using the |boolean| type and boolean constants.
-@^system dependencies@>
-
-@d white=0 {could also be |false|}
-@d black=1 {could also be |true|}
-
-@<Types...@>=
-@!pixel=white..black; {could also be |boolean|}
-
-@ In order to allow different systems to change the |image| array easily from
-row-major order to column-major order (or vice versa), or to transpose it top
-and bottom or left and right, we declare and access it as follows.
-@^system dependencies@>
-
-@d image==image_array[m,n]
-
-@<Glob...@>=
-@!image_array: packed array [0..max_col,0..max_row] of pixel;
-
-@ A |boc| command has parameters |min_m|, |max_m|, |min_n|, and |max_n|
-that define a rectangular subarray in which the pixels of the current
-character must lie. The program here computes limits on \.{GFtype}'s
-modified |m| and |n| variables, and clears the resulting subarray
-to all |white|.
-
-(There may be a faster way to clear a subarray on particular systems,
-using nonstandard extensions of \PASCAL.)
-@^system dependencies@>
-
-@<Clear the image@>=
-begin max_subcol:=max_m_stated-min_m_stated-1;
-if max_subcol>max_col then max_subcol:=max_col;
-max_subrow:=max_n_stated-min_n_stated;
-if max_subrow>max_row then max_subrow:=max_row;
-n:=0;
-while n<=max_subrow do
- begin m:=0;
- while m<=max_subcol do
- begin image:=white; incr(m);
- end;
- incr(n);
- end;
-end
-
-@ @<Glob...@>=
-@!max_subrow,@!max_subcol:integer; {size of current subarray of interest}
-
-@ As we paint the pixels of a character, we will record its actual
-boundaries in variables |max_m_observed| and |max_n_observed|.
-Then the following routine will be called on to output the image,
-using blanks for |white| and asterisks for |black|. Blanks are
-emitted only when they are followed by nonblanks, in order to conserve
-space in the output. Further compaction could be achieved on many
-systems by using tab marks.
-@^system dependencies@>
-
-An integer variable |b| will be declared for use in counting blanks.
-
-@<Print the image@>=
-begin @<Compare the subarray boundaries with the observed boundaries@>;
-if max_subcol>=0 then {there was at least one \\{paint} command}
- @<Print asterisk patterns for rows 0 to |max_subrow|@>
-else print_ln('(The character is entirely blank.)');
-end
-
-@ @<Glob...@>=
-@!min_m_stated, @!max_m_stated, @!min_n_stated, @!max_n_stated: integer;
- {bounds stated in the \.{GF} file}
-@!max_m_observed,@!max_n_observed: integer;
- {bounds on $(m',n')$ actually observed when painting}
-@!min_m_overall, @!max_m_overall, @!min_n_overall, @!max_n_overall: integer;
- {bounds observed in the entire file so far}
-
-@ If the given character is substantially smaller than the |boc|
-command predicted, we don't want to bother to output rows and columns
-that are all blank.
-
-@<Compare the subarray boundaries with the observed boundaries@>=
-if (max_m_observed>max_col)or(max_n_observed>max_row) then
- print_ln('(The character is too large to be displayed in full.)');
-@.The character is too large...@>
-if max_subcol>max_m_observed then max_subcol:=max_m_observed;
-if max_subrow>max_n_observed then max_subrow:=max_n_observed;
-
-@ @<Print asterisk patterns...@>=
-begin print_ln('.<--This pixel''s lower left corner is at (',
- min_m_stated:1,',',max_n_stated+1:1,') in METAFONT coordinates');
-@.This pixel's lower...@>
-n:=0;
-while n<=max_subrow do
- begin m:=0; b:=0;
- while m<=max_subcol do
- begin if image=white then incr(b)
- else begin while b>0 do
- begin print(' '); decr(b);
- end;
- print('*');
- end;
- incr(m);
- end;
- print_nl; incr(n);
- end;
-print_ln('.<--This pixel''s upper left corner is at (',
- min_m_stated:1,',',max_n_stated-max_subrow:1,
- ') in METAFONT coordinates');
-@.This pixel's upper@>
-end
-
-@* Translation to symbolic form.
-The main work of \.{GFtype} is accomplished by the |do_char| procedure,
-which produces the output for an entire character, assuming that the |boc|
-command for that character has already been processed. This procedure is
-essentially an interpretive routine that reads and acts on the \.{GF}
-commands.
-
-@ We steal the following routine from \MF.
-
-@d unity == @'200000 {$2^{16}$, represents 1.00000}
-
-@p procedure print_scaled(@!s:integer);
- {prints a scaled number, rounded to five digits}
-var @!delta:integer; {amount of allowable inaccuracy}
-begin if s<0 then
- begin print('-'); negate(s); {print the sign, if negative}
- end;
-print(s div unity:1); {print the integer part}
-s:=10*(s mod unity)+5;
-if s<>5 then
- begin delta:=10; print('.');
- repeat if delta>unity then
- s:=s+@'100000-(delta div 2); {round the final digit}
- print(chr(ord('0')+(s div unity))); s:=10*(s mod unity); delta:=delta*10;
- until s<=delta;
- end;
-end;
-
-@ Let's keep track of how many characters are in the font, and the
-locations of where each one occurred in the file.
-
-@<Glob...@>=
-@!total_chars:integer; {the total number of characters seen so far}
-@!char_ptr: array[0..255] of integer; {correct character location pointer}
-@!gf_prev_ptr: integer; {|char_ptr| for next character}
-@!character_code: integer; {current character number}
-
-@ @<Set init...@>=
-for i:=0 to 255 do char_ptr[i]:=-1; {mark characters as not being in the file}
-total_chars:=0;
-
-@ Before we get into the details of |do_char|, it is convenient to
-consider a simpler routine that computes the first parameter of each
-opcode.
-
-@d four_cases(#)==#,#+1,#+2,#+3
-@d eight_cases(#)==four_cases(#),four_cases(#+4)
-@d sixteen_cases(#)==eight_cases(#),eight_cases(#+8)
-@d thirty_two_cases(#)==sixteen_cases(#),sixteen_cases(#+16)
-@d thirty_seven_cases(#)==thirty_two_cases(#),four_cases(#+32),#+36
-@d sixty_four_cases(#)==thirty_two_cases(#),thirty_two_cases(#+32)
-
-@p function first_par(o:eight_bits):integer;
-begin case o of
-sixty_four_cases(paint_0): first_par:=o-paint_0;
-paint1,skip1,char_loc,char_loc+1,xxx1: first_par:=get_byte;
-paint1+1,skip1+1,xxx1+1: first_par:=get_two_bytes;
-paint1+2,skip1+2,xxx1+2: first_par:=get_three_bytes;
-xxx1+3,yyy: first_par:=signed_quad;
-boc,boc1,eoc,skip0,no_op,pre,post,post_post,undefined_commands: first_par:=0;
-sixty_four_cases(new_row_0), sixty_four_cases(new_row_0+64),
- thirty_seven_cases(new_row_0+128): first_par:=o-new_row_0;
-end;
-end;
-
-@ Strictly speaking, the |do_char| procedure is really a function with
-side effects, not a `\&{procedure}'\thinspace; it returns the value |false|
-if \.{GFtype} should be aborted because of some unusual happening. The
-subroutine is organized as a typical interpreter, with a multiway branch
-on the command code.
-
-@p function do_char:boolean;
-label 9998,9999;
-var o:eight_bits; {operation code of the current command}
-@!p,@!q:integer; {parameters of the current command}
-@!aok:boolean; {the value to return}
-begin {we've already scanned the |boc|}
-aok:=true;
-while true do @<Translate the next command in the \.{GF} file;
- |goto 9999| if it was |eoc|;
- |goto 9998| if premature termination is needed@>;
-9998: print_ln('!'); aok:=false;
-9999: do_char:=aok;
-end;
-
-@ @d show_label(#)==print(a:1,': ',#)
-@d show_mnemonic(#)==if wants_mnemonics then begin print_nl; show_label(#); end
-@d error(#)==begin show_label('! ',#); print_nl; end
-@d nl_error(#)==begin print_nl; show_label('! ',#); print_nl; end
-@d start_op==a:=cur_loc; o:=get_byte; p:=first_par(o);
- if eof(gf_file) then bad_gf('the file ended prematurely')
-@.the file ended prematurely@>
-
-@<Translate the next command...@>=
-begin start_op;
-@<Start translation of command |o| and |goto| the appropriate label to
- finish the job@>;
-end
-
-@ The multiway switch in |first_par|, above, was organized by the length
-of each command; the one in |do_char| is organized by the semantics.
-
-@<Start translation...@>=
-if o<=paint1+3 then @<Translate a sequence of |paint| commands,
- until reaching a non-|paint|@>;
-case o of
-four_cases(skip0): @<Translate a |skip| command@>;
-sixty_four_cases(new_row_0), sixty_four_cases(new_row_0+64),
- thirty_seven_cases(new_row_0+128):
- @<Translate a |new_row| command@>;
-@t\4@>@<Cases for commands |no_op|, |pre|, |post|, |post_post|, |boc|,
- and |eoc|@>@;
-four_cases(xxx1): @<Translate an |xxx| command@>;
-yyy: @<Translate a |yyy| command@>;
-othercases error('undefined command ',o:1,'!')
-@.undefined command@>
-endcases
-
-@ @<Cases for commands |no_op|...@>=
-no_op: show_mnemonic('no op');
-pre: begin error('preamble command within a character!'); goto 9998;
- end;
-@.preamble command within...@>
-post,post_post: begin error('postamble command within a character!');
-@.postamble command within...@>
- goto 9998;
- end;
-boc,boc1: begin error('boc occurred before eoc!'); goto 9998;
-@.boc occurred before eoc@>
- end;
-eoc: begin show_mnemonic('eoc');
- print_nl; goto 9999;
- end;
-
-@ @<Translate an |xxx| command@>=
-begin show_mnemonic('xxx '''); bad_char:=false; b:=16;
-if p<0 then nl_error('string of negative length!');
-@.string of negative length@>
-while p>0 do
- begin q:=get_byte;
- if (q<" ")or(q>"~") then bad_char:=true;
- if wants_mnemonics then
- begin print(xchr[q]);
- if b<line_length then incr(b)
- else begin print_nl; b:=2;
- end;
- end;
- decr(p);
- end;
-if wants_mnemonics then print('''');
-if bad_char then nl_error('non-ASCII character in xxx command!');
-@.non-ASCII character...@>
-end
-
-@ @<Glob...@>=
-@!bad_char:boolean; {has a non-ASCII character code appeared in this \\{xxx}?}
-
-@ @<Translate a |yyy| command@>=
-begin show_mnemonic('yyy ',p:1,' (');
-if wants_mnemonics then
- begin print_scaled(p); print(')');
- end;
-end
-
-@ The bulk of a \.{GF} file generally consists of |paint| commands,
-so we collect them together and print them in an abbreviated format
-on one line.
-
-@<Translate a sequence of |paint| commands...@>=
-begin if wants_mnemonics then print(' paint ');
-repeat @<Paint the next |p| pixels@>;
-start_op;
-until o>paint1+3;
-end
-
-@ @<Paint the next...@>=
-if wants_mnemonics then
- if paint_switch=white then print('(',p:1,')')@+else print(p:1);
-m:=m+p;
-if m>max_m_observed then max_m_observed:=m-1;
-if wants_pixels then
- @<Paint pixels |m-p| through |m-1| in row |n| of the subarray@>;
-paint_switch:=white+black-paint_switch
- {could also be |paint_switch:=not paint_switch|}
-
-@ We use the fact that the subarray has been initialized to all |white|.
-
-@<Paint pixels |m-p|...@>=
-if paint_switch=black then if n<=max_subrow then
- begin l:=m-p; r:=m-1;
- if r>max_subcol then r:=max_subcol;
- m:=l;
- while m<=r do
- begin image:=black; incr(m);
- end;
- m:=l+p;
- end
-
-@ @<Translate a |new_row| command@>=
-begin show_mnemonic('newrow ',p:1);
-incr(n); m:=p; paint_switch:=black;
-if wants_mnemonics then print(' (n=',max_n_stated-n:1,')');
-end
-
-@ @<Translate a |skip| command@>=
-begin show_mnemonic('skip',(o-skip1+1)mod 4:1,' ',p:1);
-n:=n+p+1; m:=0; paint_switch:=white;
-if wants_mnemonics then print(' (n=',max_n_stated-n:1,')');
-end
-
-@* Reading the postamble.
-Now imagine that we are reading the \.{GF} file and positioned just
-after the |post| command. That, in fact, is the situation,
-when the following part of \.{GFtype} is called upon to read, translate,
-and check the rest of the postamble.
-
-@p procedure read_postamble;
-var k:integer; {loop index}
-@!p,@!q,@!m,@!u,@!v,@!w,@!c:integer; {general purpose registers}
-begin post_loc:=cur_loc-1;
-print('Postamble starts at byte ',post_loc:1);
-@.Postamble starts at byte n@>
-if post_loc=gf_prev_ptr then print_ln('.')
-else print_ln(', after special info at byte ',gf_prev_ptr:1,'.');
-p:=signed_quad;
-if p<>gf_prev_ptr then
- error('backpointer in byte ',cur_loc-4:1,
- ' should be ',gf_prev_ptr:1,' not ',p:1,'!');
-@.backpointer...should be p@>
-design_size:=signed_quad; check_sum:=signed_quad;@/
-print('design size = ',design_size:1,' (');
-print_scaled(design_size div 16); print_ln('pt)');
-print_ln('check sum = ',check_sum:1);@/
-hppp:=signed_quad; vppp:=signed_quad;@/
-print('hppp = ',hppp:1,' ('); print_scaled(hppp); print_ln(')');
-print('vppp = ',vppp:1,' ('); print_scaled(vppp); print_ln(')');
-pix_ratio:=(design_size/1048576)*(hppp/1048576);
-min_m_stated:=signed_quad; max_m_stated:=signed_quad;
-min_n_stated:=signed_quad; max_n_stated:=signed_quad;@/
-print_ln('min m = ',min_m_stated:1,', max m = ',max_m_stated:1);@/
-if min_m_stated>min_m_overall then
- error('min m should be <=',min_m_overall:1,'!');
-if max_m_stated<max_m_overall then
- error('max m should be >=',max_m_overall:1,'!');
-print_ln('min n = ',min_n_stated:1,', max n = ',max_n_stated:1);@/
-if min_n_stated>min_n_overall then
- error('min n should be <=',min_n_overall:1,'!');
-if max_n_stated<max_n_overall then
- error('max n should be >=',max_n_overall:1,'!');
-@<Process the character locations in the postamble@>;
-@<Make sure that the end of the file is well-formed@>;
-end;
-
-@ @<Glob...@>=
-@!design_size,@!check_sum: integer; {\.{TFM}-oriented parameters}
-@!hppp, @!vppp: integer; {magnification-oriented parameters}
-@!post_loc: integer; {location of the |post| command}
-@!pix_ratio: real; {multiply by this to convert \.{TFM} width to scaled pixels}
-
-@ @<Set init...@>=
-min_m_overall:=max_int; max_m_overall:=-max_int;
-min_n_overall:=max_int; max_n_overall:=-max_int;
-
-@ When we get to the present code, the |post_post| command has
-just been read.
-
-@<Make sure that the end of the file is well-formed@>=
-if k<>post_post then
- error('should be postpost!');
-@.should be postpost@>
-for k:=0 to 255 do if char_ptr[k]>0 then
- error('missing locator for character ',k:1,'!');
-@.missing locator...@>
-q:=signed_quad;
-if q<>post_loc then
- error('postamble pointer should be ',post_loc:1,' not ',q:1,'!');
-@.postamble pointer should be...@>
-m:=get_byte;
-if m<>gf_id_byte then error('identification byte should be ',gf_id_byte:1,
- ', not ',m:1,'!');
-@.identification byte should be n@>
-k:=cur_loc; m:=223;
-while (m=223)and not eof(gf_file) do m:=get_byte;
-if not eof(gf_file) then bad_gf('signature in byte ',cur_loc-1:1,
-@.signature...should be...@>
- ' should be 223')
-else if cur_loc<k+4 then
- error('not enough signature bytes at end of file!')
-@.not enough signature bytes...@>
-
-@ @<Process the character locations...@>=
-repeat a:=cur_loc; k:=get_byte;
-if (k=char_loc)or(k=char_loc+1) then
- begin c:=first_par(k);
- if k=char_loc then
- begin u:=signed_quad; v:=signed_quad;
- end
- else begin u:=get_byte*unity; v:=0;
- end;
- w:=signed_quad; p:=signed_quad;
- print('Character ',c:1,': dx ',u:1,' (');
- print_scaled(u);
- if v<>0 then
- begin print('), dy ',v:1,' ('); print_scaled(v);
- end;
- print('), width ',w:1,' (');
- w:=round(w*pix_ratio);
- print_scaled(w);
- print_ln('), loc ',p:1);
- if char_ptr[c]=0 then
- error('duplicate locator for this character!')
-@.duplicate locator...@>
- else if p<>char_ptr[c] then
- error('character location should be ',char_ptr[c]:1,'!');
-@.character location should be...@>
- char_ptr[c]:=0;
- k:=no_op;
- end;
-until k<>no_op
-
-@* The main program.
-Now we are ready to put it all together. This is where \.{GFtype} starts,
-and where it ends.
-
-@p begin initialize; {get all variables initialized}
-dialog; {set up all the options}
-@<Process the preamble@>;
-@<Translate all the characters@>;
-print_nl;
-read_postamble;
-print('The file had ',total_chars:1,' character');
-if total_chars<>1 then print('s');
-print(' altogether.');
-@.The file had n characters...@>
-final_end:end.
-
-@ The main program needs a few global variables in order to do its work.
-
-@<Glob...@>=
-@!a:integer; {byte number of the current command}
-@!b,@!c,@!l,@!o,@!p,@!q,@!r:integer; {general purpose registers}
-
-@ \.{GFtype} looks at the preamble in order to do error checking, and to
-display the introductory comment.
-
-@<Process the preamble@>=
-open_gf_file;
-o:=get_byte; {fetch the first byte}
-if o<>pre then bad_gf('First byte isn''t start of preamble!');
-@.First byte isn't...@>
-o:=get_byte; {fetch the identification byte}
-if o<>gf_id_byte then
- bad_gf('identification byte should be ',gf_id_byte:1,
- ' not ',o:1);
-@.identification byte should be n@>
-o:=get_byte; {fetch the length of the introductory comment}
-print('''');
-while o>0 do
- begin decr(o); print(xchr[get_byte]);
- end;
-print_ln('''');
-
-@ @<Translate all...@>=
-repeat gf_prev_ptr:=cur_loc;
- @<Pass |no_op|, |xxx| and |yyy| commands@>;
- if o<>post then
- begin if o<>boc then if o<>boc1 then
- bad_gf('byte ',cur_loc-1:1,' is not boc (',o:1,')');
-@.byte n is not boc@>
- print_nl; print(cur_loc-1:1,': beginning of char ');
- @<Pass a |boc| command@>;
- if not do_char then bad_gf('char ended unexpectedly');
-@.char ended unexpectedly@>
- max_n_observed:=n;
- if wants_pixels then @<Print the image@>;
- @<Pass an |eoc| command@>;
- end;
-until o=post;
-
-@ @<Pass |no_op|, |xxx| and |yyy| commands@>=
-repeat start_op;
- if o=yyy then
- begin @<Translate a |yyy|...@>; o:=no_op;
- end
- else if (o>=xxx1) and (o<=xxx1+3) then
- begin @<Translate an |xxx|...@>; o:=no_op;
- end
- else if o=no_op then show_mnemonic('no op');
-until o<>no_op;
-
-@ @<Pass a |boc|...@>=
-a:=cur_loc-1; incr(total_chars);
-if o=boc then
- begin character_code:=signed_quad;
- p:=signed_quad;
- c:=character_code mod 256;
- if c<0 then c:=c+256;
- min_m_stated:=signed_quad; max_m_stated:=signed_quad;
- min_n_stated:=signed_quad; max_n_stated:=signed_quad;
- end
-else begin character_code:=get_byte; p:=-1; c:=character_code;
- q:=get_byte; max_m_stated:=get_byte; min_m_stated:=max_m_stated-q;
- q:=get_byte; max_n_stated:=get_byte; min_n_stated:=max_n_stated-q;
- end;
-print(c:1);
-if character_code<>c then
- print(' with extension ',(character_code-c) div 256 : 1);
-if wants_mnemonics then
- print_ln(': ',min_m_stated:1,'<=m<=',max_m_stated:1,' ',
- min_n_stated:1,'<=n<=',max_n_stated:1);
-max_m_observed:=-1;
-if char_ptr[c]<>p then
- error('previous character pointer should be ',char_ptr[c]:1,
- ', not ',p:1,'!')
-@.previous character...@>
-else if p>0 then if wants_mnemonics then
- print_ln('(previous character with the same code started at byte ',
- p:1,')');
-char_ptr[c]:=gf_prev_ptr;
-if wants_mnemonics then print('(initially n=',max_n_stated:1,')');
-if wants_pixels then @<Clear the image@>;
-m:=0; n:=0; paint_switch:=white;
-
-@ @<Pass an |eoc|...@>=
-max_m_observed:=min_m_stated+max_m_observed+1;
-n:=max_n_stated-max_n_observed; {now |n| is the minimum |n| observed}
-if min_m_stated<min_m_overall then min_m_overall:=min_m_stated;
-if max_m_observed>max_m_overall then max_m_overall:=max_m_observed;
-if n<min_n_overall then min_n_overall:=n;
-if max_n_stated>max_n_overall then max_n_overall:=max_n_stated;
-if max_m_observed>max_m_stated then
- print_ln('The previous character should have had max m >= ',
- max_m_observed:1,'!');
-@.previous character...@>
-if n<min_n_stated then
- print_ln('The previous character should have had min n <= ',n:1,'!')
-
-@* System-dependent changes.
-This section should be replaced, if necessary, by changes to the program
-that are necessary to make \.{GFtype} work at a particular installation.
-It is usually best to design your change file so that all changes to
-previous sections preserve the section numbering; then everybody's version
-will be consistent with the printed program. More extensive changes,
-which introduce new sections, can be inserted here; then only the index
-itself will get a new section number.
-@^system dependencies@>
-@* Index.
-Pointers to error messages appear here together with the section numbers
-where each ident\-i\-fier is used.