%%% ====================================================================
%%%  @TeX-file{
%%%     author          = "Alan Jeffrey",
%%%     version         = "1.335",
%%%     date            = "09 September 1994",
%%%     time            = "20:20:42 BST",
%%%     filename        = "fontinst.sty",
%%%     address         = "School of Cognitive and Computing Sciences
%%%                        University of Sussex
%%%                        Brighton BN1 9QH
%%%                        UK",
%%%     FAX             = "+44 273 678188",
%%%     email           = "alanje@cogs.susx.ac.uk",
%%%     codetable       = "ISO/ASCII",
%%%     keywords        = "AFM, virtual fonts, fonts, PostScript, TeX",
%%%     supported       = "yes",
%%%     abstract        = "This is the fontinst TeX file for font 
%%%                        installation.  It is part of the fontinst 
%%%                        package, and should not be distributed 
%%%                        independently.  Please see the accompanying 
%%%                        fontinst.tex for more details, or CHANGES for 
%%%                        the change log.", 
%%%     package         = "fontinst",
%%%     dependencies    = "fontinst.ini, trig.sty",
%%%  }
%%% ====================================================================

% Some catcode assignments just in case we're in iniTeX:

\catcode`\{=1
\catcode`\}=2
\catcode`\#=6
\catcode`\^=7 

% The current versions:

\def\fontinstversion{1.335}
\message{v\fontinstversion}

% Copyright 1993, 1994 Alan Jeffrey.

%%%%%%%%%%%%%%% SAVE CATCODES %%%%%%%%%%%%%%%
%
% Save the current values of the catcodes of space, @, NL, ~ and _.
% _ and @ are made letters, ~ is a space, and space and NL are ignored.

\edef\spacecatcode{\the\catcode`\ }
\edef\atcatcode{\the\catcode`\@}
\edef\nlcatcode{\the\catcode`\^^M}
\edef\underscorecatcode{\the\catcode`\_}
\edef\tildecatcode{\the\catcode`\~}

\catcode`\ =9
\catcode`\^^M=9
\catcode`\@=11
\catcode`\_=11
\catcode`\~=10


%%%%%%%%%%%%%%% STUFF FROM PLAIN %%%%%%%%%%%%%%%
%
% If we're running in iniTeX we input some definitions taken from
% plain. 

\ifx\@ne\undefined_command
   \input fontinst.ini\relax
\fi

%%%%%%%%%%%%%%% SOME TEMPORARY VARIABLES %%%%%%%%%%%%%%%

\newcount\a_count
\newcount\b_count
\newcount\c_count
\newcount\d_count
\newcount\e_count
\newcount\f_count
\newcount\g_count

\newdimen\a_dimen
\newdimen\b_dimen
\newdimen\c_dimen
\newdimen\d_dimen

\newtoks\a_toks
\newtoks\b_toks
\newtoks\c_toks

%%%%%%%%%%%%%%% SOME GLOBAL VARIABLES %%%%%%%%%%%%%%%

\newwrite\out_file

%%%%%%%%%%%%%%% SOME CONSTANTS %%%%%%%%%%%%%%%

\mathchardef\one_thousand=1000
\mathchardef\max_mathchardef="7FFF

%%%%%%%%%%%%%%% TRIGONOMETRY %%%%%%%%%%%%%%%
%
% Include David Carlisle's trigonometry macros,

% First do some hacks to get round all that \NeedsTeXFormat{LaTeX2e}
% stuff that David put in :-)

\def\NeedsTeXFormat#1{}
\def\ProvidesPackage#1 [#2]{}
\let\@tempdima\a_dimen
\let\@tempdimb\b_dimen

\input trig.sty

%%%%%%%%%%%%%%% SOME USEFUL TEX HACKS %%%%%%%%%%%%%%%

\def\x_cs#1#2{\expandafter#1\csname#2\endcsname}
\def\gobble_one#1{}
\def\gobble_two#1#2{}
\def\gobble_three#1#2#3{}
\def\identity_one#1{#1}
\def\first_char#1#2={#1}
\def\g_let{\global\let}
\def\empty_command{}

\bgroup
   \catcode`\[=1
   \catcode`\]=2
   \catcode`\%=12
   \catcode`\{=12
   \catcode`\}=12
   \gdef\percent_char[%]
   \gdef\left_brace_char[{]
   \gdef\right_brace_char[}]
\egroup

{
   \catcode`\p=12
   \catcode`\t=12
   \gdef\lose_measure#1pt{#1}
}

\def\add_to#1#2{
   \ifx#1\relax
      \def#1{#2}
   \else
      \expandafter\def\expandafter#1\expandafter{#1#2}
   \fi
}
   
\let\x_relax=\relax

\def\open_out#1{\immediate\openout\out_file=#1 \def\out_filename{#1}}
\def\out_line#1{\immediate\write\out_file{#1}}
\def\out_lline#1{\out_line{\space\space\space#1}}
\def\out_llline#1{\out_lline{\space\space\space#1}}
\def\close_out#1{\immediate\write16{#1~written~on~\out_filename.}
   \immediate\closeout\out_file}

% The command \do, protected from expansion.

\def\never_do{\noexpand\do}

% In order to write macros that expand out to nested if-statements,
% I say:
%
%    \ifblah...\then...\else...\fi
%
% In order to match the \fi, \then has to be an \if.

\let\then=\iffalse
\def\if_false{\iffalse}
\def\if_true{\iftrue}

% \if_or...\or_else...\then gives the disjunction of two booleans.

\def\if_or#1\or_else#2\then{
   #1\then
      \expandafter\if_true
   \else
      #2\then
         \expandafter\expandafter\expandafter\if_true
      \else
         \expandafter\expandafter\expandafter\if_false
      \fi
   \fi
}

% \if_file_exists checks to see if a file exits, using \openin.

\def\if_file_exists#1\then{
   \immediate\openin1=#1\relax
   \ifeof1\relax
      \immediate\closein1
      \expandafter\if_false
   \else
      \immediate\closein1
      \expandafter\if_true
   \fi
}

% If \@@input is defined, I'll assume it's the LaTeX version of the TeX 
% input primitive.  I need this so that I can say 
% \expandafter\primitiveinput foo, which doesn't work with the LaTeX
% version of \input. 

\x_cs\ifx{@@input}\relax
   \let\primitiveinput=\input
\else
   \let\primitiveinput=\@@input
\fi

%%%%%%%%%%%%%%% SETTING VARIABLES %%%%%%%%%%%%%%%
%
% The macros:
%
%    \setint{INT}{INTEGER EXPRESSION}
%    \setstr{STR}{STRING}
%    \setdim{DIM}{DIMENSION}
%    \setcommand \COMMAND DEFINITION
%
% define new macros \i-INT, \s-STR, \d-DIM or \COMMAND.  The macros:
%
%    \resetint{INT}{INTEGER EXPRESSION}
%    \resetstr{STR}{STRING}
%    \resetdim{DIM}{DIMENSION}
%    \resetcommand \COMMAND DEFINITION
%
% redefine the macros \i-INT, \s-STR, \d-DIM or \COMMAND.  The macros:
%
%    \int{INT}
%    \str{STR}
%    \dim{DIM}
%    \COMMAND
%
% return the values of \i-INT, \s-STR, \d-DIM or \COMMAND.  The macros:
%
%    \ifisint{INT}\then
%    \ifisstr{STR}\then
%    \ifisdim{DIM}\then
%    \ifiscommand\COMMAND\then
%
% return \if_true if \i-INT, \s-STR or \d-DIM have been defined, and 
% \if_false otherwise.
%
%    \unsetint{INT}
%    \unsetstr{STR}
%    \unsetdim{DIM}
%    \unsetcommand \COMMAND
% 
% undefine \i-INT, \s-STR, \d-DIM or \COMMAND.
%
% Integers are kept as \mathchardef's if possible.  I compared the 
% version where you try to keep ints as mathchardefs with the version 
% where you don't bother, and for a sample font without mathchardefs I 
% got: 
%
%   114673 words of memory out of 150001
%   Time elapsed: 135.0 seconds
%
% and with, I got:
%
%   114050 words of memory out of 150001
%   Time elapsed: 134.5 seconds
%
% so I've saved a little memory and time.  Not brilliant, but I may as 
% well keep it in.

\def\setint#1#2{
   \x_cs\ifx{i-#1}\relax
      \resetint{#1}{#2}
   \fi
}

\def\setstr#1#2{\x_cs\ifx{s-#1}\relax
   \x_cs\edef{s-#1}{#2}\fi}
\def\setdim#1#2{\x_cs\ifx{d-#1}\relax
   \a_dimen=#2\relax\x_cs\edef{d-#1}{\the\a_dimen}\fi}
\def\setcommand#1{\ifx#1\undefined_command
   \expandafter\def\expandafter#1\else
   \expandafter\def\expandafter\a_command\fi}

\def\resetint#1#2{
   \eval_expr{#2} 
   \ifnum\result<\max_mathchardef
      \ifnum\result<0
         \x_cs\edef{i-#1}{\the\result}
      \else
         \x_cs\mathchardef{i-#1}=\result
      \fi
   \else
      \x_cs\edef{i-#1}{\the\result}
   \fi
}

\def\resetstr#1#2{\x_cs\edef{s-#1}{#2}}
\def\resetdim#1#2{\a_dimen=#2\x_cs\edef{d-#1}{\the\a_dimen}}
\let\resetcommand=\def

\def\int#1{\csname~i-#1\endcsname}
\def\str#1{\csname~s-#1\endcsname}
\def\dim#1{\csname~d-#1\endcsname}

\def\ifisint#1\then{\x_cs\ifx{i-#1}\relax\expandafter\if_false
   \else\expandafter\if_true\fi}
\def\ifisstr#1\then{\x_cs\ifx{s-#1}\relax\expandafter\if_false
   \else\expandafter\if_true\fi}
\def\ifisdim#1\then{\x_cs\ifx{d-#1}\relax\expandafter\if_false
   \else\expandafter\if_true\fi}
\def\ifiscommand#1\then{\ifx#1\undefined_command\expandafter\if_false
   \else\expandafter\if_true\fi}

\def\unsetint#1{\x_cs\let{i-#1}\relax}
\def\unsetstr#1{\x_cs\let{s-#1}\relax}
\def\unsetdim#1{\x_cs\let{d-#1}\relax}
\def\unsetcommand#1{\let#1=\undefined_command}

%%%%%%%%%%%%%%% INTEGER EXPRESSIONS %%%%%%%%%%%%%%%
%
% The macro:
%
%    \eval_expr{INTEGER EXPRESSION}
%
% globally assigns \result to the value of INTEGER EXPRESSION, and 
% changes the value of no other counters.

\newcount\result

\def\eval_expr#1{\global\result=#1\relax}
\def\eval_expr_to#1#2{\eval_expr{#2}#1=\result}
\def\g_eval_expr_to#1#2{\eval_expr{#2}\global#1=\result}

%    \neg{INTEGER EXPRESSION}
%    \add{INTEGER EXPRESSION}{INTEGER EXPRESSION}
%    \sub{INTEGER EXPRESSION}{INTEGER EXPRESSION}
%    \mul{INTEGER EXPRESSION}{INTEGER EXPRESSION}
%    \div{INTEGER EXPRESSION}{INTEGER EXPRESSION}
%    \scale{INTEGER EXPRESSION}{INTEGER EXPRESSION}
%    \max{INTEGER EXPRESSION}{INTEGER EXPRESSION}
%    \min{INTEGER EXPRESSION}{INTEGER EXPRESSION}

\def\neg#1{#1\global\result=-\result}
\def\add#1#2{#1{\a_count=\result\eval_expr{#2}
   \global\advance\result by \a_count}}
\def\sub#1#2{#1{\a_count=\result\eval_expr{#2}
   \advance\a_count by -\result
   \global\result=\a_count}}
\def\mul#1#2{#1{\a_count=\result\eval_expr{#2}
   \global\multiply\result by \a_count}}
\def\div#1#2{#1{\a_count=\result\eval_expr{#2}
   \divide\a_count by \result
   \global\result=\a_count}}
\def\scale#1#2{#1{\a_count=\result\eval_expr{#2}
   \global\multiply\result by \a_count
   \global\divide\result by \one_thousand}}
\def\max#1#2{#1{\a_count=\result\eval_expr{#2}
   \ifnum\a_count>\result \global\result=\a_count \fi}}
\def\min#1#2{#1{\a_count=\result\eval_expr{#2}
   \ifnum\a_count<\result \global\result=\a_count \fi}}
   
%%%%%%%%%%%%%%% CONVERTING AN ENC FILE TO AN ETX FILE %%%%%%%%%%%%%%%
%
% The macro:
%
%    \enctoetx{ENCFILE}{ETXFILE}
%
% reads ENCFILE.enc and writes the same information to ETXFILE.etx,
% in a format TeX can read more easily.

\newif\ifmissingslots

{
   \catcode`\/=\active
   \catcode`\]=\active
   \gdef\enctoetx#1#2{{
      \catcode`\/=\active
      \catcode`\]=\active
      \def/##1[{
         \a_count=0
         \global\missingslotsfalse
         \def/####1~{
            \csname~o-####1\endcsname{
               \ifmissingslots
                  \out_line{\string\nextslot{\the\a_count}}
               \fi
               \global\missingslotsfalse               
               \out_line{\string\setslot{####1}}
               \out_line{\string\endsetslot}
               \out_line{}
            }
            \advance\a_count by 1
         }
      }
      \def]~def{}
      \make_etx{#1}{#2}
   }}
}

\x_cs\def{o-.notdef}#1{\global\missingslotstrue}

\def\make_etx#1#2{
   \open_out{\temp_prefix#2.etx}
   \out_line{\percent_char~Filename:~#2.etx}
   \out_line{\percent_char~Created~by:~tex~\jobname}
   \out_line{\percent_char~Created~using:~\string\enctoetx{#1}{#2}}
   \out_line{}
   \out_line{\percent_char~This~file~contains~the
      information~of~#1.enc~in~a~form}
   \out_line{\percent_char~more~easily~read~by~TeX.
      It~is~used~by~the~fontinst~package.}
   \out_line{}
   \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
   \out_line{}
   \out_line{\string\relax}
   \out_line{}
   \out_line{\string\documentstyle[fontdoc,twocolumn]{article}}
   \out_line{}
   \out_line{\string\begin{document}}
   \out_line{}
   \out_line{This~document~describes~the~#1~encoding.}
   \out_line{It~was~automatically~generated~by~the}
   \out_line{{\string\tt\space~fontinst}~package.}
   \out_line{}
   \out_line{\string\encoding}
   \out_line{}
   \out_line{\string\needsfontinstversion{\fontinstversion}}
   \out_line{}
   \primitiveinput #1.enc\relax
   \out_line{}
   \out_line{\string\endencoding}
   \out_line{}
   \out_line{\string\end{document}}
   \close_out{Encoding~vector}
}

%%%%%%%%%%%%%%% CONVERTING AN AFM FILE TO AN MTX FILE %%%%%%%%%%%%%%%
%
% The macro:
%
%    \afmtomtx{AFMFILE}{MTXFILE}
%
% reads ETXFILE.etx and AFMFILE.afm, and writes the same information
% out to MTXFILE.mtx.

\newcount\minimum_kern

\def\afmtomtx#1#2{{
   \open_out{\temp_prefix#2.mtx}
   \def\raw_font_name{#2}
   \_italicfalse
   \setint{minimumkern}{0}
   \minimum_kern=\int{minimumkern}
   \out_line{\percent_char~Filename:~#2.mtx}
   \out_line{\percent_char~Created~by:~tex~\jobname}
   \out_line{\percent_char~Created~using:~\string\afmtomtx{#1}{#2}}
   \out_line{}
   \out_line{\percent_char~This~file~contains~the
      information~of~#1.afm~in~a~form}
   \out_line{\percent_char~more~easily~read~by~TeX.~
      It~is~used~by~the~fontinst~package.}
   \out_line{}
   \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
   \out_line{}
   \out_line{\string\relax}
   \out_line{\string\metrics}
   \out_line{}
   \out_line{\string\needsfontinstversion{\fontinstversion}}
   \out_line{}
   \catcode`\^^M=12
   \catcode`\ =10
   \expandafter\afm_line\primitiveinput #1.afm\relax
   \out_line{}
   \out_line{\string\endmetrics}
   \close_out{Metrics}
}}

% The variable \if_italic is set true if the font is italic.

\newif\if_italic

% The command \afm_line reads to the end of the line, calls
% \afm_command on that line, then calls \afm_line again.

{\catcode`\^^M=12 \gdef\afm_line#1
{\afm_command#1~\end_of_line\afm_line}}

% The command \afm_command reads the first word FOO, and calls afm-FOO.
% If this does not exist, then \gobble_one_line will eat up the rest of the
% line.

\def\afm_command#1~{\csname~afm-#1\endcsname\gobble_one_line}
\def\gobble_one_line#1\end_of_line{}

% This all stops when we reach the command EndFontMetrics.

\x_cs\def{afm-EndFontMetrics}#1\afm_line{}

% To define an afm command, you say \afm_def{COMMAND}(PATTERN){RESULT}

\def\afm_def#1(#2)#3{\x_cs\def{afm-#1}
   \gobble_one_line#2\end_of_line{#3}}

% For example, we can define the following afm commands:

\afm_def{CharWidth}(#1){\charxwidth=#1\relax}
\afm_def{XHeight}(#1){\out_line{\string\setint{xheight}{#1}}}
\afm_def{ItalicAngle}(#1){\calculate_it_slant{#1}}
\afm_def{Ascender}(#1){\out_line{\string\setint{ascender}{#1}}}
\afm_def{CapHeight}(#1){\out_line{\string\setint{capheight}{#1}}}
\afm_def{UnderlineThickness}(#1){\out_line{\string
   \setint{underlinethickness}{#1}}}
\afm_def{IsFixedPitch}(#1){
   \if\first_char#1=f
   \else\out_line{\string\setint{monowidth}{1}}
   \fi
}

\afm_def{KP}(#1~#2~#3~#4){
   \ifnum#3>\minimum_kern\relax
      \out_line{\string\setkern{#1}{#2}{#3}}
   \else\ifnum#3<-\minimum_kern\relax
      \out_line{\string\setkern{#1}{#2}{#3}}
   \fi\fi
}

\afm_def{KPX}(#1~#2~#3~#4){
   \ifnum#3>\minimum_kern\relax
      \out_line{\string\setkern{#1}{#2}{#3}}
   \else\ifnum#3<-\minimum_kern\relax
      \out_line{\string\setkern{#1}{#2}{#3}}
   \fi\fi
}

\afm_def{C}(#1~;#2){\init_afm{#1}\do_list[#2]\afm_char}
\afm_def{CH}(#1~;#2){\init_afm{#1}\do_list[#2]\afm_char}

\afm_def{CC}(#1~#2~;#3){\init_cc{#1}\do_list[#3]\cc_char}

% When parsing a character, we set the values of the following
% variables:

\newcount\char_slot
\newcount\char_x_width
\newcount\x_width
\newcount\bbox_llx
\newcount\bbox_lly
\newcount\bbox_urx
\newcount\bbox_ury
\let\char_name=\empty_command

% \init_afm initializes the variables the AFM character list writes to.

\def\init_afm#1{
   \char_slot=#1\relax
   \x_width=\char_x_width
   \bbox_llx=0
   \bbox_lly=0
   \bbox_urx=0
   \bbox_ury=0
   \let\char_name=\empty_command
}

% \afm_char writes the values of these variables to the MTX file, and 
% saves them in a macro \g-GLYPHNAME, in the form:
%
%    {WIDTH}{HEIGHT}{DEPTH}{ITALIC}
%    
% These are needed, because the (grumble grumble) syntax of CC commands 
% doesn't include the glyph measurements, so we have to remember them.

\def\afm_char{
   \a_count=-\bbox_lly
   \if_italic
      \b_count=-\x_width
      \advance\b_count by \bbox_urx
      \ifnum\b_count>0\else
         \b_count=0
      \fi
   \else
      \b_count=0
   \fi
   \out_line{
      \ifnum\char_slot>-1
         \string\setrawglyph
      \else
         \string\setnotglyph
      \fi
      {\char_name}
      {\raw_font_name}
      {10pt}
      {\the\char_slot}
      {\the\x_width}
      {\the\bbox_ury}
      {\the\a_count}
      {\the\b_count}
   }
}

% \init_cc and \cc_char write out a composite character glyph.

\def\init_cc#1{%
   \out_line{\string\setglyph{#1}}
   \def\char_name{#1}
}

\def\cc_char{%
   \out_lline{\string\samesize{\char_name-not}}
   \out_line{\string\endsetglyph}
}

% To set the italic angle, we need to calculate the tangent of the
% angle that the afm file contains.  This is done with David
% Carlisle's trig macros.  We need to do a bit of trickery to strip
% off any spaces which may have crept into the end of the angle, since
% the trig macros don't like space at the end of their argument.

\def\calculate_it_slant#1{
   \edef\theangle{\strip_spaces#1~\end_strip_spaces}
   \CalculateTan{\theangle}
   \a_dimen=-\one_thousand sp
   \a_dimen=\UseTan{\theangle}\a_dimen
   \a_count=\a_dimen
   \out_line{\string\setint{italicslant}{\the\a_count}}
   \ifnum\a_count>0~\_italictrue \else \_italicfalse \fi
}

\def\strip_spaces#1~#2\end_strip_spaces{#1}

% To process a list of commands separated by semi-colons, we call
% \do_list[LIST].  This works in a similar way to \afm_line.

\def\do_list[~#1~#2;~#3]{
   \csname~list-#1\endcsname\gobble_one_semi#2;
   \ifx\relax#3\relax\expandafter\gobble_one
   \else\expandafter\identity_one\fi
   {\do_list[~#3]}
}
\def\gobble_one_semi#1;{}

% There is an analagous \listdef for defining commands to be used
% inside lists.

\def\list_def#1(#2)#3{\x_cs\def{list-#1}\gobble_one_semi#2~;{#3}}

% For example, these are the commands that are used in giving
% character metrics:

\list_def{W}(#1~#2){\x_width=#1\relax}
\list_def{WX}(#1){\x_width=#1\relax}
\list_def{WY}(#1){}
\list_def{N}(#1){\def\char_name{#1}}
\list_def{B}(#1~#2~#3~#4){
   \bbox_llx=#1\relax
   \bbox_lly=#2\relax
   \bbox_urx=#3\relax
   \bbox_ury=#4\relax
}
\list_def{PCC}(#1~#2~#3){
   \out_lline{\string\glyphpcc{#1}{#2}{#3}}
}

%%%%%%%%%%%%%%% CONVERTING A PL FILE TO AN MTX FILE %%%%%%%%%%%%%%%
%
% The macro:
%
%    \pltomtx{PLFILE}{MTXFILE}
%
% reads PLFILE.pl, and writes the same information
% out to MTXFILE.mtx.  It can't cope with SKIP commands.

\def\pltomtx#1#2{{
   \def\raw_font_name{#1}
   \open_out{\temp_prefix#2.mtx}
   \out_line{\percent_char~Filename:~#2.mtx}
   \out_line{\percent_char~Created~by:~tex~\jobname}
   \out_line{\percent_char~Created~using:~\string\pltomtx{#1}{#2}}
   \out_line{}
   \out_line{\percent_char~This~file~contains~the~
      information~of~#1.pl~in~a~form}
   \out_line{\percent_char~more~easily~read~by~TeX.~
      It~is~used~by~the~fontinst~package.}
   \out_line{}
   \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
   \out_line{}
   \out_line{\string\relax}
   \out_line{\string\metrics}
   \out_line{}
   \out_line{\string\needsfontinstversion{\fontinstversion}}
   \out_line{}
   \catcode`\(=0 \catcode`\)=9 
   \let\/=\ignore_parens
   \let\do_pl_glyph=\relax
   \primitiveinput #1.pl\relax
   \do_pl_glyph
   \out_line{}
   \out_line{\string\endmetrics}
   \close_out{Metrics}
}}

% To parse a PL file, we first make ( the escape character, make )
% ignored, then define the various PL commands.
%
% We can ignore a parenthesis matched string by making ( and ) the
% group delimiters, then gobbling them up.

\def\ignore_parens{\bgroup\catcode`(=1 \catcode`)=2 \relax
   \expandafter\expandafter\expandafter\gobble_parens
      \iftrue\expandafter{\else}\fi}
\def\gobble_parens#1{\egroup}

% Convert a PL real to an AFM unit, assuming it contains a decimal
% point. 

\def\pl_real#1{\pl_realer(#1000)}
\def\pl_realer(#1.#2#3#4#5){#1#2#3#4}

% Convert a PL int to a TeX int, assuming it's prefixed by C, D, O, or
% H. 

\def\pl_int#1#2{
   \ifx#1C `#2
   \else\ifx#1D #2
   \else\ifx#1O '#2
   \else\ifx#1H "#2
   \else\errmessage{Unknown~PL~number~prefix~`#1'}
   \fi\fi\fi\fi
}

% Many of the PL commands are ignored, and I'm assuming the R's are in
% the places tftopl puts them, which is a bit naughty of me...

\let\COMMENT=\ignore_parens
\let\FAMILY=\ignore_parens
\let\FACE=\ignore_parens
\let\CHECKSUM=\ignore_parens
\let\BOUNDARYCHAR=\ignore_parens
\let\LIG=\ignore_parens
\let\NEXTLARGER=\ignore_parens
\let\VARCHAR=\ignore_parens

% When we reach a CODINGSCHEME instruction, we read the coding string, 
% and read in the corresponding etx file.

\def\CODINGSCHEME{\bgroup\catcode`\)=12\relax\CODINGSCHEME_cont}
\def\CODINGSCHEME_cont#1){
   \egroup
   \x_cs\ifx{enc-#1}\relax
      \errhelp{The~encoding~`#1'~has~not~been~declared.^^J
         You~should~declare~it~with~\string\declarenecoding{#1}{ETXFILE}.^^J
         Press~<RETURN>~to~carry~on~with~fingers~crossed,^^J
         or~X~<RETURN>~to~exit.}
      \errmessage{Undeclared~encoding~`#1'}
   \else
      \def\do_slot{\x_cs\let{name-\the\slot_number}\slot_name}
      \catcode`\(=12 \catcode`\)=12
      \x_cs\inputetx{enc-#1}\relax
      \catcode`\(=0 \catcode`\)=9 
   \fi
}

\def\DESIGNSIZE~#1~#2~{
   \a_dimen=#2pt
   \out_line{\string\setdim{designsize}{\the\a_dimen}}
}

\let\FONTDIMEN=\relax
\def\SLANT~R~#1~{\out_line{\string\setint{italicslant}{\pl_real{#1}}}}
\def\SPACE~R~#1~{\out_line{\string\setint{interword}{\pl_real{#1}}}}
\def\STRETCH~R~#1~{\out_line{\string\setint{stretchword}{\pl_real{#1}}}}
\def\SHRINK~R~#1~{\out_line{\string\setint{shrinkword}{\pl_real{#1}}}}
\def\XHEIGHT~R~#1~{\out_line{\string\setint{xheight}{\pl_real{#1}}}}
\def\QUAD~R~#1~{\out_line{\string\setint{quad}{\pl_real{#1}}}}
\def\EXTRASPACE~R~#1~{\out_line{\string\setint{extraspace}{\pl_real{#1}}}}
\def\DEFAULTRULETHICKNESS~R~#1~{
   \out_line{\string\setint{underlinethickness}{\pl_real{#1}}}
}

\def\HEADER~#1~#2~#3~#4~{}
\def\SEVENBITSAFEFLAG~#1~{}
\def\PARAMETER~#1~#2~#3~#4~{}
\def\NUM#1~#2~#3~{}
\def\DENOM#1~#2~#3~{}
\def\SUP#1~#2~#3~{}
\def\SUB#1~#2~#3~{}
\def\SUBDROP~#1~#2~{}
\def\SUPDROP~#1~#2~{}
\def\DELIM#1~#2~#3~{}
\def\AXISHEIGHT~#1~#2~{}
\def\BIGOPSPACING#1~#2~#3~{}

\def\LIGTABLE{\let\do=\never_do\let\temp_command\empty_command}
\def\LABEL~#1~#2~{\edef\temp_command{\temp_command\do{\pl_int{#1}{#2}}}}
\def\STOP{\let\temp_command\empty_command}
\def\SKIP~#1~#2~{\immediate\write16{Warning:~SKIP~instruction~ignored.}}
\def\KRN~#1~#2~R~#3~{
   \edef\do{\noexpand\write_pl_krn{\pl_int{#1}{#2}}{\pl_real{#3}}}
   \temp_command 
   \let\do=\never_do
}

\def\write_pl_krn#1#2#3{
   \f_count=#1
   \g_count=#3
   \out_line{\string\setkern{\csname~name-\the\g_count\endcsname}
      {\csname~name-\the\f_count\endcsname}
      {#2}}
}

\def\CHARWD~R~#1~{\b_count=\pl_real{#1}}
\def\CHARHT~R~#1~{\c_count=\pl_real{#1}}
\def\CHARDP~R~#1~{\d_count=\pl_real{#1}}
\def\CHARIC~R~#1~{\e_count=\pl_real{#1}}
\def\CHARACTER~#1~#2~{
   \do_pl_glyph
   \a_count=\pl_int{#1}{#2}
   \b_count=0
   \c_count=0
   \d_count=0
   \e_count=0
   \let\do_pl_glyph=\write_pl_glyph
}

\def\write_pl_glyph{
      \x_cs\ifx{name-\the\a_count}\relax\else
         \out_line{\string\setrawglyph
            {\csname~name-\the\a_count\endcsname}
            {\raw_font_name}
            {\the\a_dimen}
            {\the\a_count} 
            {\the\b_count} 
            {\the\c_count} 
            {\the\d_count} 
            {\the\e_count}}
      \fi
   }

%%%%%%%%%%%%%%% ENCODING FILES %%%%%%%%%%%%%%%
%
% The macro:
%
%    \inputetx{FILENAME}
%
% inputs FILENAME.etx, ignoring anything between \relax and \encoding, 
% and anything after \endencoding.

\def\inputetx#1{
   \slot_number=0
   \def\relax{\let\relax=\x_relax\iffalse}
   \let\encoding=\fi
   \let\endencoding=\endinput
   \primitiveinput #1.etx\x_relax
   \let\relax=\x_relax
}

%    \setslot{NAME} SLOT COMMANDS \endsetslot
%
% Sets \slot_number to the current slot, \slot_name to NAME, and calls 
% \do_slot at the beginning of the slot and \end_do_slot at the end.  By 
% default, \do_slot and \end_do_slot do nothing, but this is over-ridden 
% later. 

\newcount\slot_number

\def\setslot#1{\edef\slot_name{#1}\do_slot}
\def\endsetslot{\end_do_slot\advance\slot_number by 1\relax}

\let\do_slot\empty_command
\let\end_do_slot\empty_command

% The SLOT COMMANDS are:
%
%    \nextslot{INTEGER EXPRESSION}
%
% Sets \slot_number.
%
%    \ligature{LIG}{GLYPH}{GLYPH}
%    \nextlarger{GLYPH}
%    \varchar VARCHAR COMMANDS \endvarchar
%    \comment{TEXT}
%    \usedas{COMMAND}{TYPE}
%
% By default, these do nothing, but are over-ridden later.

\def\nextslot#1{\slot_number=#1\relax}

\let\ligature=\gobble_three
\let\nextlarger=\gobble_one
\let\varchar=\empty_command
\let\endvarchar=\empty_command
\let\usedas=\gobble_two
\let\comment=\gobble_one

% The VARCHAR COMMANDS are:
%
%    \vartop{GLYPH}
%    \varmid{GLYPH}
%    \varbot{GLYPH}
%    \varrep{GLYPH}

\let\vartop=\gobble_one
\let\varmid=\gobble_one
\let\varbot=\gobble_one
\let\varrep=\gobble_one

%%%%%%%%%%%%%%% METRIC FILES %%%%%%%%%%%%%%%
%
% The macro:
%
%    \inputmtx{FILENAME}
%
% inputs FILENAME.mtx, ignoring anything between \relax and \metrics, 
% and anything after \endmetrics. 

\def\inputmtx#1{
   \a_count=0
   \def\relax{\let\relax=\x_relax\iffalse}
   \let\metrics=\fi
   \let\endmetrics=\endinput
   \primitiveinput #1.mtx\x_relax
   \let\relax=\x_relax
}

% The kerning information is kept in the macros \l-NAME and \r-NAME,
% containing information about how NAME kerns on the left and on the
% right, respectively.  The \l-NAME macro should expand out to a series of 
% \k\r-NAME\AMOUNT macros, and vice versa.
%
% Where possible, we avoid re-scaling, which saves a bit of time and memory.  
% With a sample font, the version where we didn't avoid re-scaling used:
%
%   114050 words of memory out of 150001
%   Time elapsed: 134.5 seconds
%
% whereas the version where we do avoid it used:
%
%   113786 words of memory out of 150001
%   Time elapsed: 124.9 seconds
%
% We keep the names of the glyphs to kern with as \l-NAME and \r-NAME to 
% save on token space, and this got the resources used down to:
%
%   88574 words of memory out of 150001
%   Time elapsed: 106.1 seconds
%
% Keeping track of the kern amounts as \AMOUNT got the resources used 
% down to:
%
%   75424 words of memory out of 150001
%   Time elapsed: 97.2 seconds
%
% Mind you, I then added all the \transformfont stuff, and it went back to:
%
%   77079 words of memory out of 150001
%   Time elapsed: 97.7 seconds

\def\setkern#1#2#3{
   \x_cs\ifx{i-rawscale}\relax
      \expandafter\set_kern
         \csname~r-#1\expandafter\endcsname
         \csname~l-#2\endcsname{#3}
   \else
      \expandafter\set_kern
         \csname~r-#1\expandafter\endcsname
         \csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}}
   \fi
}

\def\set_kern#1#2#3{
   \eval_expr{#3}
   \expandafter\set_kern_cs\csname\the\result\endcsname#1#2
}

\def\set_kern_cs#1#2#3{
   \add_to#2{\k#3#1}
   \add_to#3{\k#2#1}
}

\def\setleftkerning#1#2#3{
   \eval_expr_to\b_count{#3}
   \expandafter\set_kerning
      \csname~l-#1\expandafter\endcsname
      \csname~l-#2\endcsname
}

\def\setrightkerning#1#2#3{
   \eval_expr_to\b_count{#3}
   \expandafter\set_kerning
      \csname~r-#1\expandafter\endcsname
      \csname~r-#2\endcsname
}

\def\set_kerning#1#2{
   \if\b_count=\one_thousand
      \def\k##1##2{
         \set_kern_cs##2##1#1
      }
   \else
      \def\k##1##2{
         \set_kern##1#1{
            \scale\b_count{\expandafter\gobble_one\string##2}
         }
      }
   \fi
   #2
}

\def\kerning#1#2{0\relax
   \def\k##1{\csname~set-\string##1\endcsname\gobble_one}
   \bgroup
   \x_cs\def{set-\string\l-#2}##1##2{
      \global\result=\expandafter\gobble_one\string##2\egroup
   }   
   \csname~r-#1\endcsname
   \csname~set-\string\l-#2\endcsname\gobble_one{00}
}

% The glyph information is kept in the macros \g-NAME, which expands
% out to:
%
%    {WIDTH}{HEIGHT}{DEPTH}{ITALIC}
%    {MAPCOMMANDS}{MAPFONTS}
%
% where the MAPCOMMANDS will write out VPL MAP fragments to a VPL
% file, and the MAPFONTS will produce any MAPFONT instructions that
% are needed.

\def\width{\glyph_parameter\first_of_six}
\def\height{\glyph_parameter\second_of_six}
\def\depth{\glyph_parameter\third_of_six}
\def\italic{\glyph_parameter\fourth_of_six}
\def\mapcommands{\glyph_parameter\fifth_of_six}
\def\mapfonts{\glyph_parameter\sixth_of_six}

\def\glyph_parameter#1#2{
   \expandafter\expandafter\expandafter
         #1\csname~g-#2\endcsname
}

\def\first_of_six#1#2#3#4#5#6{#1}
\def\second_of_six#1#2#3#4#5#6{#2}
\def\third_of_six#1#2#3#4#5#6{#3}
\def\fourth_of_six#1#2#3#4#5#6{#4}
\def\fifth_of_six#1#2#3#4#5#6{#5}
\def\sixth_of_six#1#2#3#4#5#6{#6}

% These are the commands allowed inside a glyph.  They are initally set 
% to \relax, so we can \edef with them safely.

\let\saved_scale\relax
\let\saved_mapfont\relax
\let\saved_raw\relax
\let\saved_rule\relax
\let\saved_special\relax
\let\saved_warning\relax
\let\saved_movert\relax
\let\saved_moveup\relax
\let\saved_push\relax
\let\saved_pop\relax

% When the glyph is being constructed by \setglyph...\endsetglyph, the
% values of each of these parameters are kept in the following
% variables.  Except for \glyphwidth, these are kept globally, so they
% survive through \push ... \pop pairs.

\newcount\glyph_width
\newcount\glyph_height
\newcount\glyph_depth
\newcount\glyph_italic
\newtoks\glyph_map_commands
\newtoks\glyph_map_fonts

% In addition, the current vertical offset is kept locally in 
% \glyph_voffset. 

\newcount\glyph_voffset

% The \setglyph{NAME} command defines \g-NAME, unless \g-NAME has already 
% been defined.

\def\setglyph#1{
   \ifisglyph{#1}\then
      \expandafter\gobble_glyph
   \else
      \x_cs\def{g-#1}{{\the\glyph_width}{\the
         \glyph_height}{\the\glyph_depth}{\the\glyph_italic}{\the
         \glyph_map_commands}{\the\glyph_map_fonts}}      
      \resetglyph{#1}
   \fi
}

\long\def\gobble_glyph#1\endsetglyph{}

\def\resetglyph#1{
   \def\glyphname{#1}
   \glyph_width=0
   \global\glyph_height=0
   \global\glyph_depth=0
   \global\glyph_italic=0
   \glyph_voffset=0
   \global\glyph_map_commands={}
   \global\glyph_map_fonts={}
}

\def\endsetglyph{
   \x_cs\edef{g-\glyphname}{{\the\glyph_width}{\the
      \glyph_height}{\the\glyph_depth}{\the\glyph_italic}{\the
      \glyph_map_commands}{\the\glyph_map_fonts}}
}

\let\endresetglyph=\endsetglyph

\def\setrawglyph#1#2#3#4#5#6#7#8{
   \x_cs\ifx{g-#1}\relax
      \x_cs\ifx{i-rawscale}\relax
         \x_cs\def{g-#1}{
            {#5}
            {#6}
            {#7}
            {#8}
            {\saved_raw{#2}{#4}{#1}}
            {\saved_mapfont{#2}{#3}}
         }
      \else
         \eval_expr_to\e_count{\int{rawscale}}
         \eval_expr_to\a_count{\scale{#5}\e_count}
         \eval_expr_to\b_count{\scale{#6}\e_count}
         \eval_expr_to\c_count{\scale{#7}\e_count}
         \eval_expr_to\d_count{\scale{#8}\e_count}
         \x_cs\edef{g-#1}{
            {\the\a_count}
            {\the\b_count}
            {\the\c_count}
            {\the\d_count}
            {\saved_scale{\the\e_count}
               {\saved_raw{#2}{#4}{#1}}}
            {\saved_scale{\the\e_count}
               {\saved_mapfont{#2}{#3}}}
         }
      \fi
   \fi
}

\def\setnotglyph#1#2#3#4#5#6#7#8{
   \x_cs\ifx{g-#1-not}\relax
      \x_cs\ifx{i-rawscale}\relax
         \x_cs\def{g-#1-not}{
            {#5}
            {#6}
            {#7}
            {#8}
            {}
            {}
         }
      \else
         \eval_expr_to\e_count{\int{rawscale}}
         \eval_expr_to\a_count{\scale{#5}\e_count}
         \eval_expr_to\b_count{\scale{#6}\e_count}
         \eval_expr_to\c_count{\scale{#7}\e_count}
         \eval_expr_to\d_count{\scale{#8}\e_count}
         \x_cs\edef{g-#1-not}{
            {\the\a_count}
            {\the\b_count}
            {\the\c_count}
            {\the\d_count}
            {}
            {}
         }
      \fi
   \fi
}

\def\unsetglyph#1{\x_cs\let{g-#1}\relax}

% The glyph commands are:

\def\glyph#1#2{
   \eval_expr_to\b_count{#2}
   \eval_expr_to\glyph_width{\add\glyph_width{\scale\b_count{\width{#1}}}}
   \g_eval_expr_to\glyph_height{\max\glyph_height
      {\add{\scale\b_count{\height{#1}}}\glyph_voffset}}
   \g_eval_expr_to\glyph_depth{\max\glyph_depth
      {\sub{\scale\b_count{\depth{#1}}}\glyph_voffset}}
   \g_eval_expr_to\glyph_italic{\scale\b_count{\italic{#1}}}
   \edef\temp_command{\the\glyph_map_commands
      \saved_scale{\the\b_count}{\mapcommands{#1}}}
   \global\glyph_map_commands\expandafter{\temp_command}
   \edef\temp_command{\the\glyph_map_fonts
      \saved_scale{\the\b_count}{\mapfonts{#1}}}
   \global\glyph_map_fonts\expandafter{\temp_command}
}

\def\glyphrule#1#2{
   \eval_expr_to\b_count{#1} \eval_expr_to\c_count{#2}
   \advance\glyph_width by \b_count
   \g_eval_expr_to\glyph_depth{\max\glyph_depth{-\glyph_voffset}}
   \g_eval_expr_to\glyph_height{\max\glyph_height{\add\glyph_voffset\c_count}}
   \global\glyph_italic=0
   \edef\temp_command{\the\glyph_map_commands
      \saved_rule{\the\b_count}{\the\c_count}}
   \global\glyph_map_commands\expandafter{\temp_command}
}

\def\glyphspecial#1{
   \edef\temp_command{\the\glyph_map_commands\saved_special{#1}}
   \global\glyph_map_commands\expandafter{\temp_command}}

\def\glyphwarning#1{
   \edef\temp_command{\the\glyph_map_commands\saved_warning{#1}}
   \global\glyph_map_commands\expandafter{\temp_command}}

\def\movert#1{
   \eval_expr{#1}
   \ifnum\result=0\else
      \advance\glyph_width by \result
      \edef\temp_command{\the\glyph_map_commands\saved_movert{\the\result}}
      \global\glyph_map_commands\expandafter{\temp_command}
   \fi}

\def\moveup#1{
   \eval_expr{#1}
   \ifnum\result=0\else
      \advance\glyph_voffset by \result
      \edef\temp_command{\the\glyph_map_commands\saved_moveup{\the\result}}
      \global\glyph_map_commands\expandafter{\temp_command}
   \fi}

\def\push{\bgroup
   \edef\temp_command{\the\glyph_map_commands\saved_push}
   \global\glyph_map_commands\expandafter{\temp_command}}

\def\pop{\egroup
   \edef\temp_command{\the\glyph_map_commands\saved_pop}
   \global\glyph_map_commands\expandafter{\temp_command}}

\def\resetwidth#1{\movert{\sub{#1}\glyph_width}}
\def\resetheight{\g_eval_expr_to\glyph_height}
\def\resetdepth{\g_eval_expr_to\glyph_depth}
\def\resetitalic{\g_eval_expr_to\glyph_italic}

% Some syntactic sugar... \glyphpcc could do with optimization...

\def\glyphpcc#1#2#3{
   \push
      \movert{#2}
      \moveup{#3}
      \glyph{#1}{\one_thousand}
   \pop
}

\def\samesize#1{
   \expandafter\expandafter\expandafter
      \same_size\csname g-#1\endcsname
}

\def\same_size#1#2#3#4#5#6{
   \movert{\sub{#1}\glyph_width}
   \global\glyph_height=#2
   \global\glyph_depth=#3
   \global\glyph_italic=#4
}

% The control flow command:

\def\ifisglyph#1\then{
   \x_cs\ifx{g-#1}\relax
      \expandafter\if_false
   \else
      \expandafter\if_true
   \fi
}

%%%%%%%%%%%%%%% CONVERTING AN ETX FILE TO A VPL FILE %%%%%%%%%%%%%%%
%
% The macro:
%
%    \etxtovpl{ENCODING}{VPLFILE}
%
% writes a virtual font with the encoding ENCODING.

\def\etxtovpl#1#2{{
   \def\do_slot{\resetint\slot_name\slot_number}
   \inputetx{#1}
   \open_out{#2.vpl}
   \out_line{(VTITLE~virtual~font~#2~created~by~fontinst~v\fontinstversion)}
   \out_line{}
   \out_line{(COMMENT~Filename:~#2.vpl)}
   \out_line{(COMMENT~Created~by:~tex~\jobname)}
   \out_line{(COMMENT~Created~using:~\string\etxtovpl{#1}{#2})}
   \out_line{}
   \out_line{(COMMENT~This~file~can~be~turned~into~a~virtual~font~with)}
   \out_line{(COMMENT~vptovf~#2.vpl~#2.vf~#2.tfm)}
   \out_line{}
   \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
   \out_line{}
   \make_font{#1}
   \out_line{}
   \out_line{(COMMENT~END~OF~FILE~#2.vpl)}
   \close_out{Virtual~font}
}}

% \afmconvert\DIMEN=INTEGER EXPRESSION; 
% converts a count into a dimen, assuming the 
% count is a number of AFM units.  I'll assume that the largest dimension 
% I'll have to deal with is 131pt, to try to minimize rounding errors.

\newdimen\scaled_design_size

\def\afm_convert#1=#2;{
   \eval_expr{#2}
   #1=\scaled_design_size
   \divide#1 by 8
   \multiply #1 by \result
   \divide #1 by \one_thousand
   \multiply#1 by 8
}

% The commands \vpl_real\dimen or \vpl_int\count print a dimension or
% integer in (V)PL syntax.

\def\vpl_real#1{R~\expandafter\lose_measure\the#1}

\def\vpl_int#1{D~\the#1}

% \make_font{ENCODING} makes a VPL file.

\newdimen\side_bearings
\newcount\boundary_char

\def\make_font#1{
   \setdim{designsize}{10pt}
   \scaled_design_size=\dim{designsize}
   \out_line{(DESIGNSIZE~\vpl_real\scaled_design_size)}
   \out_line{(DESIGNUNITS~\vpl_real\scaled_design_size)}
   \setstr{codingscheme}{UNKNOWN}
   \out_line{(CODINGSCHEME~\str{codingscheme})}
   \ifisint{boundarychar}\then
      \boundary_char=\int{boundarychar}
      \out_line{(BOUNDARYCHAR~\vpl_int\boundary_char)}
   \else
      \boundary_char=-1
   \fi
   \setint{letterspacing}{0}
   \afm_convert\side_bearings=\div{\int{letterspacing}}{2};
   \ifdim\side_bearings=0pt
      \let\do_character=\do_character_no_letterspacing
   \fi
   \out_line{}
   \let\saved_scale\vpl_scale
   \let\saved_mapfont\vpl_mapfont
   \let\saved_raw\vpl_raw
   \let\saved_rule\vpl_rule
   \let\saved_special\vpl_special
   \let\saved_warning\vpl_warning
   \let\saved_movert\vpl_movert
   \let\saved_moveup\vpl_moveup
   \let\saved_push\vpl_push
   \let\saved_pop\vpl_pop
   \global\font_count=0
   \let\do_slot=\do_mapfont
   \inputetx{#1}
   \out_line{}
   \out_line{(FONTDIMEN}
      \ifisint{fontdimen(1)}\then
         \a_dimen=\int{fontdimen(1)}pt
         \divide\a_dimen by \one_thousand
         \out_lline{(PARAMETER~D~1~\vpl_real\a_dimen)}
      \fi
      \a_count=2
      \loop\ifnum\a_count<256
         {\ifisint{fontdimen(\the\a_count)}\then
            \afm_convert\a_dimen=\int{fontdimen(\the\a_count)};
            \out_lline{(PARAMETER~\vpl_int\a_count\space\vpl_real\a_dimen)}
         \fi}
      \advance\a_count by 1 \repeat
   \out_lline{)}
   \out_line{}
   \bgroup
      \out_line{(LIGTABLE}
      \let\do_slot=\relax
      \let\end_do_slot=\vpl_kerning
      \let\ligature=\vpl_ligature
      \let\k=\vpl_kern
      \inputetx{#1}
      \out_lline{)}
   \egroup
   \out_line{}
   \bgroup
      \let\do_slot=\do_character
      \let\end_do_slot=\end_do_character
      \let\nextlarger=\vpl_nextlarger
      \let\varchar=\vpl_varchar
      \let\endvarchar=\end_vpl_varchar
      \let\vartop=\vpl_vartop
      \let\varmid=\vpl_varmid
      \let\varbot=\vpl_varbot
      \let\varrep=\vpl_varrep
      \inputetx{#1}
   \egroup
   \a_count=0\loop\ifnum\a_count<\font_count
      \edef\temp_command{\csname~f-\the\a_count\endcsname}
      \global\x_cs\let\temp_command\relax
      \advance\a_count by 1
   \repeat
   \global\font_count=0
}

% \vpl_ligature{TYPE}{NAME}{NAME} produces a ligtable entry for glyph 
% \slot_name. 

\def\vpl_ligature#1#2#3{
   \ifisint{#2}\then 
      \ifisint{#3}\then
         \ifisglyph{#3}\then
            \a_count=\int{#2}
            \b_count=\int{#3}
            \vpl_liglabel
            \out_lline{(#1~\vpl_int\a_count\space \vpl_int\b_count)~
               (COMMENT~#2~#3)}
         \else
            \immediate\write16{Warning:~\string\ligature\space
               for~unknown~slot~`#3'.}
         \fi
      \else
         \immediate\write16{Warning:~\string\ligature\space
            for~unknown~slot~`#3'.}
      \fi
   \else
      \immediate\write16{Warning:~\string\ligature\space
         for~unknown~slot~`#2'.}
   \fi
}      

% \vpl_kerning writes out kerning instructions.

\def\vpl_kerning{\csname~r-\slot_name\endcsname\vpl_ligstop}

% \vpl_kern\l-NAME\AMOUNT writes out a kern instruction.

\def\vpl_kern#1#2{
   \edef\temp_command{\expandafter\gobble_three\string#1}
   \ifisint\temp_command\then
      \vpl_liglabel
      \a_count=\int\temp_command 
      \afm_convert\a_dimen=\expandafter\gobble_one\string#2;
      \out_lline{
         (KRN~\vpl_int\a_count\space \vpl_real\a_dimen)~
         (COMMENT~\temp_command)
      }
   \fi
}
   
% \vpl_liglabel writes out a LIGLABEL instruction if appropriate.

\def\out_liglabel{
   \out_lline{(LABEL~\vpl_int\slot_number)~(COMMENT~\slot_name)}
   \ifnum\slot_number=\boundary_char
      \out_lline{(LABEL~BOUNDARYCHAR)}
   \fi
   \let\vpl_liglabel=\relax
   \let\vpl_ligstop=\out_ligstop
}

\let\vpl_liglabel=\out_liglabel

% \vpl_ligstop writes out a LIGSTOP instruction if appropriate.

\def\out_ligstop{\out_lline{(STOP)}
   \let\vpl_liglabel=\out_liglabel
   \let\vpl_ligstop=\relax}

\let\vpl_ligstop=\relax

% \do_mapfont produces a MAPFONT entry for each font used by glyph 
% \slot_name. 

\def\do_mapfont{
   \ifisglyph\slot_name\then
      \mapfonts\slot_name
   \fi
}

% The following commands can be used in a mapfont:

\def\vpl_scale#1#2{{
   \divide \scaled_design_size by 8
   \multiply \scaled_design_size by #1
   \divide \scaled_design_size by \one_thousand
   \multiply \scaled_design_size by 8
   #2
}}

\def\vpl_mapfont#1#2{
   \a_dimen=#2
   \x_cs\ifx{#1-\the\scaled_design_size}\relax
      \x_cs\xdef{#1-\the\scaled_design_size}{\the\font_count}
      \x_cs\xdef{f-\the\font_count}{#1-\the\scaled_design_size}
      \out_line{(MAPFONT~\vpl_int\font_count\space
         (FONTNAME~#1)~
         (FONTDSIZE~\vpl_real\a_dimen)~
         (FONTAT~\vpl_real\scaled_design_size))}
      \global\advance\font_count by 1
   \fi
}

\newcount\font_count
\newcount\next_mapfont
\newcount\prev_mapfont

% \do_character produces a character entry for glyph \slot_name in slot 
% \slot_number.  First of all, the version with letterspacing:

\newdimen\curr_bearings

\def\do_character{
   \x_cs\ifx{g-\slot_name}\relax
      \expandafter\gobble_setslot
   \else
      \ifx\slot_name\notdef_name\else
         \out_line{(CHARACTER~\vpl_int\slot_number\space
            (COMMENT~\slot_name)}
         \ifisint{\slot_name-spacing}\then
            \afm_convert\curr_bearings=\int{\slot_name-spacing};
            \divide\curr_bearings by 2
         \else
            \curr_bearings=\side_bearings
         \fi
         \afm_convert\a_dimen=\width\slot_name;
         \advance\a_dimen by 2\curr_bearings
         \out_lline{(CHARWD~\vpl_real\a_dimen)}
         \afm_convert\a_dimen=\height\slot_name;
         \out_lline{(CHARHT~\vpl_real\a_dimen)}
         \afm_convert\a_dimen=\depth\slot_name;
         \out_lline{(CHARDP~\vpl_real\a_dimen)}
         \afm_convert\a_dimen=\italic\slot_name;
         \ifnum\a_dimen>0 \out_lline{(CHARIC~\vpl_real\a_dimen)} \fi
         \global\prev_mapfont=0 \out_lline{(MAP} 
            \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
            \mapcommands\slot_name 
            \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
         \out_llline{)} 
      \fi
   \fi
}

% Now the version without:

\def\do_character_no_letterspacing{
   \x_cs\ifx{g-\slot_name}\relax
      \expandafter\gobble_setslot
   \else
      \ifx\slot_name\notdef_name\else
         \out_line{(CHARACTER~\vpl_int\slot_number\space
            (COMMENT~\slot_name)}
         \afm_convert\a_dimen=\width\slot_name;
         \out_lline{(CHARWD~\vpl_real\a_dimen)}
         \afm_convert\a_dimen=\height\slot_name;
         \out_lline{(CHARHT~\vpl_real\a_dimen)}
         \afm_convert\a_dimen=\depth\slot_name;
         \out_lline{(CHARDP~\vpl_real\a_dimen)}
         \afm_convert\a_dimen=\italic\slot_name;
         \ifnum\a_dimen>0 \out_lline{(CHARIC~\vpl_real\a_dimen)} \fi
         \global\prev_mapfont=0 \out_lline{(MAP} 
            \mapcommands\slot_name 
         \out_llline{)} 
      \fi
   \fi
}

% Gobble a set_slot

\def\gobble_setslot#1\endsetslot{\endsetslot}

\def\end_do_character{
   \ifisglyph\slot_name\then
      \out_lline{)}
   \fi
}

\def\notdef_name{.notdef}

% \vpl_nextlarger{NAME} produces a NEXTLARGER entry.

\def\vpl_nextlarger#1{
   \ifisint{#1}\then
      \out_lline{(NEXTLARGER~D~\the\int{#1})~(COMMENT~#1)}
   \else
      \immediate\write16{Warning:~\string\nextlarger\space
         for~unknown~slot~`#1'}
   \fi
}

% \vpl_varchar VARCHAR COMMANDS \end_vpl_varchar produces a VARCHAR entry.

\def\vpl_varchar{\out_lline{(VARCHAR}}

\def\vpl_vartop#1{
   \ifisint{#1}\then
      \out_llline{(TOP~D~\the\int{#1})~(COMMENT~#1)}
   \else
      \immediate\write16{Warning:~\string\vartop\space
         for~unknown~slot~`#1'}
   \fi
}

\def\vpl_vartop#1{
   \ifisint{#1}\then
      \out_llline{(TOP~D~\the\int{#1})~(COMMENT~#1)}
   \else
      \immediate\write16{Warning:~\string\vartop\space
         for~unknown~slot~`#1'}
   \fi
}
\def\vpl_varmid#1{
   \ifisint{#1}\then
      \out_llline{(MID~D~\the\int{#1})~(COMMENT~#1)}
   \else
      \immediate\write16{Warning:~\string\varmid\space
         for~unknown~slot~`#1'}
   \fi
}

\def\vpl_varbot#1{
   \ifisint{#1}\then
      \out_llline{(BOT~D~\the\int{#1})~(COMMENT~#1)}
   \else
      \immediate\write16{Warning:~\string\varbot\space
         for~unknown~slot~`#1'}
   \fi
}

\def\vpl_varrep#1{
   \ifisint{#1}\then
      \out_llline{(REP~D~\the\int{#1})~(COMMENT~#1)}
   \else
      \immediate\write16{Warning:~\string\varrep\space
         for~unknown~slot~`#1'}
   \fi
}

\def\end_vpl_varchar{\out_llline{)}}

% The following commands can be used in a glyph:

\def\vpl_raw#1#2#3{
   \global\next_mapfont=\csname~#1-\the\scaled_design_size\endcsname\relax
   \ifnum\next_mapfont=\prev_mapfont\else
      \out_llline{(SELECTFONT~\vpl_int\next_mapfont)~
         (COMMENT~#1~at~\the\scaled_design_size)}
   \fi
   \out_llline{(SETCHAR~D~#2)~(COMMENT~#3)}
   \global\prev_mapfont=\next_mapfont
}

\def\vpl_rule#1#2{
   \afm_convert\a_dimen=#1;
   \afm_convert\b_dimen=#2;
   \out_llline{(SETRULE~\vpl_real\b_dimen\space~\vpl_real\a_dimen)}
}

\def\vpl_special#1{\out_llline{(SPECIAL~#1)}}

\def\vpl_warning#1{
   \out_llline{(SPECIAL~Warning:~#1)}
   \immediate\write16{Warning:~#1.}
}

\def\vpl_movert#1{
   \afm_convert\a_dimen=#1;
   \out_llline{(MOVERIGHT~\vpl_real\a_dimen)}
}

\def\vpl_moveup#1{
   \afm_convert\a_dimen=#1;
   \out_llline{(MOVEUP~\vpl_real\a_dimen)}
}

\def\vpl_push{\out_llline{(PUSH)}}

\def\vpl_pop{\out_llline{(POP)}}

%%%%%%%%%%%%%%% CONVERTING AN MTX FILE TO A PL FILE %%%%%%%%%%%%%%%
%
% The macro:
%
%    \mtxtopl{MTXFILE}{PLFILE}
%
% writes a font from the \rawglyph instructions in PLFILE.  It ignores 
% any font dimensions and kerning, so the resulting font is only useful 
% for generating virtual fonts from.

\def\mtxtopl#1#2{{
   \open_out{#2.pl}
   \out_line{(COMMENT~raw~font~#2~created~by~fontinst~v\fontinstversion)}
   \out_line{}
   \out_line{(COMMENT~Filename:~#2.pl)}
   \out_line{(COMMENT~Created~by:~tex~\jobname)}
   \out_line{(COMMENT~Created~using:~\string\mtxtopl{#1}{#2})}
   \out_line{}
   \out_line{(COMMENT~This~file~can~be~turned~into~a~TeX~font~with)}
   \out_line{(COMMENT~pltotfm~#2.pl~#2.tfm)}
   \out_line{}
   \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
   \out_line{}
   \out_line{(DESIGNSIZE~R~10.0)}
   \out_line{(DESIGNUNITS~R~10.0)}
   \out_line{}
   \scaled_design_size=10pt
   \let\setglyph=\iffalse
   \let\endsetglyph=\fi
   \let\setkern=\gobble_three
   \let\setrawglyph=\pl_raw_glyph
   \inputmtx{#1}
   \out_line{}
   \out_line{(COMMENT~END~OF~FILE~#2.pl)}
   \close_out{Raw~font}
}}

\def\pl_raw_glyph#1#2#3#4#5#6#7#8{
   \a_count=#4
   \afm_convert\a_dimen=#5;
   \afm_convert\b_dimen=#6;
   \afm_convert\c_dimen=#7;
   \afm_convert\d_dimen=#8;
   \out_line{(CHARACTER~\vpl_int\a_count\space(COMMENT~#1)}
   \out_lline{(CHARWD~\vpl_real\a_dimen)}
   \out_lline{(CHARHT~\vpl_real\b_dimen)}
   \out_lline{(CHARDP~\vpl_real\c_dimen)}
   \out_lline{(CHARIC~\vpl_real\d_dimen)}
   \out_lline{)}
}

%%%%%%%%%%%%%%% WRAPPING IT UP %%%%%%%%%%%%%%%
%
% The macro:
%
%    \installfonts INSTALL COMMANDS \endinstallfonts
%
% is the top-level interface for installing a number of fonts and 
% creating FD files for them.
%
% The INSTALL COMMANDS are:  
%
%    \installfamily{ENCODING}{FAMILY}{FD-COMMANDS}
%    \installfont{FONT-NAME}{FILE-LIST}{ETX}
%       {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE}

\def\declareencoding#1#2{\x_cs\edef{enc-#1}{#2}}

\declareencoding{EXTENDED~TEX~FONT~ENCODING~-~LATIN}{T1}
\declareencoding{TEX~TEXT}{OT1}
\declareencoding{TEX~TYPEWRITER~TEXT}{OT1tt}
\declareencoding{TEX~MATH~ITALIC}{OML}
\declareencoding{TEX~MATH~SYMBOLS}{OMS}
\declareencoding{TEX~MATH~EXTENSION}{OMX}

\def\declaresize#1#2{\x_cs\edef{siz-#1}{#2}}

\declaresize{}{<->}
\declaresize{5}{<5>}
\declaresize{6}{<6>}
\declaresize{7}{<7>}
\declaresize{8}{<8>}
\declaresize{9}{<9>}
\declaresize{10}{<10>}
\declaresize{11}{<10.95>}
\declaresize{12}{<12>}
\declaresize{14}{<14.4>}
\declaresize{17}{<17.28>}
\declaresize{20}{<20.74>}
\declaresize{25}{<24.88>}

\def\installfonts{
   \bgroup
   \global\family_toks={}
   \gdef\prev_file_list{}
}

\newtoks\family_toks

\def\installfamily#1#2#3{
   \global\family_toks=\expandafter{\the\family_toks\fd_family{#1}{#2}{#3}}
   \global\x_cs\let{#1-#2}\empty_command
}

%    \installfont{FONT-NAME}{FILE-LIST}{ETX}
%       {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE}

\def\installfont#1#2#3#4#5#6#7#8{
   \xdef\curr_file_list{#2}
   \ifx\prev_file_list\curr_file_list\else
      \egroup\bgroup
      \expandafter\input_mtx_files\curr_file_list,
         \relax,\end_input_mtx_files
      \global\let\prev_file_list=\curr_file_list
   \fi
   \etxtovpl{#3}{#1}
   \x_cs\ifx{#4-#5-#6-#7}\relax
      \let\do_shape=\relax
      \x_cs\xdef{#4-#5}{
         \x_cs\ifx{#4-#5}\relax\else
            \csname#4-#5\endcsname
         \fi
         \do_shape{#4}{#5}{#6}{#7}
      }
   \fi
   \let\do_size=\relax
   \x_cs\xdef{#4-#5-#6-#7}{
      \x_cs\ifx{#4-#5-#6-#7}\relax\else
         \csname#4-#5-#6-#7\endcsname
      \fi
      \do_size{#8}{#1}
   }
}

\def\endinstallfonts{
   \let\do_shape=\fd_shape
   \let\do_size=\fd_size
   \the\family_toks
   \global\family_toks{}
   \egroup
}

%    \input_mtx_files{FILE-LIST}

\def\input_mtx_files#1,#2\end_input_mtx_files{
   \if\relax#1
      \expandafter\gobble_one
   \else
      \expandafter\identity_one
   \fi{
      \input_mtx_file{#1}
      \input_mtx_files#2\end_input_mtx_files
   }
}

%    \input_mtx_file{FILE}

\def\input_mtx_file#1{
   \if\relax#1\relax\else
      \get_file_name #1~scaled~1000~;
      \if_file_exists{\file_name.mtx}\then
         \inputmtx\file_name
      \else
         \if_file_exists{\file_name.afm}\then
            \afmtomtx\file_name\file_name
            \mtxtopl\file_name\file_name
         \else
            \if_file_exists{\file_name.pl}\then
               \pltomtx\file_name\file_name
            \fi
         \fi
         \inputmtx\file_name
      \fi
   \fi
}

%    \get_file_name FILENAME scaled SCALE JUNK ;

\def\get_file_name #1~scaled~#2~#3;{
   \edef\file_name{#1}
   \ifnum#2=\one_thousand
      \unsetint{rawscale}
   \else
      \setint{rawscale}{#2}
   \fi
}

%    \fd_family{ENCODING}{FAMILY}{FD-COMMANDS}

\def\fd_family#1#2#3{
   \a_toks{#3}
   \open_out{#1#2.fd}
   \out_line{\percent_char~Filename:~#1#2.fd}
   \out_line{\percent_char~Created~by:~tex~\jobname}
   \out_line{\percent_char~Created~using~fontinst~v\fontinstversion}
   \out_line{}
   \out_line{\percent_char~THIS~FILE~SHOULD~BE~PUT~IN~A~TEX~INPUTS~DIRECTORY}
   \out_line{}
   \out_line{\string\ProvidesFile{#1#2.fd}}
   \out_lline{[
      \the\year/
      \ifnum10>\month0\fi\the\month/
      \ifnum10>\day0\fi\the\day\space
      Fontinst~v\fontinstversion\space
      font~definitions~for~#1/#2.
   ]}
   \out_line{}
   \out_line{\string\DeclareFontFamily{#1}{#2}{\the\a_toks}}
   {
      \csname #1-#2\endcsname
      \out_line{}
      \let\do_shape=\substitute_shape
      \csname #1-#2\endcsname
      \let\do_shape=\remove_shape
      \csname #1-#2\endcsname
   }
   \x_cs\g_let{#1-#2}\relax
   \out_line{}
   \out_line{\string\endinput}
   \close_out{Font~definitions}
}

%    \substitute_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}

\def\substitute_shape#1#2#3#4{
   \edef\orig_shape{#4}
   \substitute_series{#1}{#2}{#3}{\orig_shape}
   \x_cs\ifx{sub-\orig_shape}\relax\else
      \edef\subst_shape{\csname sub-\orig_shape\endcsname}
      \x_cs\ifx{#1-#2-#3-\subst_shape}\relax
         \out_line{
            \string\DeclareFontShape{#1}{#2}{#3}{\subst_shape}{
               <->\csname typ-\orig_shape\endcsname\space *~#2/#3/\orig_shape
            }{}
         }
         \x_cs\let{#1-#2-#3-\subst_shape}\empty_command
         \substitute_shape{#1}{#2}{#3}{\subst_shape}
      \fi
   \fi
}

%    \substitute_series{ENCODING}{FAMILY}{SERIES}{SHAPE}

\def\substitute_series#1#2#3#4{
   \edef\orig_series{#3}
   \x_cs\ifx{sub-\orig_series}\relax\else
      \edef\subst_series{\csname sub-\orig_series\endcsname}
      \x_cs\ifx{#1-#2-\subst_series-#4}\relax
         \out_line{
            \string\DeclareFontShape{#1}{#2}{\subst_series}{#4}{
               <->\csname typ-\orig_series\endcsname\space *~#2/\orig_series/#4
            }{}
         }
         \x_cs\let{#1-#2-\subst_series-#4}\empty_command
         \substitute_series{#1}{#2}{\subst_series}{#4}
      \fi
   \fi
}

%    \substitutesilent{FROM}{TO}
%    \substitutenoisy{FROM}{TO}

\def\substitutesilent#1#2{
   \x_cs\def{sub-#2}{#1}
   \x_cs\def{typ-#2}{ssub}
}

\def\substitutenoisy#1#2{
   \x_cs\def{sub-#2}{#1}
   \x_cs\def{typ-#2}{sub}
}

% Default substitutions.

\substitutenoisy{ui}{it}
\substitutesilent{bx}{b}
\substitutesilent{b}{bx}
\substitutesilent{b}{sb}
\substitutesilent{b}{db}
\substitutesilent{m}{l}
\substitutesilent{sc}{nc}

%    \remove_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}

\def\remove_shape#1#2#3#4{
   \x_cs\g_let{#1-#2-#3-#4}\relax
}

%    \fd_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}

\def\fd_shape#1#2#3#4{
   \out_line{}
   \out_line{\string\DeclareFontShape{#1}{#2}{#3}{#4}\left_brace_char}
   \csname #1-#2-#3-#4\endcsname
   \x_cs\g_let{#1-#2-#3-#4}\empty_command
   \out_line{\right_brace_char{}}
}

%    \fd_size{SIZE}{FONT-NAME}

\def\fd_size#1#2{
   \x_cs\ifx{siz-#1}\relax
      \out_lline{#1~#2}
   \else
      \out_lline{\csname siz-#1\endcsname\space #2}
   \fi
}

%%%%%%%%%%%%%%% FONT TRANSFORMS %%%%%%%%%%%%%%%
%
% The macro:
% 
%    \transformfont{FONT-NAME}{TRANSFORMED FONT}
%
% transforms a raw font.  The TRANSFORMED FONT commands are:
%
%    \fromafm{AFM}
%    \scalefont{INTEGER EXPRESSION}{TRANSFORMED FONT}
%    \xscalefont{INTEGER EXPRESSION}{TRANSFORMED FONT}
%    \yscalefont{INTEGER EXPRESSION}{TRANSFORMED FONT}
%    \slantfont{INTEGER EXPRESSION}{TRANSFORMED FONT}
%    \reencodefont{ETX}{TRANSFORMED FONT}
%

\def\transformfont#1#2{{
   \unsetstr{afm-name}
   \unsetstr{etx-name}
   \resetint{x-scale}{\one_thousand}
   \resetint{y-scale}{\one_thousand}
   \resetint{slant-scale}{0}
   #2
   \mtxtomtx{\str{afm-name}}{#1}
   \mtxtopl{#1}{#1} 
}}

\def\fromafm#1{
   \setstr{afm-name}{#1}
   \afmtomtx{#1}{#1}
   \mtxtopl{#1}{#1}
}

\def\frommtx{
   \setstr{afm-name}
}

\def\frompl#1{
   \setstr{afm-name}{#1}
   \pltomtx{#1}{#1}
}

\def\scalefont#1#2{
   \resetint{x-scale}{#1}
   \resetint{y-scale}{\int{x-scale}}
   #2
}

\def\xscalefont#1#2{
   \resetint{x-scale}{#1}
   #2
}

\def\yscalefont#1#2{
   \resetint{y-scale}{#1}
   #2
}

\def\slantfont#1#2{
   \resetint{slant-scale}{#1}
   #2
}

\def\reencodefont#1#2{
   \resetstr{etx-name}{#1}
   #2
}

% The macro:
%
%    \mtxtomtx{MTX}{MTX}
%
% Converts the first MTX file to the second, using the current values of 
% \int{x-scale}, \int{y-scale}, \int{slant-scale} and \str{etx-name}.
% NOTE: this doesn't convert arbitrary MTX files, just ones created with 
% \afmtomtx.

\def\mtxtomtx#1#2{{
   \ifisstr{etx-name}\then
      \def\do_slot{\resetint\slot_name\slot_number}
      \inputetx{\str{etx-name}}
   \fi
   \open_out{\temp_prefix#2.mtx}
   \def\raw_font_name{#2}
   \out_line{\percent_char~Filename:~#2.mtx}
   \out_line{\percent_char~Created~by:~tex~\jobname}
   \out_line{\percent_char~Created~using:~\string\mtxtomtx{#1}{#2}}
   \out_line{}
   \out_line{\percent_char~This~file~is~used~by~the~fontinst~package.}
   \out_line{}
   \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
   \out_line{}
   \out_line{\string\relax}
   \out_line{\string\metrics}
   \out_line{}
   \out_line{\string\needsfontinstversion{\fontinstversion}}
   \out_line{}
   \let\setint=\mtxtomtx_setint
   \let\setrawglyph=\mtxtomtx_setrawglyph
   \let\setnotglyph=\mtxtomtx_setrawglyph
   \let\setkern=\mtxtomtx_setkern
   \let\setglyph=\mtxtomtx_setglyph
   \let\glyphpcc=\mtxtomtx_glyphpcc
   \let\samesize=\mtxtomtx_samesize
   \let\endsetglyph=\mtxtomtx_endsetglyph
   \inputmtx{#1}
   \out_line{}
   \out_line{\string\endmetrics}
   \close_out{Transformed~metrics}
}}

\def\mtxtomtx_setint#1#2{
   \def\temp_command{#1}
   \ifx\temp_command\italicslant_name
      \eval_expr_to\a_count{
         \add{\int{slant-scale}}{
            \div{\mul{\int{x-scale}}{#2}}{\int{y-scale}}
         }
      }
   \else
      \eval_expr_to\a_count{\scale{#2}{\int{y-scale}}}
   \fi
   \out_line{\string\setint{#1}{\the\a_count}}
}

\def\italicslant_name{italicslant}

\def\mtxtomtx_setrawglyph#1#2#3#4#5#6#7#8{
   \eval_expr_to\a_count{\scale{#5}{\int{x-scale}}}
   \eval_expr_to\b_count{\scale{#6}{\int{y-scale}}}
   \eval_expr_to\c_count{\scale{#7}{\int{y-scale}}}
   \eval_expr_to\d_count{
      \add{
         \scale{#8}{\int{x-scale}}
      }{
         \scale\b_count{\int{slant-scale}}
      }
   }
   \ifisstr{etx-name}\then
      \ifisint{#1}\then
         \e_count=\int{#1}
      \else
         \e_count=-1
      \fi
   \else
      \e_count=#4
   \fi
   \out_line{
      \ifnum\e_count>-1
         \string\setrawglyph
      \else
         \string\setnotglyph
      \fi
         {#1}{\raw_font_name}{#3}{\the\e_count}
         {\the\a_count}{\the\b_count}{\the\c_count}{\the\d_count}
   }
}

\def\mtxtomtx_setkern#1#2#3{
   \eval_expr{\scale{\int{x-scale}}{#3}}
   \out_line{\string\setkern{#1}{#2}{\the\result}}
}

\def\mtxtomtx_setglyph#1{\out_line{\string\setglyph{#1}}}
\def\mtxtomtx_samesize#1{\out_lline{\string\samesize{#1}}}
\def\mtxtomtx_endsetglyph{\out_line{\string\endsetglyph}}
\def\mtxtomtx_glyphpcc#1#2#3{
   \eval_expr_to\b_count{\scale{\int{y-scale}}{#3}}
   \eval_expr_to\a_count{
      \add{\scale{\int{x-scale}}{#2}}{\scale\b_count{\int{slant-scale}}}
   }
   \out_lline{\string\glyphpcc{#1}{\the\a_count}{\the\b_count}}
}


%%%%%%%%%%%%%%% LATIN FAMILIES %%%%%%%%%%%%%%%
%
% The macro:
%
%    \latinfamily{FAMILY}{COMMANDS}
%
% installs a Latin font family.
 
% \latinfamily{FAMILY}{COMMANDS}
 
\def\latinfamily#1#2{
   \edef\temp_command{#1}
   \expandafter\parse_family\temp_command
      \empty_command\empty_command\end_parse_family
   \installfonts
      \installfamily{T1}{#1}{#2}
      \installfamily{OT1}{#1}{#2}
      \install_latin_series{b}{}{b}
      \install_latin_series{b}{n}{bc}
      \install_latin_series{d}{}{db}
      \install_latin_series{i}{}{xl}
      \install_latin_series{l}{}{l}
      \install_latin_series{s}{}{sb}
      \install_latin_series{k}{}{m}
      \install_latin_series{m}{}{m}
      \install_latin_series{r}{}{m}
      \install_latin_series{r}{n}{mc}
      \install_latin_series{x}{}{xb}
   \endinstallfonts
}   

% \parse_family FAMILY \end_parse_family

\def\parse_family#1#2#3#4#5\end_parse_family{
   \edef\family_LaTeX_name{#1#2#3#4#5}
   \edef\font_name_virtual##1##2{#1#2#3##1#4#5##2}
   \ifx#4x
      \_expert_true
      \def\encoding_name##1{##1}
      \edef\font_name_raw##1##2{#1#2#3##1#5##2}
   \else\ifx#49
      \_expert_true
      \def\encoding_name##1{##19}
      \edef\font_name_raw##1##2{#1#2#3##1#5##2}
   \else
      \_expert_false
      \def\encoding_name##1{##1}
      \edef\font_name_raw##1##2{#1#2#3##1#4#5##2}
   \fi\fi
}

\newif\if_expert_

% \install_latin_series{WEIGHT}{EXPANSION}{SERIES}

\def\install_latin_series#1#2#3{
   \install_slanted_font{#1}{}{0#2}
   \install_slanted_font{#1}{x}{#2}
   \install_latin_shape{#1}{#3}{n}{}{}{#2}
   \install_latin_shape{#1}{#3}{sc}{c}{c}{#2}
   \install_latin_shape{#1o}{#3}{sl}{}{}{#2}
   \if_file_exists{\font_name_raw{#1i}{0#3}.afm}\then
      \install_latin_shape{#1i}{#3}{it}{i}{}{#2}
   \else 
      \if_file_exists{\font_name_raw{#1o}{0#3}.afm}\then
         \install_latin_shape{#1o}{#3}{it}{i}{}{#2}
      \else
         \install_latin_shape{#1i}{#3}{it}{i}{}{#2}
      \fi
   \fi
}

% \install_slanted_font{WEIGHT}{VARIANT}{ENCODINGEXPANSION}

\def\install_slanted_font#1#2#3{
   \if_file_exists{\font_name_raw{#1o#2}{#3}.afm}\then\else
      \if_file_exists{\font_name_raw{#1#2}{#3}.afm}\then
         \immediate\write16{
            Faking~oblique~font~\font_name_raw{#1o#2}{#3}~from~
            \font_name_raw{#1#2}{#3}.
         }
         \transformfont{\font_name_raw{#1o#2}{#3}}{
            \slantfont{167}{\fromafm{\font_name_raw{#1#2}{#3}}}
         }
      \fi
   \fi
}

% \install_latin_shape{VARIANT}{SERIES}{SHAPE}{OT1SUFFIX}{T1SUFFIX}{EXPANSION}
 
\def\install_latin_shape#1#2#3#4#5#6{
   \if_or
      \if_file_exists{\font_name_raw{#1}{0#6}.afm}
   \or_else
      \if_file_exists{\font_name_raw{#1}{0#6}.mtx}
   \then
      \global\let\expert_font=\empty_command
      \if_expert_
         \if_or
            \if_file_exists{\font_name_raw{#1}{x#6}.afm}
         \or_else
            \if_file_exists{\font_name_raw{#1}{x#6}.mtx}
         \then
            \xdef\expert_font{,\font_name_raw{#1}{x#6}}
         \fi
      \fi
      \immediate\write16{Installing~\family_LaTeX_name/#2/#3.}
      \installfont{\font_name_virtual{#1}{#5q#6}}
         {\font_name_raw{#1}{0#6}\expert_font,latin}
         {\encoding_name{T1#5}}{T1}{\family_LaTeX_name}{#2}{#3}{}
      \installfont{\font_name_virtual{#1}{#57t#6}}
         {\font_name_raw{#1}{0#6}\expert_font,latin}
         {\encoding_name{OT1#4}}{OT1}{\family_LaTeX_name}{#2}{#3}{}
   \else
      \immediate\write16{
         No~file~\font_name_raw{#1}{0#6}.afm,~
         so~not~installing~\family_LaTeX_name/#2/#3.
      }
   \fi
}

%%%%%%%%%%%%%%% VERSION NUMBERS %%%%%%%%%%%%%%%
%
% The macro:
%
%    \needsfontinstversion{NUMBER} 
%
% checks the version number.

\def\needsfontinstversion#1{{
   \a_dimen=#1pt
   \b_dimen=\fontinstversion~pt\relax
   \ifnum\a_dimen>\b_dimen
      \immediate\write16{}
      \immediate\write16{Warning:~This~file~needs~fontinst~version~#1.}
      \immediate\write16{Warning:~You~are~using~version~\fontinstversion.}
      \immediate\write16{Warning:~This~may~cause~errors.}
      \immediate\write16{}
   \fi
}}

% The directory for temporary files.

\def\tempfileprefix#1{\def\temp_prefix{#1}}

\tempfileprefix{}
   
%%%%%%%%%%%%%%% EXIT %%%%%%%%%%%%%%%
%
% If \bye hasn't been defined, define it (for LaTeX).

\ifx\bye\undefined_command
   \outer\x_cs\def{bye}{\par\vfill\supereject\@@end}
\fi

%%%%%%%%%%%%%%% RESTORE CATCODES %%%%%%%%%%%%%%%
%
% Restore the catcodes we changed.

\catcode`\@=\atcatcode
\catcode`\^^M=\nlcatcode
\catcode`\ =\spacecatcode
\catcode`\~=\tildecatcode

%%%%%%%%%%%%%%% RC FILE %%%%%%%%%%%%%%%
%
% We input the fontinst.rc file, if it exists. 

\if_file_exists{fontinst.rc}\then
   \catcode`\_=\underscorecatcode
   \primitiveinput fontinst.rc
\else
   \catcode`\_=\underscorecatcode
   \immediate\write16{No file fontinst.rc.}
\fi

%%%%%%%%%%%%%%% THE END %%%%%%%%%%%%%%%

\endinput

