% \CheckSum{4056}
% \iffalse meta-comment
%
% Copyright 1993, 1994, 1995, 1996 Alan Jeffrey,
% hacked and maintained 1997, 1998 Sebastian Rahtz,
% copyright 1998, 1999, 2000 the fontinst maintenance team and any
% individual authors listed elsewhere in this file. All rights reserved.
%
% This file is part of the fontinst system version 1.9.
% -----------------------------------------------------
%
% It may be distributed under the terms of the LaTeX Project Public
% License, as described in lppl.txt in the base LaTeX distribution.
% Either version 1.1 or, at your option, any later version.
%
%%% From file: fimain.dtx
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{fisource}
\title{The \package{fontinst} utility}
\author{Alan Jeffrey, Sebastian Rahtz, Ulrik Vieth, Lars Hellstr\"om}
\begin{document}
\maketitle
\tableofcontents
\DocInput{fimain.dtx}
\end{document}
%
% \fi
%
% \StopEventually{}
%
%
% \section{Encoding files}
%
% \changes{1.911}{1999/11/21}{Definitions of encoding file commands
% added to \protect\protect\protect\Module{misc}. (LH)}
%
% \DescribeMacro{\inputetx}
% The macro
% \begin{quote}
% |\inputetx|\marg{filename}
% \end{quote}
% inputs \meta{filename}|.etx|, ignoring anything between |\relax|
% and |\encoding|, and anything after |\endencoding|.
%
% The file name is transformed to lowercase before opening.
%
% \begin{macro}{\inputetx}
% \begin{macro}{\encoding}
% \changes{1.900}{1999/02/07}
% {Changed group in fontdoc to \cs{begingroup} type. (LH)}
% \usechange{raggedright}
% \begin{macro}{\endencoding}
% \changes{1.900}{1999/02/07}{Made it outer. (LH)}
% \usechange{raggedright}
% \begin{macrocode}
%<*pkg|misc>
\def\inputetx#1{
\edef\lowercase_file{\lowercase{
\edef\noexpand\lowercase_file{#1}}}
\lowercase_file
\slot_number=0
\def\relax{\let\relax=\x_relax\iffalse}
\let\encoding=\fi
\primitiveinput \lowercase_file.etx\x_relax
\let\relax=\x_relax
}
\let\encoding=\relax
\outer\def\endencoding{\endinput}
%
% \end{macrocode}
%
% Things are a bit more complicated in \package{fontdoc}, since the
% |\relax| \textellipsis\ |\encoding| \textellipsis\ |\endencoding|
% markup must be able to work in two different ways. In the main file
% only |\encoding| actually does anything---it sets |\slot@number| to
% zero. In a file that is being |\inputetx|ed, they must work as with
% \package{fontinst}: Everything between |\relax| and |\encoding|,
% and everything after |\endencoding| must be ignored.
% \multchanges{\cs{inputetx}\cs{inputmtx}}{1.914}{2000/05/27}
% {New \package{fontdoc} definition, using \cs{IfFileExists}. (LH)}
% \multchanges{\cs{encoding}\cs{endencoding}}{1.918}{2001/06/19}
% {Added \cs{par} and \cs{addvspace} to \package{fontdoc}
% definitions. (LH)}
% \multchanges{\cs{endencoding}}{1.919}{2001/09/01}
% {Added setting of \cs{parindent} to 1\,em to \package{fontdoc}
% definition. (LH)}
% \begin{macrocode}
%<*doc>
\def\inputetx#1{%
\begingroup
\edef\lowercase@file{\lowercase{%
\edef\noexpand\lowercase@file{#1}%
}}%
\lowercase@file
\global\slot@number=0%
\FD@slot@known@true
\IfFileExists{\lowercase@file.etx}{%
\FD@relax@encoding@tricks
\@@input \@filef@und
\let\relax=\x@relax
}{%
\PackageError{fontdoc}{File #1.etx not found}%
{\@eha\MessageBreak You can \protect\inputetx\space
some other file now, if you want.}%
}
\endgroup
}
% \end{macrocode}
% \begin{macro}{\FD@relax@encoding@tricks}
% There is a problem with |\if| \dots\ |\fi| nesting in the
% redefinition of |\relax| and |\encoding|, which interacts badly
% with |\IfFileExists|. To work around that, these redefinitions
% are hidden in the |\FD@relax@encoding@tricks| macro.
% \changes{1.928}{2004/11/24}{Macro added, to fix bug reported by
% Peter Dyballa. (LH)}
% \begin{macrocode}
\def\FD@relax@encoding@tricks{%
\def\relax{\let\relax=\x@relax\iffalse}%
\let\encoding=\fi
\outer\x@cs\def{endencoding}{\endinput}%
}
% \end{macrocode}
% \end{macro}
% \begin{macrocode}
\def\encoding{%
\par
\ifFD@spec@ \addvspace{\bigskipamount}\fi
\begin{flushleft}
\global\slot@number=\z@
}
\outer\def\endencoding{%
\end{flushleft}
\ifFD@spec@ \addvspace{\bigskipamount}\fi
}
%
% \end{macrocode}
% \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\setslot}
% \changes{1.917}{2001/03/23}{Made slots referencable using
% \cs{label}. (LH)}
% \begin{macro}{\endsetslot}
% \begin{macro}{\slot_name}
% |\setslot|\marg{name} \meta{slot commands} |\endsetslot|
%
% In \package{fontinst}, this sets |\slot_name| to \meta{name} and
% calls |\do_slot| at the beginning of the slot and it calls
% |\end_do_slot| and increments |\slot_number| by one at the end.
% By default, |\do_slot| and |\end_do_slot| do nothing, but this is
% over-ridden later.
%
% \begin{macrocode}
%<*pkg|misc>
\def\setslot#1{\edef\slot_name{#1}\do_slot}
\def\endsetslot{\end_do_slot\advance\slot_number by 1\x_relax}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\slot@name}
% \changes{1.917}{2001/03/23}{Now storing the printable form of the
% name, rather than the raw code. (LH)}
% In \package{fontdoc}, the same code converts \meta{name} to a
% printable string and stores the result in |\slot@name|, prints an
% |\Aheading| heading for the slot which show the name and number
% of the slot, and prints the current automatic slot comment (if
% one has been set) at the beginning of the slot. At the end of
% the slot, it simply increments |\slot@number| by one.
%
% \begin{macrocode}
%<*doc>
\newcommand\setslot[1]{%
\protected@edef\slot@name{%
\noexpand\MakePrintable \noexpand\slot@name {FD@swa}{#1}%
}%
\slot@name
\FD@tight@true
\Aheading{Slot
\ifFD@slot@known@
\the\slot@number\space
\else
\(\FD@slot@expression + \the\slot@number\)
\fi
`\FD@typeset@string{\slot@name}'%
}%
\protected@edef\@currentlabel{%
\ifFD@slot@known@
\the\slot@number
\else
\protect\(%
\FD@slot@expression+\the\slot@number
\protect\)%
\fi
\space(\protect\FD@typeset@string{\slot@name})%
}%
\ifFD@slot@known@ \ifslot@comment@ \comment{\slot@comment}\fi\fi
}
\def\endsetslot{%
\global\advance \slot@number \@ne
\FD@tight@false
}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\do_slot}
% \begin{macro}{\end_do_slot}
% \begin{macrocode}
%<*pkg|misc>
\let\do_slot\empty_command
\let\end_do_slot\empty_command
% \end{macrocode}
% \end{macro} \end{macro}
% \multchanges{\cs{do_new_slot}}{1.910}{1999/11/01}{Macro removed. (LH)}
%
% \begin{macro}{\nextslot}
% \begin{macro}{\skipslots}
% \begin{macro}{\slot_number}
% \begin{macro}{\slot@number}
% \begin{switch}{FD@slot@known@}
% \begin{macro}{\FD@slot@expression}
% |\nextslot|\marg{integer expression}\\
% |\skipslots|\marg{integer expression}
%
% In \package{fontinst}, |\nextslot| sets the |\slot_number| and
% |\skipslots| addvances the |\slot_number|.
%
% \begin{macrocode}
\newcount\slot_number
\def\nextslot#1{\eval_expr_to\slot_number{#1}}
\def\skipslots#1{\eval_expr{#1} \advance\slot_number by \result}
%
% \end{macrocode}
%
% The commands do the same in \package{fontdoc} as in
% \package{fontinst}, although they do it to |\slot@number| instead of
% |\slot_number|.
%
% \begin{macrocode}
%<*doc>
\newcount\slot@number
\def\FD@slot@known@true{\global\let\ifFD@slot@known@\iftrue}
\def\FD@slot@known@false{\global\let\ifFD@slot@known@\iffalse}
\FD@slot@known@true
\newcommand\nextslot[1]{%
\FD@evaluate@true
\FD@eval@expr{#1}%
\ifFD@evaluate@
\global\slot@number=\FD@result
\FD@slot@known@true
\else
\global\let\FD@slot@expression=\FD@expression
\global\slot@number=\z@
\FD@slot@known@false
\fi
}
\newcommand\skipslots[1]{%
\FD@evaluate@true
\FD@eval@expr{#1}%
\ifFD@evaluate@
\global\advance \slot@number \FD@result
\else
\ifFD@slot@known@
\global\let\FD@slot@expression=\FD@expression
\else
\protected@xdef\FD@slot@expression{%
\FD@slot@expression+\FD@expression
}%
\fi
\FD@slot@known@false
\fi
}
%
% \end{macrocode}
%
% There has been some ambiguity concerning what is allowed as
% arguments of \cs{nextslot} and \cs{skipslots}. At least since
% v\,1.335 the comments in the source has said it was an integer
% expression, but the implementation was for a \TeX\ number.
% Alan's v\,1.5 manual and Rowland's v\,1.8 manual both say the
% arguments must be numbers. Allowing arbitrary integer
% expressions with \package{fontinst} is trivial, the above
% implementation copes with that, but \package{fontdoc} gets in
% trouble, so what should we do about it? /LH
%
% AFAIK, all instances of |\nextslot| or |\skipslots| appearing in
% present |*.etx| files are explicit numbers, no fancy constructs. /UV
%
% No, but if a |\setslot| command appears in a |\for| loop then the
% slot number in that command will depend on the values of various
% integer expressions anyway, so we might as well deal with it. /LH
%
% The matter was finally resolved when \package{fontdoc} was
% augmented to handle (and typeset) arbtrary integer expressions.
%
% \multchanges{\cs{nextslot}\cs{skipslots}}{1.900}{1999/02/07}^^A
% {Made changes of \cs{slot@number} global. (LH)}
% \end{macro}\end{switch}\end{macro}\end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\setleftboundary}
% \multchanges{\cs{setleftboundary}\cs{endsetleftboundary}}^^A
% {1.909}{1999/10/19}{\package{fontdoc} definition added. (LH)}
% \changes{1.917}{2001/03/23}{Made the left boundary referencable
% using \cs{label}. (LH)}
% \begin{macro}{\endsetleftboundary}
% \begin{macro}{\do_boundary}
% |\setleftboundary|\marg{glyph} \meta{slot commands}
% |\endsetleftboundary|
%
% These macros are like |\setslot| and |\endsetslot|, but they merely
% set the left boundary ligkern program, they do not cause any
% |CHARACTER| property list to be written. Thus the only metric
% information connected to the \meta{glyph} argument that is ever used
% is the kerns with this glyph on the left.
%
% |\do_boundary| and |\endsetleftboundary| are initally |\relax|, but
% are later redefined.
%
% \begin{macrocode}
%<*pkg>
\def\setleftboundary#1{\edef\slot_name{#1}\do_boundary}
\let\endsetleftboundary\x_relax
\let\do_boundary\x_relax
%
%<*doc>
\newcommand\setleftboundary[1]{%
\protected@edef\slot@name{%
\noexpand\MakePrintable \noexpand\slot@name {FD@swa}{#1}%
}%
\slot@name
\FD@tight@true
\Aheading{Left boundary `\FD@typeset@string{\slot@name}'}%
\protected@edef\@currentlabel{%
left boundary (\protect\FD@typeset@string{\slot@name})%
}%
}
\let\endsetleftboundary=\FD@tight@false
%
%<*misc>
\let\setleftboundary=\gobble_one
\let\endsetleftboundary=\x_relax
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
%
% \begin{macro}{\setrightboundary}
% |\setrightboundary|\marg{glyph}
%
% The |\setrightboundary| macro should be used to set which slot in
% the font is used as right boundary marker if that slot is empty. It
% advances |\slot_number| just like a |\setslot| \textellipsis\
% |\endsetslot| pair, but since the slot will be left empty, there is
% no need for any \meta{slot commands}, and hence there is no need for
% a closing |\endset|\textellipsis\ command either.
%
% If the right boundary marker slot is not to be left empty (often
% unavoidable), then one should use the slot command
% |\makerightboundary| instead.
%
% \changes{1.909}{1999/10/19}{doc definition added. (LH)}
% \begin{macrocode}
%<*pkg|misc>
\def\setrightboundary#1{
\makerightboundary{#1}
\advance \slot_number 1\x_relax
}
%
%<*doc>
\newcommand\setrightboundary[1]{%
\Aheading{Right boundary slot
\ifFD@slot@known@
\the\slot@number\space
\else
\(\FD@slot@expression + \the\slot@number\)
\fi
`\TypesetStringExpression{#1}'%
}%
\global\advance \slot@number \@ne
}
%
% \end{macrocode}
% \end{macro}
%
%
% \DescribeMacro{\ligature}
% \DescribeMacro{\Ligature}
% \DescribeMacro{\oddligature}
% \DescribeMacro{\nextlarger}
% \DescribeMacro{\varchar}
% \DescribeMacro{\endvarchar}
% \DescribeMacro{\usedas}
% \DescribeMacro{\makerightboundary}
% \DescribeMacro{\Unicode}
% The \meta{slot commands} are:
% \begin{quote}
% |\ligature|\marg{lig}\marg{glyph}\marg{glyph}\\
% |\Ligature|\marg{lig}\marg{glyph}\marg{glyph}\\
% |\oddligature|\marg{note}\marg{lig}\marg{glyph}\marg{glyph}\\
% |\nextlarger|\marg{glyph}\\
% |\varchar| \meta{varchar commands} |\endvarchar|\\
% |\usedas|\marg{command}\marg{type}\\
% |\makerightboundary|\marg{glyph}\\
% |\Unicode|\marg{code point}\marg{name}
% \end{quote}
% By default, these do nothing in \package{fontinst}, but most of
% those defaults are overridden locally in those situations where one
% wants them to do something. Exceptions are \cs{usedas},
% which is never used at all AFAIK,\footnote{It was intended to be
% used for math font encodings, but that never got off the
% \texttt{TODO} list. /LH} and |\oddligature| and |\Unicode|,
% which are purely documentation commands. In \package{fontdoc},
% they generate descriptive headings.
%
% \begin{macro}{\ligature}
% \begin{macro}{\Ligature}
% \changes{1.917}{2001/03/31}{Command added. (LH)}
% \begin{macro}{\oddligature}
% \changes{1.918}{2001/05/31}{Command added. (LH)}
% The |\ligature| and |\Ligature| commands have the same syntax and
% meaning to \package{fontinst}, but \package{fontdoc} can give them
% slightly different treatment. In a specification ETX file, the
% |\Ligature| command gets the heading ``Mandatory ligature'', whereas
% the |\ligature| command gets the heading ``Ordinary ligature''.
%
% The |\oddligature| command takes a fourth argument which contains a
% short note on when the ligature might be appropriate. The entire
% command is always ignored by \package{fontinst}.
% \begin{macrocode}
%\let\ligature=\gobble_three
%\def\Ligature{\ligature}
%\def\oddligature#1#2#3#4{}
%<*doc>
\newcommand\ligature[3]{%
\Bheading{\ifFD@spec@ Ordinary ligature\else Ligature\fi}
\@nameuse{FD@lig-#1}{#2}{#3}%
}
\newcommand\Ligature[3]{%
\Bheading{\ifFD@spec@ Mandatory ligature\else Ligature\fi}
\@nameuse{FD@lig-#1}{#2}{#3}%
}
\newcommand\oddligature[4]{%
\Bheading{Odd\footnote{#1} ligature}
\@nameuse{FD@lig-#2}{#3}{#4}%
}
% \end{macrocode}
%
% Symbolic typesetting of |\ligature| programs requires
% special processing.\describecsfamily{FD@lig-\meta{lig}}
% \multchanges{\cs{FD@lig-/LIG\PrintChar{`>}}\cs
% {FD@lig-LIG/\PrintChar{`>}}\cs{FD@lig-/LIG/\PrintChar{`>}}\cs
% {FD@lig-/LIG/\PrintChar{`>}\PrintChar{`>}}}{1.917}
% {2001/03/31}{Changed how \package{fontdoc} marks the current
% position after a ligature instruction, from $+$ to
% $*\lfloor$. (LH)}
% \multchanges{\cs{FD@lig-/LIG}}{1.927}
% {2004/06/21}{Fixed a typo. (LH) Reported by Werner Lemberg.}
% \multchanges{\cs{FD@lig-/LIG/\PrintChar{`>}\PrintChar{`>}}}{1.927}
% {2004/06/24}{Fixed a typo. (LH) Reported by Werner Lemberg.}
%
% \begin{macrocode}
\x@cs\def{FD@lig-LIG}#1#2{%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
${}\rightarrow{}$\typeset@glyph{#2}%
}
\x@cs\def{FD@lig-/LIG}#1#2{%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
${}\rightarrow{}$%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#2}%
}
\x@cs\def{FD@lig-LIG/}#1#2{%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
${}\rightarrow{}$%
\typeset@glyph{#2}${}*{}$\typeset@glyph{#1}%
}
\x@cs\def{FD@lig-/LIG/}#1#2{%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
${}\rightarrow{}$%
\FD@typeset@string{\slot@name}${}*{}$%
\typeset@glyph{#2}${}*{}$\typeset@glyph{#1}%
}
\x@cs\def{FD@lig-/LIG>}#1#2{%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
${}\rightarrow{}$%
\FD@typeset@string{\slot@name}${}*\lfloor$\typeset@glyph{#2}%
}
\x@cs\def{FD@lig-LIG/>}#1#2{%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
${}\rightarrow{}$%
\typeset@glyph{#2}${}*\lfloor$\typeset@glyph{#1}%
}
\x@cs\def{FD@lig-/LIG/>}#1#2{%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
${}\rightarrow{}$%
\FD@typeset@string{\slot@name}${}*\lfloor$%
\typeset@glyph{#2}${}*{}$\typeset@glyph{#1}%
}
\x@cs\def{FD@lig-/LIG/>>}#1#2{%
\FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
${}\rightarrow{}$%
\FD@typeset@string{\slot@name}${}*{}$%
\typeset@glyph{#2}${}*\lfloor$\typeset@glyph{#1}%
}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
%
% \begin{macro}{\nextlarger}
% \begin{macro}{\usedas}
% \begin{macro}{\makerightboundary}
% \begin{macrocode}
%<*pkg|misc>
\let\nextlarger=\gobble_one
\let\usedas=\gobble_two
\let\makerightboundary=\gobble_one
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\nextlarger#1{\Bheading{Next larger} \typeset@glyph{#1}}
\def\makerightboundary#1{%
\Bheading{Right boundary marker slot} designation \typeset@glyph{#1}%
}
%
% \end{macrocode}
% \missing{doc}{\usedas}
% \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\Unicode}
% \changes{1.917}{2001/03/13}{Command added. (LH)}
% \changes{1.917}{2001/03/31}{Added setting of \cs{linepenalty} and
% \cs{spaceskip}. (LH)}
% \begin{macro}{\textunicode}
% \changes{1.918}{2001/06/17}{Command added. (LH)}
% \begin{macro}{\FD@codepoint}
% \changes{1.918}{2001/06/17}{Macro added. (LH)}
% \begin{macro}{\FD@charname}
% \changes{1.918}{2001/06/17}{Macro added. (LH)}
% Since ISO\,10646\slash Unicode has become the primary reference for
% identifying characters, we provide a special comment command for
% specifying which Unicode character corresponds to a particular slot
% in an encoding. \label{Unicode} The syntax is
% \begin{quote}
% |\Unicode|\marg{code point}\marg{name}
% \end{quote}
% where the \meta{code point} is the four hexadecimal digits that
% identify the code point of the character and \meta{name} is the
% name of the character. An example is
% \begin{quote}
% |\Unicode{0041}{LATIN CAPITAL LETTER A}|
% \end{quote}
% which is typeset as
% \begin{quote}
% Unicode character \texttt{U+0041}, \textsc{latin capital letter a}.
% \end{quote}
% The \meta{name} field may be left empty.
%
% The |\Unicode| command makes a whole |\comment|, but it is also
% useful to have a similar command for writing such data as part of a
% longer paragraph. The |\textunicode| command, which has the same
% argument structure as |\Unicode|, is provided for this. If you write
% \begin{quote}
% |see also \textunicode{0041}{LATIN CAPITAL LETTER A} for|
% \end{quote}
% then this is typeset as
% \begin{quote}
% see also \texttt{U+0041} (\textsc{latin capital letter a}) for
% \end{quote}
%
% As case is not significant in the character names and they
% furthermore usually seem to be written in capitals, I have chosen
% to typeset them using small capitals only. This is done by
% |\FD@charname|. The |\FD@codepoint| macro similarly handles
% typesetting of code points. See also the \texttt{hypertex} option
% to the \package{fontdoc} package.
%
% The \package{fontinst} and \package{finstmsc} definitions of
% |\Unicode| are to gobble the arguments.
% \begin{macrocode}
%\let\Unicode=\gobble_two
%<*doc>
\newcommand*\Unicode[2]{%
\comment{%
\spaceskip=\fontdimen2\font minus 1.1\fontdimen4\font
Unicode character \FD@codepoint{#1}%
\ifx \par#2\par \else , \FD@charname{#2}\fi.%
\linepenalty=300\par
}%
}
\newcommand*\textunicode[2]{%
\FD@codepoint{#1} \ifx\par#2\par\else(\FD@charname{#2})\fi
}
\providecommand*\FD@codepoint[1]{\texttt{U+\uppercase{#1}}}
\providecommand*\FD@charname[1]{\textsc{\lowercase{#1}}}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\charseq}
% Most commonly occurring glyphs correspond to one |\Unicode|
% character, but this is not at all true in general---in fact there
% may even be letters which cannot be encoded as single characters,
% as they do not exist in precomposed form but have to be expressed
% with a base letter and combining diacritical mark. Reasonable
% compliance with the standard requires supporting character
% sequences as well as individual characters.
% \changes{1.928}{2004/11/27}{Command added. (LH)}
% \changes{1.928}{2004/12/16}{Typeset form changed, from paragraph to
% a one-item-per-line list. (LH)}
%
% In \package{fontinst}, the |\charseq| command is used to specify
% such a character sequence. The syntax is
% \begin{quote}
% |\charseq|\marg{\cs{Unicode} commands}
% \end{quote}
% where the \meta{\cs{Unicode} commands} is one or several |\Unicode|
% commands. This means the sequence of those characters. For example
% \begin{quote}
% |\charseq{|\\
% | \Unicode{0066}{LATIN SMALL LETTER F}|\\
% | \Unicode{0069}{LATIN SMALL LETTER I}|\\
% |}|
% \end{quote}
% is typeset as
% \begin{quote}
% Unicode character sequence:\\
% \vadjust{}\quad\texttt{U+0066} (\textsc{latin small letter f})\\
% \vadjust{}\quad\texttt{U+0069} (\textsc{latin small letter i})
% \end{quote}
% This indentation is made using the \texttt{IfBranch} environment,
% which could be considered a bit hackish.
%
% |\charseq| is gobbled in \Module{pkg} and \Module{misc}, but in the
% latter case it might get redefined.
% \begin{macrocode}
%\let\charseq=\gobble_one
% \end{macrocode}
% Note how the environment group restores the definition
% of |\Unicode|.
% \begin{macrocode}
%<*doc>
\newcommand\charseq[1]{%
\comment{Unicode character sequence:}%
\begin{IfBranch}%
\def\Unicode##1##2{%
\noindent\FD@codepoint{##1}
\ifx\par##2\par\else(\FD@charname{##2})\fi
\par
}%
#1%
\end{IfBranch}%
}
%
% \end{macrocode}
% \end{macro}
%
%
% \DescribeMacro{\vartop}
% \DescribeMacro{\varmid}
% \DescribeMacro{\varbot}
% \DescribeMacro{\varrep}
% The \meta{varchar commands} are:
% \begin{quote}
% |\vartop|\marg{glyph}\\
% |\varmid|\marg{glyph}\\
% |\varbot|\marg{glyph}\\
% |\varrep|\marg{glyph}
% \end{quote}
% These too do by default, which is overridden later, nothing in
% \package{fontinst} but typeset descriptive headings in \package{fontdoc}.
%
% \begin{macro}{\varchar}
% \begin{macro}{\vartop}
% \begin{macro}{\varmid}
% \begin{macro}{\varbot}
% \begin{macro}{\varrep}
% \begin{macro}{\endvarchar}
% \begin{macrocode}
%<*pkg|misc>
\let\varchar=\empty_command
\let\vartop=\gobble_one
\let\varmid=\gobble_one
\let\varbot=\gobble_one
\let\varrep=\gobble_one
\let\endvarchar=\empty_command
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\varchar{\Bheading{Extensible glyph:}}
\def\vartop#1{\Bheading{Top} \typeset@glyph{#1}}
\def\varmid#1{\Bheading{Middle} \typeset@glyph{#1}}
\def\varbot#1{\Bheading{Bottom} \typeset@glyph{#1}}
\def\varrep#1{\Bheading{Repeated} \typeset@glyph{#1}}
\let\endvarchar\relax
%
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\useexamplefont}
% \begin{macro}{\slotexample}
% \begin{macro}{\setslotcomment}
% \begin{macro}{\resetslotcomment}
% \begin{macro}{\unsetslotcomment}
% \begin{macro}{\slot@comment}
% \begin{macro}{\slot@font}
% As of v\,1.8 of \package{fontinst}, we have added an interface
% for automatic documentation of encoding files, which has been
% developed by Matthias Clasen as part of his work on math fonts.
% The implementation was slightly modified and integrated into
% this version by Ulrik Vieth.
%
% |\setslotcomment| defines a default slot comment, stored in the
% variable |\slot@comment|, which is subsequently used to annotate
% all |\setslot| commands. The slot comment can be changed by
% |\resetslotcomment| or turned off by |\unsetslotcomment|.
%
% |\useexamplefont| defines a default font, |\slot@font|, which
% may be referenced by calling |\slotexample| in slot comments to
% display the character or symbol allocated to the current slot.
%
% Taking advantage of this mechanism, it is possible to write:
% \begin{quote}
% |\useexamplefont{FONT}|\\[0.5\baselineskip]
% |\setslotcomment{The symbol `\slotexample'.}|\\
% |\setslot{FOO}\endsetslot|\\
% |\setslot{BAR}\endsetslot|\\
% |\resetslotcomment{The character `\slotexample'.}|\\
% |\setslot{BAZ}\endsetslot|
% \end{quote}
% instead of having to write:
% \begin{quote}
% |\usepackage{PACKAGE-to-use-symbols-from-FONT}|\\[0.5\baselineskip]
% |\setslot{FOO}\comment{The symbol `\foo'.}\endsetslot|\\
% |\setslot{BAR}\comment{The symbol `\bar'.}\endsetslot|\\
% |\setslot{BAZ}\comment{The character `\baz'.}\endsetslot|
% \end{quote}
%
% These macros never do anything in \package{fontinst}, they just
% gobble their arguments.
% \begin{macrocode}
%<*pkg|misc>
\let\useexamplefont=\gobble_one
\let\slotexample=\empty_command
\let\setslotcomment=\gobble_one
\let\resetslotcomment=\gobble_one
\let\unsetslotcomment=\empty_command
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newif\ifslot@comment@
\slot@comment@false
\def\slot@comment{}
\newcommand\setslotcomment[1]{%
\slot@comment@true
\gdef\slot@comment{#1}%
}
\newcommand\resetslotcomment[1]{\gdef\slot@comment{#1}}
\newcommand\unsetslotcomment{%
\slot@comment@false
\global\let\slot@comment\@empty
}
% \end{macrocode}
%
% \begin{macrocode}
\let\slot@font=\nullfont
\newcommand\useexamplefont[1]{\font\slot@font=#1 }
\newcommand\slotexample{%
\ifFD@slot@known@{\slot@font\char\slot@number}\fi
}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\setfontdimen}
% \changes{1.917}{2001/03/16}{Command added. (LH)}
% The |\setfontdimen| command is used in an ETX file to set a font
% dimen. The syntax is
% \begin{quote}
% |\setfontdimen|\marg{fontdimen no.}\marg{integer}
% \end{quote}
% where \meta{fontdimen no.} and \meta{integer} are \emph{string}
% expressions. \meta{fontdimen no.} specifies the fontdimen to set.
% \meta{integer} is the name of the integer variable to whose value
% the fontdimen will be set.
%
% When used in font installation, the above |\setfontdimen| command
% is equivalent to
% \changes{1.923}{2002/10/25}{Leave the fontdimen unset when the
% integer variable has not been set. (LH)}
% \begin{quote}
% |\ifisint|\marg{integer}|\then|\\
% | \setint{fontdimen(|\meta{fontdimen no.}|)}{\int{|^^A
% \meta{integer}|}}|\\
% |\fi|
% \end{quote}
% but |\setfontdimen| is also understood by the (V)PL-to-MTX
% converter as declaring an integer that the generated MTX file
% should set to the value of the fontdimen in the (V)PL.
% \begin{macrocode}
%<*pkg>
\def\setfontdimen#1#2{
\ifisint{#2}\then \setint{fontdimen(#1)}{\int{#2}} \fi
}
%
%\let\setfontdimen\gobble_two
%<*doc>
\newcommand\setfontdimen[2]{%
\Bheading{Fontdimen} \TypesetStringExpression{#1} is
\(\TypesetIntegerExpression{\int{#2}}\)%
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\label}
% \changes{1.917}{2001/03/23}{Macro added. (LH)}
% \package{fontinst} and \package{finstmsc} defines the \LaTeX\
% |\label| command to gobble its argument, so that one can use it to
% reference slots.
% \begin{macrocode}
%\let\label=\gobble_one
% \end{macrocode}
% \end{macro}
%
% \begin{switch}{direct}
% The encoding aspect of a font can to a large extent be understood
% as a mapping from the set of slots to the set of glyphs---such
% mappings are for example realised by PostScript encoding vectors
% (mapping slots to glyph names) and virtual fonts (mapping slots to
% DVI commands for drawing a glyph). In some cases however, encodings
% are rather used to specify an inverse mapping going the opposite
% way. Since encodings are in general many-to-one, this means there
% need not be a proper inverse to a given encoding; instead the
% inverse image of a glyph is in practice chosen randomly\footnote{In
% the sense: according to a very deterministic (but not particularly
% useful) rule which depends completely on details in the
% implementation, and therefore should not be relied upon anyway.}
% among the slots that are mapped to it. This is not always desirable.
%
% The \texttt{direct} switch can be used to check whether an encoding
% is interpreted in the direct (slots to glyphs) or inverse (glyphs to
% slots) manner. If those |\setslot| commands which are undesirable
% under the inverse interpretation are put inside an |\ifdirect|
% \dots\ |\Fi| construction, then these will be ignored in that
% circumstance, thus allowing the programmer to exactly specify both
% the direct and the inverse mappings.
% \changes{1.924}{2003/02/08}{Command added. (LH)}
%
% In \package{fontinst}, this command is a switch, which is usually
% true.
% \begin{macrocode}
%\newif\ifdirect \directtrue
% \end{macrocode}
% In \package{fontdoc}, this is a conditional that will be typeset
% if |\showbranches| is being used.
% \begin{macrocode}
%\newcommand\ifdirect{\generic@if{direct}}
% \end{macrocode}
% \end{switch}
%
% \begin{macro}{\input_mtx_as_etx}
% The |\input_mtx_as_etx| command is syntactically similar to the
% |\inputetx| command, but it inputs an MTX file instead of an ETX
% file and redefines |\setscaledrawglyph| so that it expands to a
% |\nextslot| followed by a |\setslot| \dots\ |\endsetslot|. This is
% useful when making proofs of fonts with nonstandard encodings, as
% the MTX of a font can be used to specify ``the default encoding''
% of that font.
%
% \textbf{Warning:} Since this macro redefines a lot of the metric
% commands, you'll probably only want to call it inside a group.
% \changes{1.923}{2002/10/24}{Macro added. (LH)}
% \begin{macrocode}
%<*pkg|misc>
\def\input_mtx_as_etx#1{
\def\setscaledrawglyph##1##2##3##4##5##6##7##8##9{
\nextslot{##5}
\setslot{##1}\endsetslot
}
\offcommand\setscalednotglyph
\let\setglyph=\gobble_glyph
\offcommand\setkern
\inputmtx{#1}
}
%
% \end{macrocode}
% \end{macro}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Metric files}
% \label{Sec:Metric files}
%
% \changes{1.911}{1999/11/17}{Definitions of metric file commands
% added to \protect\protect\protect\Module{misc}. (LH)}
%
% \DescribeMacro{\inputmtx}
% The macro
% \begin{quote}
% |\inputmtx|\marg{filename}
% \end{quote}
% inputs \meta{filename}|.mtx|, ignoring anything between |\relax| and
% |\metrics|, and anything after |\endmetrics|.
%
% \begin{macro}{\inputmtx}
% \begin{macro}{\metrics}
% \changes{1.914}{2000/05/26}{Fixed typo: \cs{x@relax} instead of
% \cs{x_relax}. (LH)}
% \usechange{raggedright}
% \begin{macro}{\endmetrics}
% \changes{1.900}{1999/02/08}{Made it outer. (LH)}
% \usechange{raggedright}
% \begin{macro}{\endmetrics_text}
% \begin{macro}{\endmetrics@hook}
% The |\endmetrics_text| macro expands to |\endmetrics| (eleven
% `other' tokens, not one control sequence token). It is used instead
% of |\string\endmetrics|, which does not work since |\endmetrics| is
% outer.
% \begin{macrocode}
%<*pkg|misc>
\def\inputmtx#1{
\def\relax{\let\relax=\x_relax\iffalse}
\let\metrics=\fi
\primitiveinput #1.mtx\x_relax
\let\relax=\x_relax
}
\let\metrics=\x_relax
\edef\endmetrics_text{\string\endmetrics}
\outer\def\endmetrics{\endinput}
%
% \end{macrocode}
% |\inputmtx| used to set |\a_count|, but we haven't been able to
% find a reason for this, so it was removed.
%
% In \package{fontdoc}, the |\metrics| and |\endmetrics| macros
% initially just define a group, but |\inputmtx| redefines them to
% work as they do in \package{fontinst}. |\endmetrics@hook| is a
% macro that gets executed just before the |\endgroup| in
% |\endmetrics|; it is normally |\@empty|, and it is set to this value
% at each |\metrics|, but the metric package system redefines it.
% \multchanges{\cs{endmetrics_hook}}{1.914}{2000/05/27}{Macro added.
% (LH)}
% \multchanges{\cs{inputetx}\cs{inputmtx}}{1.914}{2000/05/27}
% {New \package{fontdoc} definition, using \cs{IfFileExists}. (LH)}
% \begin{macrocode}
%<*doc>
\def\inputmtx#1{%
\begingroup
\edef\lowercase@file{\lowercase{%
\edef\noexpand\lowercase@file{#1}%
}}%
\lowercase@file
\let\endmetrics@hook=\@empty
\IfFileExists{\lowercase@file.mtx}{%
\skip@mtx@preamble
\@@input \@filef@und
\let\relax=\x@relax
}{%
\PackageError{fontdoc}{File #1.mtx not found}%
{\@eha\MessageBreak You can \protect\inputmtx\space
some other file now, if you want.}%
}
\endmetrics@hook
\endgroup
}
\def\skip@mtx@preamble{%
\def\relax{\let\relax=\x@relax\iffalse}%
\let\metrics=\fi
\outer\x@cs\def{endmetrics}{\endinput}%
}
\def\metrics{%
\begin{flushleft}%
\let\endmetrics@hook=\@empty
}
\outer\def\endmetrics{%
\endmetrics@hook
\end{flushleft}%
}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
%
%
% \begin{macro}{\ProvidesMtxPackage}
% \changes{1.923}{2003/01/05}{Redesigned the headings for metric
% packages, since they interact poorly with \cs{section} headings.
% (LH)}
% \begin{switch}{@mtxpackage@headed@}
% \begin{macro}{\announce@package}
% \begin{macro}{\finish@package}
% \multchanges{\cs{ProvidesMtxPackage}\cs{usemtxpackage}}{1.914}
% {2000/05/27}{New \package{fontdoc} implementation---the packages
% are actually loaded (they have to, since they can define
% commands). Multiple loading is prevented as in
% \package{fontinst}. (LH)}
% The call
% \begin{quote}
% |\ProvidesMtxPackage|\marg{package~name}
% \end{quote}
% signals to the package managing system that there is no need to load
% this package again.
% \begin{macrocode}
%\def\ProvidesMtxPackage#1{\x_cs\let{pack-#1}P}
%<*doc>
\def\ProvidesMtxPackage#1{%
\endmetrics@hook
% \@mtxpackage@headed@false
% \everypar={
\announce@package{#1}%
% }%
\def\endmetrics@hook{\finish@package{#1}}
\global\x@cs\let{FD@pack-#1}\@empty
}
% \end{macrocode}
% \begin{macrocode}
% \newif\if@mtxpackage@headed@
% \end{macrocode}
% \begin{macrocode}
\def\announce@package#1{%
% \everypar={}%
% \@mtxpackage@headed@true
\Aheading{[Start of metric package \textsf{#1}.}%
}
% \end{macrocode}
% \begin{macrocode}
\def\finish@package#1{%
% \if@mtxpackage@headed@
\Aheading{End of metric package \textsf{#1}.]}%
% \else
% \everypar={}%
% \Aheading{(Metric package \textsf{#1}.)}%
% \fi
\par\addvspace\medskipamount
}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{switch}\end{macro}
%
%
% \begin{macro}{\usemtxpackage}
% The call
% \begin{quote}
% |\usemtxpackage|\marg{package~list}
% \end{quote}
% inputs those of the packages in the list that have not been loaded
% yet (i.e., those for which no |\ProvidesMtxPackage| has been made).
% Each package is assumed to reside in the metric file that
% |\inputmtx| loads when given the name of the package as argument.
%
% The call
% \begin{quote}
% |\usemtxpackage|\oarg{filename}\marg{package~list}
% \end{quote}
% inputs the packages in the list if at least one of them has not been
% loaded yet. In this case, all the packages are assumed to reside in
% the single metric file that |\inputmtx| loads when given
% \meta{filename} as argument.
%
% \begin{macrocode}
%<*pkg>
\def\usemtxpackage{\futurelet\next_token\test_UseMtxPkg_arguments}
\def\test_UseMtxPkg_arguments{\ifx\next_token[
\expandafter\mtx_package_given_file
\else
\expandafter\mtx_package_separate_files
\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\mtx_package_given_file[#1]#2{
\_a_false
\process_csep_list\load_true_unless_loaded #2,\process_csep_list,
\if_a_ \inputmtx{#1} \fi
}
\def\load_true_unless_loaded#1{
\x_cs\ifx{pack-#1}P\else\_a_true\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\mtx_package_separate_files#1{
\process_csep_list\load_file_unless_loaded #1,\process_csep_list,
}
\def\load_file_unless_loaded#1{
\x_cs\ifx{pack-#1}P\else \inputmtx{#1} \fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\usemtxpackage[2][\x@relax]{%
\ifx \x@relax#1%
\@for\@tempa:=#2\do{%
\x@cs\ifx{FD@pack-\@tempa}\@empty \else
\inputmtx{\@tempa}%
\fi
}%
\else
\@tempswafalse
\@for\@tempa:=#1\do{%
\x@cs\ifx{FD@pack-\@tempa}\@empty \else \@tempswatrue \fi
}%
\if@tempswa
\inputmtx{#2}%
\fi
\fi
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\glyph_name_modifier}
% The |\glyph_name_modifier| macro is applied to all glyph names
% supplied to commands that are allowed in transformable MTX files
% (see Subsection~\ref{Ssec:TransMTX}). The syntax is
% \begin{quote}
% |\glyph_name_modifier|\marg{glyph name}
% \end{quote}
% and the above must expand fully to a valid glyph name in \TeX's
% mouth.
%
% \changes{1.923}{2002/10/20}{Macro added. (LH)}
% The normal definition is to simply expand to the \meta{glyph name},
% i.e.,
% \begin{macrocode}
%\let\glyph_name_modifier=\identity_one
% \end{macrocode}
% but the command may expand to any sequence of character tokens. It
% was introduced to support (simple) automatic renaming of glyphs
% in cases where the |\reglyphfont| command would not be appropriate,
% such as when the wanted renaming is simply to add a short suffix to
% the glyph names.
%
% The reason it only affects the commands allowed in transformable
% MTX files is that the macro isn't meant as a generic override for
% metric commands.
% \end{macro}
%
%
% \subsection{Kerning information}
%
% The kerning information is kept in the macros
% \describecsfamily{l-\meta{name}}|\l-|\meta{name} and
% \describecsfamily{r-\meta{name}}|\r-|\meta{name}, containing
% information about how \meta{name} kerns on the left and on the right,
% respectively. The |\l-|\meta{name} macro should expand out to a
% series of
% \begin{quote}
% \DescribeMacro{\k}|\k|\,|\r-|\meta{name}\,|\|\meta{amount}
% \end{quote}
% control sequences, and vice versa. Examples of
% \describecsfamily{\meta{amount}} |\|\meta{amount}
% control sequences are: |\0|, |\1|, |\1000|, |\-50|, |\33|; these
% corresponds to the kern amounts $0$, $1$, $1000$ (which would be
% a very large kern), $-50$, and $33$ respectively.
%
%
% \begin{macro}{\setkern}
% |\setkern|\marg{glyph1}\marg{glyph2}\marg{integer expression}
%
% Sets a kern pair between \meta{glyph1} and \meta{glyph2} to the
% specified value, which is typically a value returned by
% |\kerning|\marg{glyph3}\marg{glyph4}. If there already is a kern
% set between \meta{glyph1} and \meta{glyph2} then this will not affect
% the output, but it will use up another 3 units of token memory.
%
% \begin{macrocode}
%<*pkg>
\def\setkern#1#2#3{
\x_cs\ifx{i-rawscale}\x_relax
\expandafter\set_kern
\csname~r-\glyph_name_modifier{#1}\expandafter\endcsname
\csname~l-\glyph_name_modifier{#2}\endcsname
{#3}
\else
\expandafter\set_kern
\csname~r-\glyph_name_modifier{#1}\expandafter\endcsname
\csname~l-\glyph_name_modifier{#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}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\setkern[3]{%
\Bheading{Kern} \typeset@glyph{#1}${{}+{}}$\typeset@glyph{#2}%
${}\rightarrow \TypesetIntegerExpression{#3}$%
}
%
%\let\setkern=\gobble_three
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\resetkern}
% |\resetkern|\marg{glyph1}\marg{glyph2}\marg{integer expression}
%
% Resets the kern pair between \meta{glyph1} and \meta{glyph2} to
% the specified value. Note however that this does not relieve \TeX\
% of the burden to remember the previous kerning pair between these
% two glyphs (if there was one).
%
% \begin{macrocode}
%<*pkg>
\def\resetkern#1#2#3{
\x_cs\ifx{i-rawscale}\x_relax
\expandafter\reset_kern
\csname~r-#1\expandafter\endcsname
\csname~l-#2\endcsname{#3}
\else
\expandafter\reset_kern
\csname~r-#1\expandafter\endcsname
\csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}}
\fi
}
\def\reset_kern#1#2#3{
\eval_expr{#3}
\expandafter\reset_kern_cs\csname\the\result\endcsname#1#2
}
\def\reset_kern_cs#1#2#3{
\prep_to#2{\k\expandafter#3\expandafter#1}
\prep_to#3{\k\expandafter#2\expandafter#1}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\resetkern[3]{%
\Bheading{Override kern} \typeset@glyph{#1}${{}+{}}$\typeset@glyph{#2}%
${}\rightarrow \TypesetIntegerExpression{#3}$%
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\setleftkerning}
% \begin{macro}{\setrightkerning}
% \begin{macro}{\setleftrightkerning}
% |\setleftkerning|\marg{glyph1}\marg{glyph2}\marg{scaled}\\
% |\setrightkerning|\marg{glyph1}\marg{glyph2}\marg{scaled}\\
% |\setleftrightkerning|\marg{glyph1}\marg{glyph2}\marg{scaled}
%
% Sets left or right kerning of \meta{glyph1} to that of \meta{glyph2}
% scaled by \meta{scaled} (which is an integer expression).
% |\setleftrightkerning| does both.
%
% \begin{macrocode}
%<*pkg>
\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\setleftrightkerning#1#2#3{
\eval_expr_to\b_count{#3}
\expandafter\set_kerning
\csname~l-#1\expandafter\endcsname
\csname~l-#2\endcsname
\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
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\setleftkerning[3]{%
\Bheading{Kern} \typeset@glyph{#1} on the left like
\typeset@glyph{#2} \ConditionallyScaled{#3}}
\newcommand\setrightkerning[3]{%
\Bheading{Kern} \typeset@glyph{#1} on the right like
\typeset@glyph{#2} \ConditionallyScaled{#3}}
\newcommand\setleftrightkerning[3]{%
\Bheading{Kern} \typeset@glyph{#1} on the left and right like
\typeset@glyph{#2} \ConditionallyScaled{#3}}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\ConditionallyScaled}
% \changes{1.916}{2001/01/06}{Command added. (LH)}
% Several metric commands have take a scaling factor argument which is
% rendered by \package{fontdoc} as ``scaled \meta{argument}''. The by
% far most common value for this argument is however the constant
% number 1000 (no scaling), and in those cases the ``scaled
% \textellipsis'' feels a bit long-winded. The cure for this is the
% |\Conditionally|\-|Scaled| command, which takes an integer expression
% as its argument and typesets the ``scaled \meta{integer expression}''
% \emph{unless} that expression evaluates to 1000, in which case
% |\Conditionally|\-|Scaled| simply gobbles any spaces following it.
% \begin{macrocode}
\newcommand\ConditionallyScaled[1]{%
\FD@evaluate@true
\FD@eval@expr{#1}%
\@tempswatrue
\ifFD@evaluate@ \ifnum \FD@result=\@m \@tempswafalse \fi\fi
\FD@evaluate@false
\if@tempswa scaled \(\FD@expression\)\else \ignorespaces \fi
}
%
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\kerning}
% |\kerning|\marg{glyph1}\marg{glyph2}
%
% Returns the value of kern pair between \meta{glyph1} and
% \meta{glyph2} as an integer. Returns a value of zero if such a kern
% pair doesn't exist.
%
% \begin{macrocode}
%<*pkg>
\def\kerning#1#2{0\x_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}
}
%
% \end{macrocode}
% \changes{1.909}{1999/10/19}{A use of \#1 where it should have
% been \#2 was corrected. (LH)}
% \begin{macrocode}
%<*doc>
\DeclareRobustCommand\kerning[2]{%
\begingroup
\MakePrintable\@tempa{FD@swa}{#1}%
\MakePrintable\@tempb{FD@swa}{#2}%
\protected@xdef\FD@expression{%
\mathop{\protect\mathrm{k{}}}(%
\text{\protect\FD@typeset@string{\@tempa}}%
,\penalty\FD@commapenalty
\text{\protect\FD@typeset@string{\@tempb}}%
)%
}%
\global\chardef\FD@priority=5%
\global\FD@bracket@level=\@ne
\FD@evaluate@false
\endgroup
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifiskern}
% |\ifiskern|\marg{glyph1}\marg{glyph2}|\then|
%
% This command tests if there is a kern pair between \meta{glyph1} and
% \meta{glyph2}. It's hard to say if there is a use for it, but it is
% included for symmetry.
%
% \begin{macrocode}
%<*pkg>
\def\ifiskern#1#2\then{
\def\k##1##2{\ifx T##1 \let\k\gobble_two \fi}
\bgroup
\x_cs\let{l-#2}T
\csname r-#1\endcsname
\expandafter\egroup \ifx\k\gobble_two
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\ifiskern#1#2\then{%
\generic@if{kern \typeset@glyph{#1}${}+{}$\typeset@glyph{#2} set}%
}
%
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\unsetkerns}
% |\unsetkerns|\marg{left~glyph~list}\marg{right~glyph~list}
%
% This command unsets all kerns with a glyph in the \meta{left~glyph~list}
% on the left and a glyph in the \meta{right~glyph~list} on the right.
% The lists themselves are ordinary comma-separated lists. Unlike
% |\setkern| and |\resetkern|, |\unsetkerns| actually removes the
% kerning pairs from \TeX's memory.
%
% The implementation itself simply goes through |\r-|\meta{left~glyph}
% for each element \meta{left~glyph} in \meta{left~glyph~list} and
% |\l-|\meta{right~glyph} for each element \meta{right~glyph} in
% \meta{right~glyph~list}, removing each |\k|\meta{token}\meta{token}
% tripple that refers to a glyph from the opposite list as it goes
% along. To make this test reasonably fast, the routine first ``marks''
% the glyphs in the other list by setting the control sequences
% |\slots-|\meta{glyph} to |U| (the letter token U). This mark is
% later removed when the |\r-|\meta{glyph} or |\l-|\meta{glyph}
% respectively control sequences have been gone through; the
% |\slots-|\meta{glyph} control sequences are then set to |\relax|.
%
% \begin{macrocode}
%<*pkg>
\def\unsetkerns#1#2{
\let\k\k_unless_to_U
\process_csep_list\make_slots_U#1,\process_csep_list,
\def\do##1{\x_cs\main_remove_Us{l-##1}}
\process_csep_list\do#2,\process_csep_list,
\process_csep_list\make_slots_relax#1,\process_csep_list,
\process_csep_list\make_slots_U#2,\process_csep_list,
\def\do##1{\x_cs\main_remove_Us{r-##1}}
\process_csep_list\do#1,\process_csep_list,
\process_csep_list\make_slots_relax#2,\process_csep_list,
}
\def\make_slots_U#1{\x_cs\let{slots-#1}U}
\def\make_slots_relax#1{\x_cs\let{slots-#1}\x_relax}
\def\k_unless_to_U#1#2{
\x_cs\ifx{slots-\expandafter\gobble_three\string#1}U \else
\noexpand\k\noexpand#1\noexpand#2
\fi
}
\def\main_remove_Us#1{
\ifx#1\x_relax \else
\edef#1{#1}
\ifx#1\empty_command \let#1\x_relax \fi
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\unsetkerns[2]{%
\Bheading{Remove} all kerning pairs in
\FD@typeset@string@set{#1}${}\times{}$\FD@typeset@string@set{#2}%
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\FD@typeset@string@set}
% \begin{macro}{\FD@typeset@string@set@}
% \multchanges{\cs{FD@typeset@string@set}^^A
% \cs{FD@typeset@string@set@}}{1.916}{2001/01/02}{Macros added.
% \cs{FD@typeset@string@set} should be used instead of
% \cs{print@csep@list} in most occations. (LH)}
% The |\FD@typeset@string@set| macro takes a comma-separated list of
% string expressions as argument and typesets that list as elements of
% a set, e.g.
% \begin{quote}
% |\FD@typeset@string@set{a,b,\str{c}}|
% \end{quote}
% is typeset as
% \begin{quote}
% $\{$\texttt{a}$,{}$\texttt{b}$,\mathrm{s}($\texttt{c}$)\}$
% \end{quote}
% \begin{macrocode}
\def\FD@typeset@string@set#1{%
\toks@={}%
\@for\@tempa:=#1\do{%
\protected@edef\@tempa{%
\noexpand\MakePrintable \noexpand\@tempa {FD@swa}{\@tempa}%
}%
\@tempa
\toks@=\expandafter{\the\expandafter\toks@
\expandafter\do \expandafter{\@tempa}}%
}%
\expandafter\FD@typeset@string@set@ \expandafter{\the\toks@}%
}
\def\FD@typeset@string@set@#1{%
\TypesetList{$\{$}{$,\penalty\FD@commapenalty{}$}%
{$,\penalty\FD@commapenalty{}$}{$,\penalty\FD@commapenalty{}$}%
{$\}$}{$\emptyset$}{\FD@typeset@string}{#1}%
}
%
% \end{macrocode}
% \end{macro}\end{macro}
%
%
% \begin{macro}{\noleftkerning}
% \changes{1.906}{1999/07/30}{Macro added. (LH)}
% \begin{macro}{\norightkerning}
% \changes{1.906}{1999/07/30}{Macro added. (LH)}
% \begin{macro}{\noleftrightkerning}
% \changes{1.906}{1999/07/30}{Macro added. (LH)}
% The argument of these commands is the name of a glyph. The commands
% removes all kerns on the left, on the right, and on both sides
% respectively, of this glyph.
%
% \begin{macrocode}
%<*pkg>
\def\noleftkerning#1{\no_kerning{l}{#1}}
\def\norightkerning#1{\no_kerning{r}{#1}}
\def\noleftrightkerning#1{\no_kerning{l}{#1}\no_kerning{r}{#1}}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\noleftkerning[1]{%
\Bheading{Remove kerns} on the left of glyphs in
\FD@typeset@string@set{#1}.}
\newcommand\norightkerning[1]{%
\Bheading{Remove kerns} on the right of glyphs in
\FD@typeset@string@set{#1}.}
\newcommand\noleftrightkerning[1]{%
\Bheading{Remove kerns} on any side of glyphs in
\FD@typeset@string@set{#1}.}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\no_kerning}
% \changes{1.906}{1999/07/30}{Macro added. (LH)}^^A
% \changes{1.906}{1999/08/01}{Macro thoroughly rewritten. (LH)}^^A
% This macro is called as
% \begin{quote}
% |\no_kerning|\marg{side}\marg{glyph list}
% \end{quote}
% where \meta{side} is |l| or |r|, and \meta{glyph list} is a
% comma-separated list of glyph names. The macro unsets all kerns on
% the \meta{side} side of the glyphs in the \meta{glyph list}.
%
% \begin{macrocode}
%<*pkg>
\def\no_kerning#1#2{
\let\k\no_kerning_i
\def\do##1{\csname #1-##1\endcsname}
\bgroup
\aftergroup\def \aftergroup\a_macro \aftergroup{
\process_csep_list\do #2,\process_csep_list,
\aftergroup}
\egroup
\def\do##1{\expandafter\let \csname #1-##1\endcsname \x_relax}
\process_csep_list\do #2,\process_csep_list,
\let\k\no_kerning_ii
\def\do##1{\edef##1{##1}}
\a_macro
}
% \end{macrocode}
% \begin{macro}{\no_kerning_i}
% The |\no_kerning_i| macro is used by |\no_kerning| in constructing
% a list of all glyphs that a glyph in the \meta{glyph list} has a
% \meta{side} kern to, while avoiding repetitions.
% \begin{macrocode}
\def\no_kerning_i#1#2{
\ifx #1\x_relax \else
\aftergroup\do \aftergroup#1
\let #1\x_relax
\fi
}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\no_kerning_ii}
% The |\no_kerning_ii| macro is similar to the |\k_unless_to_U|
% macro.
% \begin{macrocode}
\def\no_kerning_ii#1#2{
\ifx #1\x_relax \else \noexpand\k \noexpand#1 \noexpand#2 \fi
}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
% \subsection{Glyph information}
% \label{Ssec:Glyph-info}
%
% The glyph information is kept in the macros
% \describecsfamily{g-\meta{name}}|\g-|\meta{name}, which expands
% out to:
% \begin{quote}
% \marg{width}\marg{height}\marg{depth}\marg{italic}^^A
% \marg{mapcommands}\marg{mapfonts}
% \end{quote}
% where the \meta{mapcommands} will write out VPL |MAP| fragments to a
% |.vpl| file, and the \meta{mapfonts} will produce any |MAPFONT|
% instructions that are needed.
%
%
% \begin{macro}{\typeset@glyph}
% \changes{1.909}{1999/10/20}{Macro added, and most commands that
% print a glyph name changed to use this macro. (LH)}
% \changes{1.916}{2001/01/02}{Macro redefined (made synonymous to
% \cs{Typeset\-String\-Expression}). (LH)}
% The |\typeset@glyph| macro takes a string expression and typesets
% that as the name of a glyph. Currently names of glyphs are formatted
% precisely the same as any other string expression.
% \begin{macrocode}
%\let\typeset@glyph=\TypesetStringExpression
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\width}
% \begin{macro}{\height}
% \begin{macro}{\depth}
% \begin{macro}{\italic}
% |\width|\marg{glyph}\\
% |\height|\marg{glyph}\\
% |\depth|\marg{glyph}\\
% |\italic|\marg{glyph}
%
% In \package{fontinst}, these macros return the width, height,
% depth, and italic correction of \meta{glyph} as an integer.
% \begin{macrocode}
%<*pkg>
\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}
%
% \end{macrocode}
%
% In \package{fontdoc}, they print symbolic representations for the
% corresponding integer expressions.
% \begin{macrocode}
%<*doc>
\DeclareRobustCommand\width[1]{\FD@glyph@metric{w}{#1}}
\DeclareRobustCommand\height[1]{\FD@glyph@metric{h}{#1}}
\DeclareRobustCommand\depth[1]{\FD@glyph@metric{d}{#1}}
\DeclareRobustCommand\italic[1]{\FD@glyph@metric{i}{#1}}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\FD@glyph@metric}
% The |\FD@glyph@metric| macro is a convenient shorthand to use when
% defining integer-valued functions which represents some glyph
% metric (e.g.\ \cs{height}). Its syntax is
% \begin{quote}
% |\FD@glyph@metric|\marg{func-name}\marg{string expression}
% \end{quote}
% The \meta{string expression} must be expanded.
% \begin{macrocode}
\def\FD@glyph@metric#1#2{%
\begingroup
\MakePrintable\@tempa{FD@swa}{#2}%
\protected@xdef\FD@expression{%
\protect\FD@integer@func{#1}{\@tempa}%
}%
\global\chardef\FD@priority=5%
\global\FD@bracket@level=\@ne
\FD@evaluate@false
\endgroup
}
%
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\mapcommands}
% \begin{macro}{\mapfonts}
% These are similar to |\width| and its companions, but they are not
% user level commands.
% \begin{macrocode}
%<*pkg>
\def\mapcommands{\glyph_parameter\fifth_of_six}
\def\mapfonts{\glyph_parameter\sixth_of_six}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\glyph_parameter}
% \begin{macro}{\first_of_six}
% \begin{macro}{\second_of_six}
% \begin{macro}{\third_of_six}
% \begin{macro}{\fourth_of_six}
% \begin{macro}{\fifth_of_six}
% \begin{macro}{\sixth_of_six}
% \begin{macro}{\glyph_metrics}
% These macros are used to define |\width| and its friends.
% |\glyph_parameter| takes one of the other seven for its first
% argument and a glyph name for its second argument. The
% |\glyph_metrics| macro can be used if one wants to get all the
% metric variables at once.
% \begin{macrocode}
%<*pkg>
\def\glyph_parameter#1#2{
\expandafter\expandafter\expandafter
#1\csname g-#2\endcsname
}
% \end{macrocode}
% \begin{macrocode}
\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}
% \end{macrocode}
% \begin{macrocode}
\def\glyph_metrics#1#2#3#4#5#6{
\a_count=#1
\b_count=#2
\c_count=#3
\d_count=#4~
}
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
% \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\saved_scale}
% \begin{macro}{\saved_mapfont}
% \begin{macro}{\saved_raw}
% \begin{macro}{\saved_rule}
% \begin{macro}{\saved_special}
% \begin{macro}{\saved_warning}
% \begin{macro}{\saved_movert}
% \begin{macro}{\saved_moveup}
% \begin{macro}{\saved_push}
% \begin{macro}{\saved_pop}
% These are the commands allowed inside a glyph. They are initally
% set to |\relax|, so we can |\edef| with them safely.
% \begin{macrocode}
\let\saved_scale\x_relax
\let\saved_mapfont\x_relax
\let\saved_raw\x_relax
\let\saved_rule\x_relax
\let\saved_special\x_relax
\let\saved_warning\x_relax
\let\saved_movert\x_relax
\let\saved_moveup\x_relax
\let\saved_push\x_relax
\let\saved_pop\x_relax
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
%
% When the glyph is being constructed by
% \begin{quote}
% |\setglyph|\marg{glyph} \meta{glyph commands} |\endsetglyph|
% \end{quote}
% the values of each of these parameters are kept in the following
% variables. Except for |\glyph_width|, these are kept globally,
% so they survive through |\push| \textellipsis\ |\pop| pairs. In
% addition, the current vertical offset is kept locally in
% |\glyph_voffset|. The |\glyph_maxhpos| variable globally keeps track
% of the largest horizontal offset position reached so far (with the
% possible exception of the current position, i.e.\ width, which may
% well be larger).
%
%
% \begin{macro}{\glyph_width}
% \begin{macro}{\glyph_height}
% \begin{macro}{\glyph_depth}
% \begin{macro}{\glyph_italic}
% \begin{macro}{\glyph_map_commands}
% \begin{macro}{\glyph_map_fonts}
% \begin{macro}{\glyph_voffset}
% \begin{macro}{\glyph_maxhpos}
% \changes{1.903}{1999/05/20}{Variable added. (LH)}
% \begin{macrocode}
\newcount\glyph_width
\newcount\glyph_height
\newcount\glyph_depth
\newcount\glyph_italic
\newtoks\glyph_map_commands
\newtoks\glyph_map_fonts
\newcount\glyph_voffset
\newcount\glyph_maxhpos
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
% \end{macro} \end{macro} \end{macro}
%
% \begin{macro}{\setglyph}
% \changes{1.916}{2001/01/06}{Added `set' to \package{fontdoc} text.
% (LH)}
% \begin{macro}{\gobble_glyph}
% The |\setglyph|\marg{name} command defines |\g-|\meta{name},
% unless |\g-|\meta{name} has already been defined.
%
% The reason |\g-|\meta{name} is defined before calling |\resetglyph|
% is to make it possible to refer to ``the glyph constructed so far''
% using |\width|\marg{name}, |\height|\marg{name}, etc.
% \begin{macrocode}
\def\setglyph#1{
\ifisglyph{\glyph_name_modifier{#1}}\then
\expandafter\gobble_glyph
\else
\x_cs\def{g-\glyph_name_modifier{#1}}{
{\the\glyph_width}{\the\glyph_height}
{\the\glyph_depth}{\the\glyph_italic}
{\the\glyph_map_commands}{\the\glyph_map_fonts}
}
\resetglyph{\glyph_name_modifier{#1}}
\fi
}
\long\def\gobble_glyph#1\endsetglyph{}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\setglyph[1]{%
\FD@tight@true
\Aheading{Set glyph `\typeset@glyph{#1}'}%
}
%
%\long\def\setglyph#1\endsetglyph{}
% \end{macrocode}
%
% LH 2003/01/05: A very useful trick, which unfortunately used to be
% undocumented, is to put kerning or variable assignment commands
% between |\setglyph| and the corresponding |\endsetglyph|. These
% commands will then only be executed if the glyph is being set by
% that |\setglyph|. Typical application: If \texttt{Aacutesmall}
% is being made by skrinking \texttt{Aacute}, then it is reasonable
% to make \texttt{Aacutesmall} kern like \texttt{Aacute} (modulo
% some scaling factor). If on the other hand \texttt{Aacutesmall}
% has already been set then there is less reason to believe
% \texttt{Aacutesmall} should kern like \texttt{Aacute} (a more
% probable guess is that it should kern like \texttt{Asmall}).
% \end{macro} \end{macro}
%
% \begin{macro}{\resetglyph}
% The |\resetglyph|\marg{name} command redefines |\g-|\meta{name},
% regardless of whether |\g-|\meta{name} has already been defined.
% \changes{1.923}{2002/10/20}{\cs{edef}ing \cs{glyphname}, for
% consistency with \cs{setslot}. In principle, this could break
% MTX files, but I doubt that it will. (LH)}
%
% \begin{macrocode}
%<*pkg>
\def\resetglyph#1{
\edef\glyphname{#1}
\glyph_width=0
\global\glyph_height=0
\global\glyph_depth=0
\global\glyph_italic=0
\glyph_voffset=0
\global\glyph_maxhpos=0
\global\glyph_map_commands={}
\global\glyph_map_fonts={}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\resetglyph[1]{%
\FD@tight@true
\Aheading{Reset glyph `\typeset@glyph{#1}'}}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endsetglyph}
% \begin{macro}{\endresetglyph}
% \begin{macrocode}
%<*pkg>
\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
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\let\endsetglyph=\FD@tight@false
\let\endresetglyph=\FD@tight@false
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\setscaledrawglyph}
% \changes{1.922}{2002/09/07}{Corrected typo: should test whether the
% \texttt{rawscale} integer exists, not whether the
% \texttt{i-rawscale} integer exists. (LH)}
% \begin{macro}{\setrawglyph}
% The |\setscaledrawglyph| has the syntax
% \begin{isyntax}
% |\setscaledrawglyph|\marg{glyph}\marg{font}\marg{design size}^^A
% \marg{scale}\penalty0\marg{slot}\penalty0\marg{width}\penalty0
% \marg{height}\penalty0\marg{depth}\penalty0\marg{italic}
% \end{isyntax}
% It is a generalized form of the old |\setrawglyph| command, which
% has the syntax
% \begin{isyntax}
% |\setrawglyph|\marg{glyph}\marg{font}\marg{design size}^^A
% \marg{slot}\penalty0\marg{width}\penalty0
% \marg{height}\penalty0\marg{depth}\penalty0\marg{italic}
% \end{isyntax}
% |\setrawglyph| is now syntactic sugar for the equivalent call of
% |\set|\-|scaled|\-|raw|\-|glyph|.
% \begin{macrocode}
%<*pkg>
\def\setrawglyph#1#2#3{
\setscaledrawglyph{#1}{#2}{#3}\one_thousand
}
% \end{macrocode}
%
% These commands are generated automatically, when an |.mtx| file is
% written out by |\afmtomtx|, |\pltomtx|, or |\mtxtomtx|.
%
% To illustrate the difference between |\setrawglyph| and the new
% |\set|\-|scaled|\-|raw|\-|glyph|, note that
% \begin{quote}
% |\setscaledrawglyph{fscaled}{xfont}{10pt}{800}{102}%|\\
% | {300}{600}{300}{40}|
% \end{quote}
% produces the same \texttt{fscaled} glyph as
% \begin{quote}
% |\setrawglyph{f}{xfont}{10pt}{102}{375}{750}{375}{50}|\\
% |\setglyph{fscaled} \glyph{f}{800} \endsetglyph|
% \end{quote}
%
% \begin{macrocode}
\def\setscaledrawglyph#1#2#3#4#5#6#7#8#9{
\if_undefined{g-\glyph_name_modifier{#1}}\then
\eval_expr{#4}
\ifnum \result=\one_thousand
\let\a_macro\identity_one
\else
\edef\a_macro##1{\saved_scale{\the\result}{##1}}
\fi
\eval_expr_to\a_count{#6}
\eval_expr_to\b_count{#7}
\eval_expr_to\c_count{#8}
\eval_expr_to\d_count{#9}
\ifisint{rawscale}\then
\e_count=\int{rawscale}
\multiply \a_count \e_count \l_rounded_thousandths\a_count
\multiply \b_count \e_count \l_rounded_thousandths\b_count
\multiply \c_count \e_count \l_rounded_thousandths\c_count
\multiply \d_count \e_count \l_rounded_thousandths\d_count
\edef\a_macro##1{\saved_scale{\the\e_count}{\a_macro{##1}}}
\fi
\x_cs\edef{g-\glyph_name_modifier{#1}}{
{\the\a_count}
{\the\b_count}
{\the\c_count}
{\the\d_count}
{\a_macro{\saved_raw{#2}{#5}{#1}}}
{\a_macro{\saved_mapfont{#2}{#3}}}
}
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\setrawglyph[8]{%
\Aheading{Glyph `\typeset@glyph{#1}'}
\Bheading{Taken from} slot $\TypesetIntegerExpression{#4}$ in
font \TypesetStringExpression{#2}%
}
\newcommand\setscaledrawglyph[9]{%
\Aheading{Glyph `\typeset@glyph{#1}'}
\Bheading{Taken from} slot $\TypesetIntegerExpression{#5}$ in
font \TypesetStringExpression{#2} \ConditionallyScaled{#4}%
}
%
%\def\setrawglyph#1#2#3#4#5#6#7#8{}
%\def\setscaledrawglyph#1#2#3#4#5#6#7#8#9{}
% \end{macrocode}
% \end{macro}\end{macro}
%
% \begin{macro}{\setscalednotglyph}
% \changes{1.917}{2001/03/13}{This macro should set
% \cs{g-\meta{glyph}-not}, not \cs{g-\meta{glyph}}. (LH)}
% \changes{1.922}{2002/09/07}{Corrected typo: should test whether
% the \texttt{rawscale} integer exists, not whether the
% \texttt{i-rawscale} integer exists. (LH)}
% \begin{macro}{\setnotglyph}
% The |\setscalednotglyph| command has the same syntax as the
% |\set|\-|scaled|\-|raw|\-|glyph| command, i.e.,
% \begin{isyntax}
% |\setscalednotglyph|\marg{glyph}\marg{font}\marg{design size}^^A
% \marg{scale}\penalty0\marg{slot}\penalty0\marg{width}\penalty0
% \marg{height}\penalty0\marg{depth}\penalty0\marg{italic}
% \end{isyntax}
% It is a generalized form of the old |\setnotglyph| command, which
% has the syntax
% \begin{isyntax}
% |\setnotglyph|\marg{glyph}\marg{font}\marg{design size}^^A
% \marg{slot}\penalty0\marg{width}\penalty0\marg{height}\penalty0
% \marg{depth}\penalty0\marg{italic}
% \end{isyntax}
% |\setnotglyph| is now syntactic sugar for the equivalent call of
% |\set|\-|scaled|\-|not|\-|glyph|.
% \begin{macrocode}
%<*pkg>
\def\setnotglyph#1#2#3{
\setscalednotglyph{#1}{#2}{#3}\one_thousand
}
% \end{macrocode}
%
% Note that only the \meta{glyph}, \meta{width}, \meta{height},
% \meta{depth}, and \meta{italic} parameters are used. The reason for
% having the other parameters is that |\set|\-|scaled|\-|not|\-^^A
% |glyph| commands can be converted to |\set|\-|scaled|\-|raw|\-^^A
% |glyph| commands when a font is reencoded. Therefore all the
% information must be present, even if it is not used by the main
% definition.
%
% To think about (LH 2000/03/02): Perhaps the \meta{mapcommands} field
% of a \texttt{-not}-glyph should contain a |\glyphwarning|, just in
% case anyone tries to use one?
% \begin{macrocode}
\def\setscalednotglyph#1#2#3#4#5#6#7#8#9{
\if_undefined{g-\glyph_name_modifier{#1}-not}\then
\eval_expr_to\a_count{#6}
\eval_expr_to\b_count{#7}
\eval_expr_to\c_count{#8}
\eval_expr_to\d_count{#9}
\ifisint{rawscale}\then
\e_count=\int{rawscale}
\multiply \a_count \e_count \l_rounded_thousandths\a_count
\multiply \b_count \e_count \l_rounded_thousandths\b_count
\multiply \c_count \e_count \l_rounded_thousandths\c_count
\multiply \d_count \e_count \l_rounded_thousandths\d_count
\fi
\x_cs\edef{g-\glyph_name_modifier{#1}-not}{
{\the\a_count}
{\the\b_count}
{\the\c_count}
{\the\d_count}
{}{}
}
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\setnotglyph[8]{%
\Aheading{Pseudoglyph `\typeset@glyph{#1-not}'}%
}
\newcommand\setscalednotglyph[9]{%
\setnotglyph{#1}{#2}{#3}{#5}{#6}{#7}{#8}{#9}%
}
%
%\let\setnotglyph=\setrawglyph
%\let\setscalednotglyph=\setscaledrawglyph
% \end{macrocode}
% \end{macro}\end{macro}
%
% \begin{macro}{\unsetglyph}
% The |\unsetglyph|\marg{name} command makes |\g-|\meta{name}
% undefined.
%
% \begin{macrocode}
%\def\unsetglyph#1{\x_cs\let{g-#1}\x_relax}
%\newcommand\unsetglyph[1]{%
% \Aheading{Unset glyph `\typeset@glyph{#1}'}}
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Glyph commands}
%
% The \meta{glyph commands} are:
% \changes{1.908}{1999/08/22}{Glyph commands avoid \cs{edef}ing old
% contents of \cs{glyph_map_commands} and \cs{glyph_map_fonts}. (LH)}
% \begin{macro}{\glyph}
% |\glyph|\marg{glyph}\marg{scale}
% \changes{1.900}{1999/02/08}{Avoids scaling by 1000. (LH)}
%
% \begin{macrocode}
%<*pkg>
\def\glyph#1#2{
\glyph_parameter\glyph_metrics{#1}
\eval_expr_to\e_count{#2}
\ifnum \e_count=\one_thousand
\edef\a_macro{\mapcommands{#1}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
\edef\a_macro{\mapfonts{#1}}
\else
\multiply \a_count \e_count \l_rounded_thousandths\a_count
\multiply \b_count \e_count \l_rounded_thousandths\b_count
\multiply \c_count \e_count \l_rounded_thousandths\c_count
\multiply \d_count \e_count \l_rounded_thousandths\d_count
\edef\a_macro{\saved_scale{\the\e_count}{\mapcommands{#1}}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
\edef\a_macro{\saved_scale{\the\e_count}{\mapfonts{#1}}}
\fi
\advance \glyph_width \a_count
\advance \b_count \glyph_voffset
\ifnum \glyph_height<\b_count \global\glyph_height=\b_count \fi
\advance \c_count -\glyph_voffset
\ifnum \glyph_depth<\c_count \global\glyph_depth=\c_count \fi
\global\glyph_italic=\d_count
\global\glyph_map_fonts\expandafter{
\the\expandafter\glyph_map_fonts \a_macro
}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\glyph[2]{%
\Bheading{Glyph} `\typeset@glyph{#1}' \ConditionallyScaled{#2}%
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\glyphrule}
% |\glyphrule|\marg{width}\marg{height}
%
% \begin{macrocode}
%<*pkg>
\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\a_macro{\saved_rule{\the\b_count}{\the\c_count}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\glyphrule[2]{%
\Bheading{Rule} $\TypesetIntegerExpression{#1}$ by
$\TypesetIntegerExpression{#2}$%
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\glyphspecial}
% \begin{macro}{\glyphwarning}
% |\glyphspecial|\marg{string}\\
% |\glyphwarning|\marg{string}
%
% \begin{macrocode}
%<*pkg>
\def\glyphspecial#1{
\edef\a_macro{\saved_special{#1}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
}
\def\glyphwarning#1{
\edef\a_macro{\saved_warning{#1}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\glyphspecial[1]{%
\Bheading{Special} `\TypesetStringExpression{#1}'}
\newcommand\glyphwarning[1]{%
\Bheading{Warning} `\TypesetStringExpression{#1}'}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\movert}
% \changes{1.903}{1999/05/20}{Added update of \cs{glyph_maxhpos}. (LH)}
% \begin{macro}{\moveup}
% |\movert|\marg{xoffset}\\
% |\moveup|\marg{yoffset}
%
% \begin{macrocode}
%<*pkg>
\def\movert#1{
\eval_expr{#1}
\ifnum \glyph_maxhpos<\glyph_width
\global\glyph_maxhpos\glyph_width
\fi
\ifnum 0=\result \else
\advance\glyph_width by \result
\edef\a_macro{\saved_movert{\the\result}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\moveup#1{
\eval_expr{#1}
\ifnum\result=0\else
\advance\glyph_voffset by \result
\edef\a_macro{\saved_moveup{\the\result}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\movert[1]{\Bheading{Rt}~$\TypesetIntegerExpression{#1}$}
\newcommand\moveup[1]{\Bheading{Up}~$\TypesetIntegerExpression{#1}$}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\push}
% \changes{1.907}{1999/08/02}{Removed the \cs{edef}. (LH)}
% \begin{macro}{\pop}
% \changes{1.903}{1999/05/20}{Added update of \cs{glyph_maxhpos}. (LH)}
% \changes{1.907}{1999/08/02}{Removed the \cs{edef}. (LH)}
% \begin{macrocode}
%<*pkg>
\def\push{
\bgroup
\global\glyph_map_commands\expandafter{
\the\glyph_map_commands \saved_push
}
}
% \end{macrocode}
% \begin{macrocode}
\def\pop{
\ifnum \glyph_maxhpos<\glyph_width
\global\glyph_maxhpos\glyph_width
\fi
\egroup
\global\glyph_map_commands\expandafter{
\the\glyph_map_commands \saved_pop
}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\push{\Bheading{Push}}
\newcommand\pop{\Bheading{Pop}}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\resetwidth}
% \begin{macro}{\resetheight}
% \begin{macro}{\resetdepth}
% \begin{macro}{\resetitalic}
% |\resetwidth|\marg{width}\\
% |\resetheight|\marg{height}\\
% |\resetdepth|\marg{depth}\\
% |\resetitalic|\marg{italic}
%
% \begin{macrocode}
%<*pkg>
\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}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\resetwidth[1]{%
\Bheading{Reset width to $\TypesetIntegerExpression{#1}$}%
}
\newcommand\resetheight[1]{%
\Bheading{Reset height to $\TypesetIntegerExpression{#1}$}%
}
\newcommand\resetdepth[1]{%
\Bheading{Reset depth to $\TypesetIntegerExpression{#1}$}%
}
\newcommand\resetitalic[1]{%
\Bheading{Reset italic to $\TypesetIntegerExpression{#1}$}%
}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\glyphpcc}
% Some syntactic sugar: |\glyphpcc| could do with optimization.
% \begin{quote}
% |\glyphpcc|\marg{glyph}\marg{xoffset}\marg{yoffset}
% \end{quote}
% \changes{1.925}{2003/05/28}{Added check that the glyph used is
% defined; we get an ugly error if it isn't. (LH)}
% \changes{1.932}{2005/06/17}{Changed error message to warning when a
% corresponding notglyph exists. (LH) This deals with an issue
% regarding composites in fonts which have been reencoded to
% something not a superset of \texttt{8a}.}
%
% \begin{macrocode}
%<*pkg>
\def\glyphpcc#1#2#3{
\ifisglyph{\glyph_name_modifier{#1}}\then
\push
\movert{#2}
\moveup{#3}
\glyph{\glyph_name_modifier{#1}}{\one_thousand}
\pop
\else\ifisglyph{\glyph_name_modifier{#1}-not}\then
\fontinstwarning{\string\glyphpcc}{
Base~glyph~`\glyph_name_modifier{#1}'~not~appended,\messagebreak
because~it~is~so~far~unencoded~in~the~glyph~base
}
\else
\fontinsterror{\string\glyphpcc}{
Base~glyph~not~set.\messagebreak
This~could~be~a~sign~that~the~AFM~file~is~buggy
}\error_help_a
\fi\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\glyphpcc#1#2#3{
\push
\movert{#2}
\moveup{#3}
\glyph{#1}{1000}
\pop
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\glyphbboxright}
% \changes{1.903}{1999/05/20}{Macro added. (LH)}
% The |\glyphbboxright| command is a valid integer expression, but
% its value is only meaningful inside a |\setglyph| \textellipsis\
% |\endsetglyph| or |\resetglyph| \textellipsis\ |\endresetglyph|
% structure. There its value is almost the horizontal position of
% the right edge of the bounding box for the glyph constructed so
% far---in reality it is the greatest horizontal offset reached so
% far.
%
% \begin{macrocode}
%\def\glyphbboxright{\max\glyph_width\glyph_maxhpos}
%<*doc>
\DeclareRobustCommand\glyphbboxright{%
\gdef\FD@expression{\protect\mathrm{glyphbboxright}}
\global\chardef\FD@priority=\tw@
\global\FD@bracket@level=\z@
\FD@evaluate@false
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\samesize}
% \changes{1.903}{1999/05/20}{Added behaviour for nonexistent glyph
% (based on a suggestion from Hilmar Schlegel) and fixed typo in
% \package{fontdoc}. (LH)}
% |\samesize|\marg{glyph}
%
% \begin{macrocode}
%<*pkg>
\def\samesize#1{
\if_undefined{g-\glyph_name_modifier{#1}}\then
\resetwidth{\glyphbboxright}
\else
\expandafter\expandafter\expandafter
\same_size\csname g-\glyph_name_modifier{#1}\endcsname
\fi
}
\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
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\samesize[1]{%
\Bheading{Reset dimensions to those of `\typeset@glyph{#1}'.}%
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifisglyph}
% The control flow command:
% \changes{1.923}{2002/10/20}{Using \cs{if_defined}. (LH)}
% \begin{macrocode}
%\def\ifisglyph#1\then{\if_defined{g-#1}\then}
% \end{macrocode}
% \changes{1.911}{1999/11/30}{\protect\protect\protect\Module{misc}
% definition added. (LH)}
% |\ifisglyph| evaluates to false in \Module{misc}, since this avoids
% uses of various metric integer expressions (such as |\width|,
% |\height|, etc.) that are not defined there.
% \begin{macrocode}
%\def\ifisglyph#1\then{\generic@if{glyph \typeset@glyph{#1} set}}
%\def\ifisglyph#1\then{\iffalse}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifareglyphs}
% \changes{1.917}{2001/03/17}{Macro added. (LH)}
% The |\ifareglyphs| command test if all glyphs in a comma-separeted
% list of glyphs are set. The syntax is
% \begin{quote}
% |\ifareglyphs|\marg{glyph list}|\then|
% \end{quote}
% The implementation relies on that |\if_true| and |\if_false| do not
% count when \TeX\ is skipping text that is balanced with respect to
% |\if|s and |\fi|s.
% \begin{macrocode}
%<*pkg>
\def\ifareglyphs#1\then{
\process_csep_list{\if_is_glyph}#1,\process_csep_list,
\if_true
}
\def\if_is_glyph#1{
\if_undefined{g-#1}\then \expandafter\if_false \fi
}
%
%\let\ifareglyphs=\ifisglyph
%<*doc>
\def\ifareglyphs#1\then{%
\generic@if{all glyphs in \FD@typeset@string@set{#1} are set}%
}
%
% \end{macrocode}
% \end{macro}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Converting an ETX file to a (V)PL file}
%
% \subsection{Lowest-level user interface}
%
% \DescribeMacro{\etxtovpl}
% The macro:
% \begin{quote}
% |\etxtovpl|\marg{encoding list}\marg{vplfile}
% \end{quote}
% writes a virtual font (as a virtual property list) with the
% encoding specified by the items in the \meta{encoding list},
% which typically are names of ETX files.
% (This macro is called by |\installfont|.)
%
% \DescribeMacro{\etxtopl}
% The macro:
% \begin{quote}
% |\etxtopl|\marg{encoding list}\marg{plfile}
% \end{quote}
% writes a font (as a property list) with the encoding
% specified by the items in the \meta{encoding list},
% which typically are names of ETX files.
% (This macro is called by |\installrawfont|.)
%
% \multchanges{\cs{etxtovpl}\cs{etxtopl}}{1.923}{2002/10/24}{The
% first argument of these macros is now a comma-separated list
% of ETX files, and the items may be subjected to modifier
% clauses. (LH)}
%
% \begin{macro}{\etxtovpl}
% \changes{1.923}{2002/10/25}{The program is called \texttt{vptovf},
% not \texttt{vpltovf}. (LH)}
% \begin{macro}{\etxtopl}
% \begin{macrocode}
%<*pkg>
\def\etxtovpl#1#2{{
\def\vpl_extension{vpl}
\def\vpl_title{COMMENT}
\def\vpl_font{virtual~font}
\def\vpl_Font{Virtual~font}
\def\vpl_call{\string\etxtovpl{#1}{#2}}
\def\vpl_to_vf##1{vptovf~##1.vpl~##1.vf~##1.tfm}
\a_toks={}
\process_csep_list\make_inputetx #1,\process_csep_list,
\expandafter\etx_to_font \expandafter{\the\a_toks}{#2}
}}
\def\etxtopl#1#2{{
\def\vpl_extension{pl}
\def\vpl_title{COMMENT}
\def\vpl_font{font}
\def\vpl_Font{Font}
\def\vpl_call{\string\etxtopl{#1}{#2}}
\def\vpl_to_vf##1{pltotf~##1.pl~##1.tfm}
\_including_map_false
\global\rawfont_scaling=-\p@
\a_toks={}
\process_csep_list\make_inputetx #1,\process_csep_list,
\expandafter\etx_to_font \expandafter{\the\a_toks}{#2}
}}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{switch}{_including_map_}
% \changes{1.900}{1998/10/02}{New switch that can inhibit writing of
% VPL-specific properties. (LH)}
% The v\,1.5 method of controlling whether \texttt{MAP} and
% \texttt{MAPFONT} properties should be written requires that some
% code is put in an awkward place (in |\make_mapfonts| rather than
% |\make_characters|). As the code was being reorganised anyway, it
% seemed best to let a switch control this instead. If
% |\if_including_map_| is true, \texttt{MAP} and \texttt{MAPFONT}
% properties are written to the file (which should be a VPL), if it is
% false then they are not written to the file (which is then a normal
% PL).
% \begin{macrocode}
\newif\if_including_map_
\_including_map_true
% \end{macrocode}
% \end{switch}
%
% \begin{macro}{\make_inputetx}
% The |\make_inputetx| macro takes a single argument that should have
% the form
% \begin{quote}
% \meta{file name root}\meta{optional modifiers}
% \end{quote}
% as explained in the comments to |\input_mtx_file|. The effect of
% this macro is to append some commands (usually
% |\inputetx|\marg{file name root}) to |\a_toks|. This may however
% change if some clause in the \meta{optional modifiers} redefines
% |\a_macro|.
% \changes{1.923}{2002/10/24}{Macro added. (LH)}
% \begin{macrocode}
\def\make_inputetx#1{
\def\a_macro{\noexpand\inputetx{\file_name}}
\get_file_name #1~{}~\par
\edef\a_macro{\a_macro}
\a_toks=\expandafter{ \the\expandafter\a_toks \a_macro}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\IFKW-mtxasetx}
% The \texttt{mtxasetx} modifier clause causes the \meta{encoding
% list} item in question to be input using |\input_mtx_as_etx| rather
% than |\inputetx|. This makes it possible to use the |\setrawglyph|
% and |\setscaledrawglyph| commands in an MTX file as a poor
% substitute for a proper ETX file. This is sometimes useful for
% making proofs.
% \changes{1.923}{2002/10/24}{Macro added. (LH)}
% \begin{macrocode}
\x_cs\def{IFKW-mtxasetx}{
\def\a_macro{\noexpand\input_mtx_as_etx{\file_name}}
\get_keyword
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\etx_to_font}
% |\etx_to_font|\marg{encoding commands}\marg{fontfile} makes
% a (V)PL file whose encoding is specified by the \meta{encoding
% commands}. These are usually just one or a few |\inputetx|
% commands, as the specification of an encoding usually requires much
% more code than is convenient to provide as an argument.
% \changes{1.923}{2002/10/24}{Made the first argument a list of
% commands. Renamed \cs{vpl_caller} to \cs{vpl_call}; it is now
% assumed to contain the arguments as well. (LH)}
% \begin{macrocode}
\def\etx_to_font#1#2{
\make_assignments{#1}
\open_out{#2.\vpl_extension}
\top_of_pl_hook
\out_line{(\vpl_title\space\vpl_font\space
#2~created~by~fontinst~v\fontinstversion)}
\out_line{}
\out_line{(COMMENT~Filename:~#2.\vpl_extension)}
\out_line{(COMMENT~Created~by:~tex~\jobname)}
\out_line{(COMMENT~Created~using:~\vpl_call)}
\out_line{}
\out_line{(COMMENT~This~file~can~be~turned~into~a~\vpl_font\space
with)}
\out_line{(COMMENT~\vpl_to_vf{#2})}
\out_line{}
\out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
\out_line{}
\make_header{#1}
\if_including_map_ \make_mapfonts{#1} \fi
\make_fontdimens{#1}
\make_ligtable{#1}
\make_characters{#1}
\make_tidy{#1}
\out_line{}
\out_line{(COMMENT~END~OF~FILE~#2.\vpl_extension)}
\close_out{\vpl_Font}
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\pre_first_etx_pass_hook}
% \begin{macro}{\pre_second_etx_pass_hook}
% \begin{macro}{\pre_third_etx_pass_hook}
% \begin{macro}{\pre_fourth_etx_pass_hook}
% \begin{macro}{\post_first_etx_pass_hook}
% \begin{macro}{\post_second_etx_pass_hook}
% \begin{macro}{\post_third_etx_pass_hook}
% \begin{macro}{\post_fourth_etx_pass_hook}
% \begin{macro}{\tidying_up_hook}
% \multchanges{\cs{pre_first_etx_pass_hook}^^A
% \cs{pre_second_etx_pass_hook}\cs{pre_third_etx_pass_hook}^^A
% \cs{pre_fourth_etx_pass_hook}\cs{post_first_etx_pass_hook}^^A
% \cs{post_second_etx_pass_hook}\cs{post_third_etx_pass_hook}^^A
% \cs{post_fourth_etx_pass_hook}\cs{tidying_up_hook}}{1.900}^^A
% {1998/09/30}{ETX-to-VPL hooks added. (LH)}
% \begin{macro}{\top_of_pl_hook}
% \changes{1.912}{2000/01/29}{Property list hook added. (LH)}
% As the |\etxtovpl| and |\etxtopl| macros are the
% lowest-level interfaces to what they do that are available in
% \package{fontinst} and as the amount of code they execute is really
% quite large, I suspect that users may occationally have need of
% some robust mechanism for inserting extra code at well specified
% positions. Such a mechanism is provided by the following hooks:
% \begin{macrocode}
\let\pre_first_etx_pass_hook\x_relax
\let\pre_second_etx_pass_hook\x_relax
\let\pre_third_etx_pass_hook\x_relax
\let\pre_fourth_etx_pass_hook\x_relax
\let\post_first_etx_pass_hook\x_relax
\let\post_second_etx_pass_hook\x_relax
\let\post_third_etx_pass_hook\x_relax
\let\post_fourth_etx_pass_hook\x_relax
\let\tidying_up_hook\x_relax
\let\top_of_pl_hook\x_relax
% \end{macrocode}
% The first nine are executed at the positions of the ETX-to-VPL
% file generation that their name indicate. |\top_of_pl_hook| is
% slightly different---it is executed right after a PL or VPL file
% is opened for writing. Thus it is also used by the MTX-to-PL system.
%
% To include code in one of them, one should write things like
% \begin{quote}
% |\add_to\pre_first_etx_pass_hook|\marg{extra code}
% \end{quote}
% I (LH) have the following in my \texttt{fontinst.rc} file\relax
% \SortIndex{fontinst.rc file}{\texttt{fontinst.rc} file}
% \begin{quote}
% |\add_to\top_of_pl_hook{\out_line{(COMMENT~-*-Text-*-)}}|
% \end{quote}
% Without it, my text editor annoys me by assuming that \texttt{.pl}
% stands for Perl.
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
%
%
% \subsection{Glyph to slot assignments}
%
% \changes{1.900}{1998/12/06}{New method of storing slot assignments.
% (LH)}
% The way \package{fontinst} has traditionally kept track
% of which glyph goes to which slot---information which is needed when
% writing the |LIGTABLE| in a (V)PL, for |\nextlarger|, and for the
% varchar commands---is by storing the slot number in the integer
% whose name is the name of the glyph. There are two main problems with
% this implementation: (i)~If a user sets an integer which happens to
% have the same name as a glyph that is not assigned to any slot, then
% kerns for that unused glyph might be written to the file, accidentally
% creating a kerning pair where there should be none. (ii)~It is only
% possible to store one slot number per glyph, so if one uses the same
% glyph for several slots then \package{fontinst} can only write kerns
% (and ligatures) for one of the occurences, despite the fact that all
% occurences have the same typographical need for them. These problems
% do only occur for glyphs on the right side of a ligature/kerning
% pair, but they are still serious enough. This part of
% \package{fontinst} has therefore been reimplemented.
%
% \changes{1.910}{1999/11/04}{Changed the way slot numbers are stored
% in \cs{slots-}\meta{glyph} control sequences. (LH)}
% The new implementation does not use integers, instead it uses a new
% family of macros with names on the form |\slots-|\meta{glyph}^^A
% \describecsfamily{slots-\meta{glyph}}. These macros expand to
% sequences of |\do|\thinspace\meta{character}, where \meta{character}
% is a category 12 (other) token whose character code equals the slot
% number.
%
% In the entire space of such names, each slot should be mentioned
% at most once, with one exception, namely the slot which serves as
% right boundary marker, which may occur twice (once for the glyph
% which actually is assigned to the slot and once for the right boundary
% marker glyph). To detect whether there is a collision between these two
% uses of the slot, the right boundary marker glyph uses |\rboundary_do|
% instead of |\do| and the glyph whose slot serves as boundarychar uses
% |\rbserver_do| instead of |\do|. By redefining these two control
% sequences to generate a warning message when appropriate, the occurence
% of such a collision can be brought to the user's attention.
%
% \changes{1.900}{1998/12/11}{Added compability code for the old
% interface for boundary ligatures and kerns. (LH)}
% As it turned out to not be such a big deal, some extra code (protected
% by a \package{docstrip} switch called \Module{boundaryCompability})
% that makes \package{fontinst} compatible with the previous syntax for
% boundary handling has been included. I don't recommend using
% it though, since it makes \package{fontinst} store almost all slot
% numbers in two places.
%
%
% \begin{macro}{\make_assignments}
% \begin{macrocode}
\def\make_assignments#1{
\let\do_slot=\assign_slot
\let\end_do_slot=\end_assign_slot
\def\do_boundary{\bgroup
\let\makerightboundary=\bad_makerightboundary
}
\let\endsetleftboundary=\egroup
\let\makerightboundary=\assign_rboundary
\pre_first_etx_pass_hook
#1
\post_first_etx_pass_hook
\let\end_do_slot=\empty_command
\let\do_boundary=\x_relax
\let\endsetleftboundary=\x_relax
\let\makerightboundary=\gobble_one
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\assign_slot}
% \begin{macro}{\end_assign_slot}
% \changes{1.907}{1999/08/20}{Slots are not assigned to glyphs that
% do not exist. (LH)}
% |\assign_slot| begins the assignment of a slot to a glyph.
% |\end_assign_slot| completes it. In the time between these two,
% some information is stored in |\a_toks|, so that it can be
% modified by an intervening |\makerightboundary| (which is then
% |\assign_rboundary|).
%
% Note that the code below will not reset |\lccode0|. The value of
% this register should be considered uncertain while a ligful PL
% or VPL file is written, i.e., in ETX files.
% \SortIndex{lccode0}{\cs{lccode\,0} register\encapchar usage}
% \begin{macrocode}
\def\assign_slot{\a_toks={\do}}
\begingroup
\catcode0=12
\gdef\end_assign_slot{
\ifisglyph\slot_name\then
\lccode0=\slot_number
\lowercase{
\expandafter\add_to
\csname slots-\slot_name\expandafter\endcsname
\expandafter{\the\a_toks^^@}
}
% \x_resetint\slot_name\slot_number
\fi
}
% \end{macrocode}
% \end{macro}\end{macro}
%
%
% \begin{macro}{\assign_rboundary}
% \begin{macro}{\bad_makerightboundary}
% |\assign_rboundary| is what |\makerightboundary| is when it is
% assigning a slot to act as right boundary marker.
%
% |\bad_makerightboundary| is what |\makerightboundary| temporarily
% gets set to between |\setleftboundary| and |\endsetleftboundary|.
% \begin{macrocode}
\gdef\assign_rboundary#1{
\lccode0=\slot_number
\lowercase{\x_cs\add_to{slots-#1}{\rboundary_do^^@}}
\x_setint{\percent_char boundarychar}\slot_number
\a_toks={\rbserver_do}
}
\endgroup
\def\bad_makerightboundary#1{
\errhelp={The~left~boundary~is~not~a~slot,~so~it~cannot~serve~
as~right~boundary.}
\errmessage{Incorrect~use~of~\string\makerightboundary}
}
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\get_slot_num}
% \changes{1.910}{1999/11/04}{Removed redefinition of \cs{do} to
% \cs{gobble_one} from temporary definition of \cs{do}, since a
% \cs{slots-} list usually contains only one or two elements
% anyway. (LH)}
% It is sometimes necessary to get the number of an arbitrary slot
% given only the name of the glyph which has been assigned to the
% slot. In such situations, the call
% \begin{quote}
% |\get_slot_num{|\meta{glyph}|}|
% \end{quote}
% will set |\result| to the number of one such slot if the glyph has
% been assigned to some slot, or set |\result| to minus one if the glyph
% has not been assigned to a slot.
% \begin{macrocode}
\def\get_slot_num#1{
%<*!boundaryCompability>
\global\result=-1
\bgroup
\def\do{\global\result=`}
\let\rbserver_do=\do
\let\rboundary_do=\gobble_one
\csname slots-#1\endcsname
\egroup
%!boundaryCompability>
%<*boundaryCompability>
\ifisint{#1}\then
\global\result=\int{#1}
\else
\global\result=-1
\fi
\x_relax
%
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\ifisinslot}
% The call |\ifisinslot|\marg{glyph}\marg{slot}|\then| can be used to
% test whether glyph \meta{glyph} has been assigned to slot \meta{slot}.
% Both then-part and else-part of the conditional will however be
% ignored when the ETX file is read the first time, since the
% assignment of glyph to slots need not have been completed yet.
% \begin{macrocode}
\def\ifisinslot#1#2\then{
\ifx \makerightboundary\gobble_one
% \end{macrocode}
% This is used to test if the ETX file is being read in for the first
% time. It is a bit hacky, but it is efficient.
% \begin{macrocode}
\eval_expr{#2}
\begingroup
\def\do##1{\ifnum `##1=\result \let\do=\gobble_one \fi}
\def\rbserver_do{\do}
\let\rboundary_do=\gobble_one
\csname slots-#1\endcsname
\expandafter\endgroup
\ifx \do\gobble_one
\expandafter\expandafter \expandafter\if_true
\else
\expandafter\expandafter \expandafter\if_false
\fi
\else
\expandafter\gobble_if
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\ifisinslot#1#2\then{%
\generic@if{glyph \typeset@glyph{#1} assigned to slot
$\TypesetIntegerExpression{#2}$}%
}
%
% \end{macrocode}
% \end{macro}
%
%
% \subsection{The header, mapfonts, and fontdimens}
%
% \changes{1.913}{2000/02/26}{Using \cs{make_factor} for making PL
% reals, rather than \cs{afm_convert}+\cs{vpl_real}.
% \cs{scaled_design_size} replaced by new dimen \cs{mapfont_scaling} for
% determining mapfont atsize. (LH)}
%
% \begin{macro}{\mapfont_scaling}
% The |\mapfont_scaling| dimen is used for calculating how much a mapfont
% has been scaled, for use in \texttt{FONTAT} properties, and for
% selecting the correct mapfont. It is initialized to $1$.
% \begin{macrocode}
%<*pkg>
\newdimen\mapfont_scaling
\mapfont_scaling=1pt
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\rawfont_scaling}
% The |\rawfont_scaling| dimen is used for communicating the scaling
% that has been applied to a raw font---a font being installed using
% |\install|\-|rawfont|\penalty0---out to that macro. |\rawfont_|\-^^A
% |scaling| should always be globally assigned.
% \changes{1.913}{2000/03/21}{Dimen added. (LH)}
% \begin{macrocode}
\newdimen\rawfont_scaling
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\scaled_design_size}
% \begin{macro}{\afm_convert}
% The call
% \begin{quote}
% |\afm_convert|\meta{dimen}|=|\meta{integer expression}|;|
% \end{quote}
% 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 131\,pt, to try to minimize rounding errors.
%
% \begin{macrocode}
% \newdimen\scaled_design_size
% \end{macrocode}
% \begin{macrocode}
% \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
% }
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\vpl_real}
% \begin{macro}{\vpl_int}
% The commands |\vpl_real|\meta{dimen} and |\vpl_int|\meta{count} print
% a dimension and integer respectively in (V)PL syntax.
%
% \begin{macrocode}
\def\vpl_real#1{R~\expandafter\lose_measure\the#1}
\def\vpl_int#1{D~\the#1}
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% The count register |\boundary_char| has been removed, since
% the reimplementation of the left and right boundaries have drastically
% decreased the need to check which slot serves as the right boundary.
% Instead the integer |%boundarychar| (whose name cannot normally be typed)
% is used to store the number of this slot, but the user need never (and
% should not) access this integer directly. If the integer is not set
% then no slot serves as boundarychar.
% \changes{1.900}{1998/12/04}{\cs{boundary_char} count register
% removed. Right boundary slot number is now stored in the
% \texttt{\%boundarychar} integer instead. (LH)}
%
% \begin{macro}{\side_bearings}
% \begin{macro}{\curr_bearings}
% These two dimens are used by the letterspacing mechanism.
% \begin{macrocode}
\newdimen\side_bearings
\newdimen\curr_bearings
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\make_header}
% \begin{macrocode}
\def\make_header#1{
\global\font_count=0
\setdim{designsize}{10pt}
\a_dimen=\dim{designsize}
\out_line{(DESIGNSIZE~\vpl_real\a_dimen)}
\x_setstr{codingscheme}{UNKNOWN}
\out_line{(CODINGSCHEME~\str{codingscheme})}
%<*boundaryCompability>
\ifisint{boundarychar}\then
\x_setint{\percent_char boundarychar}{\int{boundarychar}}
\immediate\write16{Please~use~\string\setleftboundary\space
and/or~\string\makerightboundary^^J
instead~of~setting~the~boundarychar~integer.}
\fi
%
\ifisint{\percent_char boundarychar}\then
\a_count=\int{\percent_char boundarychar}
\out_line{(BOUNDARYCHAR~\vpl_int\a_count)}
\fi
\x_setint{letterspacing}{0}
\side_bearings=\make_factor{\int{letterspacing}}\half_point
\x_setint{minimumkern}{0}
\minimum_kern=\int{minimumkern}
\out_line{}
}
% \end{macrocode}
% \changes{1.900}{1999/01/20}{Removed test for no letterspacing. (LH)}
% \changes{1.900}{1999/01/20}{Made integer expression \cs{div} a
% dimen \cs{divide}. (LH)}
% \end{macro}
%
%
% \begin{macro}{\make_mapfonts}
% \begin{macrocode}
\def\make_mapfonts#1{
\let\saved_scale\vpl_scale
\let\saved_mapfont\vpl_mapfont
\let\do_slot=\do_mapfont
\pre_second_etx_pass_hook
#1
\post_second_etx_pass_hook
\out_line{}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_mapfont}
% |\do_mapfont| produces a |MAPFONT| entry for each font used by
% glyph |\slot_name|.
% \begin{macrocode}
\def\do_mapfont{
\ifisglyph\slot_name\then
\mapfonts\slot_name
\fi
}
% \end{macrocode}
% \end{macro}
%
% The following commands can be used in the \meta{mapfonts} glyph
% parameter.
%
% \begin{macro}{\vpl_scale}
% \begin{macrocode}
\def\vpl_scale#1#2{{
\mapfont_scaling=\make_factor{#1}\mapfont_scaling
#2
}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_mapfont}
% \changes{1.904}{1999/06/16}{Added \cs{record_usage}. (LH)}
% \changes{1.913}{2000/02/26}{Mapfont number control sequences are
% named \cs{\meta{scaling factor}pt-\meta{font}} instead of
% \cs{\meta{font}-\meta{scaling factor}pt}. They are also made
% \cs{mathchardef}s. (LH)}
% \begin{macrocode}
\def\vpl_mapfont#1#2{
\a_dimen=#2
\if_undefined{\the\mapfont_scaling-#1}\then
\global\x_cs\mathchardef{\the\mapfont_scaling-#1}=\font_count
\x_cs\xdef{f-\the\font_count}{\the\mapfont_scaling-#1}
\out_line{(MAPFONT~\vpl_int\font_count\space
(FONTNAME~#1)~
(FONTDSIZE~\vpl_real\a_dimen)~
(FONTAT~\vpl_real\mapfont_scaling))}
\record_usage{#1}
\global\advance\font_count by 1
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pl_mapfont}
% As PL files have no \texttt{MAPFONT} properties, the |\pl_mapfont|
% macro only needs to do one thing: copy the current value of
% |\mapfont_|\-|scaling| to |\rawfont_|\-|scaling|. This is necessary
% since if the raw font for which a ligful PL is being written has
% been scaled, then that scaling factor must be put in the appropriate
% place in the FD file entry, and the simplest way to determine this
% scaling factor is to execute the |\mapfonts| of some glyph in the
% font.
%
% Due to the fact that the second ETX file pass (that during which the
% \texttt{MAPFONT} properties are written) is skipped when a PL file
% is being written, the |\mapfonts| get executed during the fourth ETX
% file pass instead of the second. This works fine since the
% |\mapcommands| that are executed at that time when a VPL file is
% being written aren't needed for PL files.
% \changes{1.913}{2000/03/21}{Macro added. (LH)}
% \begin{macrocode}
\def\pl_mapfont#1#2{\global\rawfont_scaling=\mapfont_scaling}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\font_count}
% \begin{macro}{\next_mapfont}
% \begin{macro}{\prev_mapfont}
% \begin{macrocode}
\newcount\font_count
\newcount\next_mapfont
\newcount\prev_mapfont
% \end{macrocode}
% \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\make_fontdimens}
% This macro writes the \texttt{FONTDIMEN} property list. Note that
% there is a difference between fontdimen 1 and the others, in that
% fontdimen 1 is always in \texttt{pt}, not in the atsize-relative
% \texttt{FONTUNITS} unit that the others are. Nonetheless, they can
% both be treated the same here. This relies on (i) that 1000 denotes
% the factor 1, and (ii) that 1000 AFM units equals 1 fontunit.
% \begin{macrocode}
\def\make_fontdimens#1{
\out_line{(FONTDIMEN}
\a_count=1
\loop\ifnum 256>\a_count
\ifisint{fontdimen(\the\a_count)}\then
\out_lline{(PARAMETER~\vpl_int\a_count\space
R~\make_factor{\int{fontdimen(\the\a_count)}})}
\fi
\advance \a_count \@ne
\repeat
\out_lline{)}
\out_line{}
}
% \end{macrocode}
% \end{macro}
%
%
% \subsection{The ligtable}
%
% \begin{macro}{\make_ligtable}
% \changes{1.927}{2003/12/08}{Changed the surrounding group to
% \cs{begingroup} type. This helps contain errors that arise when
% the \cs{setslot}s and \cs{endsetslot}s aren't properly balanced.
% (LH)}
% \begin{macrocode}
\def\make_ligtable#1{
\begingroup
\out_line{(LIGTABLE}
% \let\do_slot=\bgroup
%<*boundaryCompability>
\def\do_slot{\bgroup
\ifisint{boundarychar}\then
\ifnum \int{boundarychar}=\slot_number
\def\vpl_liglabel{\out_liglabel\boundary_liglabel}
\fi
\fi
}
%
\let\end_do_slot=\vpl_kerning
\def\do_boundary{\bgroup \let\vpl_liglabel=\boundary_liglabel}
\let\endsetleftboundary=\vpl_kerning
\let\ligature=\vpl_ligature
\let\k=\vpl_kern
\let\rbserver_do=\vpl_rbserver_do
\let\rboundary_do=\vpl_rboundary_do
\pre_third_etx_pass_hook
#1
\post_third_etx_pass_hook
\out_lline{)}
\endgroup
\out_line{}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_rbserver_do}
% \begin{macro}{\vpl_rboundary_do}
% \begin{macro}{\wrn_rboundary_do}
% |\vpl_rbserver_do| and |\vpl_rboundary_do| are what |\rbserver_do|
% and |\rboundary_do| respectively are when a ligkern program is being
% written and no entry has yet been written for the boundarychar
% slot. |\wrn_rboundary_do| is what one of them will get set to
% afterwards, so that warnings are written when collisions between
% using the slot as a right boundary marker and using the slot for
% the actual glyph occur.
% \begin{macrocode}
\def\vpl_rbserver_do#1{
\do{#1}
\let\rboundary_do=\wrn_rboundary_do
}
\def\vpl_rboundary_do#1{
\do{#1}
\let\rbserver_do=\wrn_rboundary_do
}
\def\wrn_rboundary_do#1{
\do{#1}
\immediate\write16{Boundarychar~slot~usage~collision~in~
`\slot_name'~ligkern~program.}
}
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
%
% \begin{macro}{\vpl_ligature}
% |\vpl_ligature{|\meta{type}|}{|\meta{glyph}|}{|\meta{glyph}|}|
% produces a ligtable entry for glyph |\slot_name|.
%
% The double spaces in the |\out_lline| statement below might look
% strange, but |\number| will always gobble the first one.
% \begin{macrocode}
\def\vpl_ligature#1#2#3{
\get_slot_num{#3}
\ifnum -1=\result
\immediate\write16{Warning:~\string\ligature\space
for~unknown~slot~`#3'.}
\else
\x_cs\ifx{slots-#2}\x_relax
\immediate\write16{Warning:~\string\ligature\space
for~unknown~slot~`#2'.}
\else
\def\do##1{
\vpl_liglabel
\out_lline{(#1~D~\number`##1~\space\vpl_int\result)~
(COMMENT~#2~#3)}
}
\csname slots-#2\endcsname
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\vpl_kerning}
% |\vpl_kerning| writes out kerning instructions.
% \begin{macrocode}
\def\vpl_kerning{
\let\do=\vpl_kern_do
\csname~r-\slot_name\endcsname
\vpl_ligstop
\egroup
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_kern}
% |\vpl_kern|\,|\l-|\meta{name}\,|\|\meta{amount} writes out a |KRN|
% instruction.
%
% \changes{1.900}{1998/10/02}{Macro modified to avoid duplicate kerns.
% (LH)}
% |\vpl_kern| has been modified so that at most one
% \texttt{KRN} instruction is written for each (ordered) pair of
% characters. The idea is basically to make \package{fontinst} forget,
% until the end of |\vpl_kerning|, that the glyph for which |\vpl_kern|
% is being called has been assigned a slot, as this stops any more
% \texttt{KRN} instructions for that particular glyph from being
% written. |\vpl_kern| has also been modified so that it will not write
% out any \texttt{KRN} instructions for kerns whose absolute value is
% less than or equal to |\minimum_kern|. |\minimum_kern| gets set to
% the value of the integer \texttt{minimumkern} in |\make_header|. If
% the user has not set \texttt{minimumkern}, a default value of 0 will
% be supplied by \package{fontinst}.
%
% \changes{1.900}{1998/12/07}{Much of the code from \cs{vpl_kern} has
% been moved to \cs{vpl_kern_do}. (LH)}
% \changes{1.913}{2000/02/26}{Using a nested \cs{ifnum} construct to
% test the condition $\left\protect\vert
% \protect\mbox{\cs{a_count}}\right\protect\vert \quotechar >
% \protect\mbox{\cs{minimum_kern}}$. (LH)}
% \begin{macrocode}
\def\vpl_kern#1#2{
\edef\a_macro{\expandafter\gobble_three\string#1}
\a_count=\expandafter\gobble_one\string#2\x_relax
\ifnum \ifnum -\a_count>\a_count - \fi\a_count>\minimum_kern
\edef\b_macro{~R~\make_factor\a_count}
\csname slots-\a_macro\endcsname
\fi
\x_cs\let{slots-\a_macro}=\x_relax
}
% \end{macrocode}
% Observation (LH 1999/03/16): The above construction has the
% side-effect that a direct contradiction between a right boundary
% glyph and a glyph in the |%boundarychar| slot won't be detected if
% one of the items in contradiction is a kern less than or equal to
% |\minimum_kern|. Perhaps this should be changed (letting |\do| equal
% to |\gobble_one| would let the dectection mechanism work, but |\do|
% would have to be restored afterwards and it is doubtful if it is
% worth it).
% \end{macro}
%
%
% \begin{macro}{\vpl_kern_do}
% |\vpl_kern_do| is what |\do| is defined to be when kerns are written.
% \begin{macrocode}
\def\vpl_kern_do#1{
\vpl_liglabel
\out_lline{
(KRN~D~\number`#1~\b_macro)~
(COMMENT~\a_macro)
}
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\out_liglabel}
% \begin{macro}{\boundary_liglabel}
% \begin{macro}{\vpl_liglabel}
% |\out_liglabel| writes out a |LIGLABEL| instruction for a slot.
% |\boundary_liglabel| writes out a |LIGLABEL| instruction for the
% |BOUNDARYCHAR| ligkern program. |\vpl_liglabel| writes out the
% correct |LIGLABEL| instruction for the current ligkern program, if it
% is approriate.
%
% \begin{macrocode}
\def\out_liglabel{
\out_lline{(LABEL~\vpl_int\slot_number)~(COMMENT~\slot_name)}
\let\vpl_liglabel=\x_relax
\let\vpl_ligstop=\out_ligstop
}
\def\boundary_liglabel{
\out_lline{(LABEL~BOUNDARYCHAR)~(COMMENT~\slot_name)}
\let\vpl_liglabel=\x_relax
\let\vpl_ligstop=\out_ligstop
}
\let\vpl_liglabel=\out_liglabel
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\out_ligstop}
% \begin{macro}{\vpl_ligstop}
% |\vpl_ligstop| writes out a |LIGSTOP| instruction if appropriate.
% \begin{macrocode}
\def\out_ligstop{\out_lline{(STOP)}
\let\vpl_liglabel=\out_liglabel
\let\vpl_ligstop=\x_relax}
\let\vpl_ligstop=\x_relax
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% \subsection{The characters}
%
% \begin{macro}{\make_characters}
% \begin{macrocode}
\def\make_characters#1{
\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
\if_including_map_
\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
\else
\def\do_character_map{
\ifdim \rawfont_scaling=-\p@
\mapfonts\slot_name
\else
\let\do_character_map=\x_relax
\fi
}
\let\saved_mapfont\pl_mapfont
\let\saved_scale\vpl_scale
\fi
\pre_fourth_etx_pass_hook
#1
\post_fourth_etx_pass_hook
\egroup
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_character}
% \changes{1.913}{2000/03/10}{Negative italic corrections \emph{are}
% written to the (V)PL being generated. (LH)}
% \changes{1.927}{2004/07/13}{Added flag for emitting warning message
% when a glyph is missing. (LH) Requested by Werner Lemberg.}
% |\do_character| produces a character entry for glyph |\slot_name| in
% slot |\slot_number|.
%
% \begin{macrocode}
\def\do_character{
\if_undefined{g-\slot_name}\then
\ifisint{requireglyphs}\then
\fontinstwarning{ETX~to~(V)PL}{
Undefined~glyph~`\slot_name'~requested\message_break
for~slot~\the\slot_number\message_number}
\fi
\expandafter\gobble_setslot
\else
\ifx\slot_name\notdef_name\else
\out_line{(CHARACTER~\vpl_int\slot_number\space
(COMMENT~\slot_name)}
\glyph_parameter\glyph_metrics\slot_name
\a_dimen=\make_factor\a_count \p@
\do_character_sidebearings
\out_lline{(CHARWD~\vpl_real\a_dimen)}
\ifnum \z@=\b_count \else
\out_lline{(CHARHT~R~\make_factor\b_count)}
\fi
\ifnum \z@=\c_count \else
\out_lline{(CHARDP~R~\make_factor\c_count)}
\fi
\ifnum \z@=\d_count \else
\out_lline{(CHARIC~R~\make_factor\d_count)}
\fi
\do_character_map
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_character_sidebearings}
% \begin{macrocode}
\def\do_character_sidebearings{
\ifisint{\slot_name-spacing}\then
\curr_bearings=\make_factor{\int{\slot_name-spacing}}\half_point
\else
\curr_bearings=\side_bearings
\fi
\advance\a_dimen by 2\curr_bearings
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_character_map}
% \begin{macrocode}
\def\do_character_map{
\global\prev_mapfont=0
\out_lline{(MAP}
\ifdim 0pt=\curr_bearings
\mapcommands\slot_name
\else
\out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
\mapcommands\slot_name
\out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
\fi
\out_llline{)}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_character_no_letterspacing}
% LH 1999/03/27: This is an alternative version of |\do_character|
% which I think is now antiquated. It used to have an advantage over
% |\do_character| in that it did not do any letterspacing (in v\,1.5,
% that was good since |\do_character| used to write code for
% letterspacing to the VPL regardless of whether is was needed or
% not), but that advantage is gone since |\do_character_map| is now
% a bit less stupid than it used to be.
%
% For the record, I don't think there ever was a user interface for
% using this macro instead of |\do_character|, but I suspect there
% are plenty of people around who have hacked it into being used.
%
% With v\,1.913 I commented it out completely, since I didn't feel
% like updating the calls to |\afm_convert|.
% \begin{macrocode}
%<*obsolete>
% \def\do_character_no_letterspacing{
% \x_cs\ifx{g-\slot_name}\x_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
% }
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\gobble_setslot}
% \begin{macrocode}
\long\def\gobble_setslot#1\endsetslot{\endsetslot}
% \end{macrocode}
% \changes{1.901}{1999/03/27}{Made \cs{gobble_setslot} a \cs{long}
% macro. (LH)}
% \end{macro}
%
% \begin{macro}{\end_do_character}
% \begin{macrocode}
\def\end_do_character{
\ifisglyph\slot_name\then
\out_lline{)}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\notdef_name}
% \begin{macrocode}
\def\notdef_name{.notdef}
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Slot commands that put things in a character property list}
%
% Here follows the active definitions for those slot commands that
% causes things to be put in |CHARACTER| property lists.
%
% \begin{macro}{\vpl_nextlarger}
% |\vpl_nextlarger|\marg{name} produces a |NEXTLARGER| entry.
% \begin{macrocode}
\def\vpl_nextlarger#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_lline{(NEXTLARGER~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\nextlarger\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_varchar}
% \begin{macro}{\end_vpl_varchar}
% |\vpl_varchar| \meta{varchar commands} |\end_vpl_varchar| produces
% a |VARCHAR| entry.
%
% \begin{macrocode}
\def\vpl_varchar{\out_lline{(VARCHAR}}
% \end{macrocode}
% \begin{macrocode}
\def\end_vpl_varchar{\out_llline{)}}
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% \begin{macro}{\vpl_vartop}
% \begin{macrocode}
\def\vpl_vartop#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_llline{(TOP~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\vartop\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_varmid}
% \begin{macrocode}
\def\vpl_varmid#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_llline{(MID~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\varmid\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_varbot}
% \begin{macrocode}
\def\vpl_varbot#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_llline{(BOT~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\varbot\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_varrep}
% \begin{macrocode}
\def\vpl_varrep#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_llline{(REP~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\varrep\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Saved map commands}
%
% The following commands (and |\vpl_scale|, which is defined above) can
% be used in the \meta{mapcommands} glyph parameter.
%
% \begin{macro}{\vpl_raw}
% This macro writes the entries in a \texttt{MAP} that are needed for
% the given raw character. Note that the `at' comment below gives the
% scaling relative to the atsize of the virtual font, not the physical
% atsize.
% \IndexEntry{\LevelSame{PL properties:}^^A
% \LevelSorted{SELECTFONT}{\texttt{SELECTFONT}}^^A
% }{usage}{\thepage}
% \begin{macrocode}
\def\vpl_raw#1#2#3{
\global\next_mapfont=\csname\the\mapfont_scaling-#1\endcsname
\ifnum \next_mapfont=\prev_mapfont \else
\out_llline{(SELECTFONT~\vpl_int\next_mapfont)~
(COMMENT~#1~at~
\expandafter\lose_measure \the\mapfont_scaling)}
\fi
\out_llline{(SETCHAR~D~#2)~(COMMENT~#3)}
\global\prev_mapfont=\next_mapfont
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_rule}
% \begin{macrocode}
\def\vpl_rule#1#2{
\a_dimen=\make_factor{#2}\mapfont_scaling
\b_dimen=\make_factor{#1}\mapfont_scaling
\out_llline{(SETRULE~\vpl_real\a_dimen\space\vpl_real\b_dimen)}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_special}
% \begin{macro}{\vpl_warning}
% \begin{switch}{warningspecials}
% \changes{1.913}{2000/02/26}{Switch controlling whether
% \cs{glyphwarning}s should put \texttt{SPECIALS} in the VPL was
% added. (LH)}
% \begin{macrocode}
\def\vpl_special#1{
\out_llline{(SPECIAL~#1)}}
% \end{macrocode}
% \begin{macrocode}
\def\vpl_warning#1{
\ifwarningspecials
\out_llline{(SPECIAL~Warning:~#1)}
\fi
\immediate\write16{Warning:~#1.}
}
% \end{macrocode}
% \begin{macrocode}
\newif\ifwarningspecials
\warningspecialstrue
% \end{macrocode}
% \end{switch}\end{macro}\end{macro}
%
% \begin{macro}{\vpl_movert}
% \begin{macro}{\vpl_moveup}
% \begin{macrocode}
\def\vpl_movert#1{
\a_dimen=\make_factor{#1}\mapfont_scaling
\out_llline{(MOVERIGHT~\vpl_real\a_dimen)}
}
% \end{macrocode}
% \begin{macrocode}
\def\vpl_moveup#1{
\a_dimen=\make_factor{#1}\mapfont_scaling
\out_llline{(MOVEUP~\vpl_real\a_dimen)}
}
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\vpl_push}
% \begin{macro}{\vpl_pop}
% \begin{macrocode}
\def\vpl_push{\out_llline{(PUSH)}}
% \end{macrocode}
% \begin{macrocode}
\def\vpl_pop{\out_llline{(POP)}}
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% \subsection{Tidying up}
%
% \begin{macro}{\make_tidy}
% If a VPL file was written, the tidying up consists of clearing the
% list of mapfont numbers, since that is stored globally. If a PL
% file was written, the tidying up consists of writing a
% \texttt{DESIGNUNITS} property for those fonts which need one.
% \begin{macrocode}
\def\make_tidy#1{
\tidying_up_hook
\if_including_map_
\a_count=0
\loop\ifnum \a_count<\font_count
\edef\a_macro{\csname~f-\the\a_count\endcsname}
\global\x_cs\let\a_macro\x_relax
\advance\a_count by 1
\repeat
\global\font_count=0
\else
\ifdim \rawfont_scaling<\z@
\fontinstwarning{ETX~to~(V)PL}{The~font~
\out_filename\space doesn't~contain~any~characters}
\global\rawfont_scaling=\p@
\fi
\ifdim \rawfont_scaling=\p@ \else
\out_line{(DESIGNUNITS~\vpl_real\rawfont_scaling)}
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Font installation commands and \texttt{.fd} files}
%
% \DescribeMacro{\installfonts}
% \DescribeMacro{\endinstallfonts}
% The call
% \begin{quote}
% |\installfonts| \meta{install commands} |\endinstallfonts|
% \end{quote}
% is the top-level interface for installing a number of fonts
% and creating |.fd| files for them.
%
% \DescribeMacro{\installfamily}
% \DescribeMacro{\installfont}
% \DescribeMacro{\installrawfont}
% The \meta{install commands} are:
% \begin{isyntax}
% |\installfamily|\marg{encoding}\marg{family}\marg{FD-commmands}\\
% |\installfont|\marg{font-name}\marg{file-list}\marg{etx}\penalty0
% \marg{encoding}\marg{family}\marg{series}\marg{shape}\marg{size}\\
% |\installrawfont|\marg{font-name}\marg{file-list}\marg{etx}^^A
% \penalty0
% \marg{encoding}\marg{family}\marg{series}\marg{shape}\marg{size}\\
% |\installfontas|\marg{font-name}\penalty0\marg{encoding}^^A
% \marg{family}\marg{series}\marg{shape}\marg{size}
% \end{isyntax}
%
% Each |\installfamily| command causes the generation of an |.fd| file
% for \meta{encoding} and \meta{family}, which is writen out by the time
% |\endinstallfonts| is processed.
%
% Each |\installfont| generates a |.vpl| font by calling |\etxtovpl|
% and adds an |.fd| entry.
% Each |\installrawfont| generates a ligfull |.pl| font by calling
% |\etxtopl| and adds an |.fd| entry. (Raw |.pl| fonts, containing only
% the glyph metrics without any ligaturing or kerning information,
% are also generated by |\mtxtopl| called from |\transformfont|
% statements.)
%
% \changes{1.912}{2000/01/15}{\cs{install}\dots\ commands updated to
% set \cs{setsomething_global} to \cs{global} around themselves. This
% reduces problems with assignments ``not working'' due to the
% unintuitive grouping. (LH) Problem pointed out by Hilmar
% Schlegel, , and others.}
%
% \begin{macro}{\installfonts}
% Initializes the |\family_toks| token register, which is used to store
% the information which is written out to |.fd| files at the end of the
% job.
%
% \begin{macrocode}
\newtoks\family_toks
\def\installfonts{
\bgroup
\global\family_toks={}
\gdef\prev_file_list{}
\global\let\setsomething_global=\global
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\installfamily}
% |\installfamily|\marg{encoding}\marg{family}\marg{FD-commmands}
%
% Adds the command
% \begin{quote}
% |\fd_family|\marg{encoding}\marg{family}\marg{FD-commmands}
% \end{quote}
% to the token list |\family_toks| and defines a macro
% |\|\meta{encoding}|-|\meta{family}.^^A
% \describecsfamily{\meta{encoding}-\meta{family}}
%
% \begin{macrocode}
\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
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\installfont}
% \begin{macro}{\installrawfont}
% \changes{1.904}{1999/06/16}{Added \cs{record_usage}. (LH)}
% \multchanges{\cs{installfont}\cs{installrawfont}}{1.913}{2000/03/21}
% {Moved some code from \cs{install_font} to these commands. (LH)}
% |\installfont|\marg{font-name}\marg{file-list}\marg{etx}\\
% \vadjust{}\qquad \marg{encoding}\marg{family}\marg{series}^^A
% \marg{shape}\marg{size}\\
% |\installrawfont|\marg{font-name}\marg{file-list}\marg{etx}\\
% \vadjust{}\qquad \marg{encoding}\marg{family}\marg{series}^^A
% \marg{shape}\marg{size}
%
% \begin{macrocode}
\def\installfont#1#2#3#4#5#6#7#8{
\global\let\setsomething_global=\x_relax
\input_metrics{}{#2}
\etxtovpl{#3}{#1}
\installfontas{#1}{#4}{#5}{#6}{#7}{#8}
\global\let\setsomething_global=\global
}
\def\installrawfont#1#2#3#4#5#6#7#8{
\global\let\setsomething_global=\x_relax
\xdef\out_filename{#1}
\input_metrics{\let\storemapdata=\installraw_storemap}{#2}
\let\storemapdata=\gobble_three
\etxtopl{#3}{#1}
\record_usage{#1}
\installfontas{
\ifdim \rawfont_scaling=\p@ \else
[\expandafter\lose_measure\the\rawfont_scaling]~
\fi #1
}{#4}{#5}{#6}{#7}{#8}
\global\let\setsomething_global=\global
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\installraw_storemap}
% The |\installraw_storemap| macro is a definition of |\storemapdata|
% that is used when the metrics for a ligful PL file is being inputed.
% Its job is to write a |\storemapdata| command for this PL to the
% transforms record file if the PL being written does not have the
% same name as the MTX that the metrics are taken from (the
% information is already stored if both files have the same name).
% |\out_filename| is prematurely set by |\installrawfont| (i.e., long
% before the PL file is actually opened) so that it can be used in
% comparing the file names.
% \changes{1.913}{1999/03/23}{Macro added. (LH)}
% \begin{macrocode}
\def\installraw_storemap#1#2#3{
\def\a_macro{#1}
\ifx \a_macro\out_filename \else
\record_transform{\out_filename}{\string\frommtx{#1}}{}\if_false
\fi
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\input_metrics}
% The |\input_metrics| macro takes a comma-separated list of metric
% files as its second argument and sees to that exactly these metrics
% are loaded. If the list is identical to that used in the last call
% to |\input_metrics|, then this is already the case and
% |\input_metrics| simply refrains from flushing those previous
% metrics from \TeX's memory. Otherwise it closes a group (flushing
% the metrics from a previous call), opens a group (so that these
% metrics can be flushed at the next |\installfont| or
% |\installrawfont| command, if necessary), and starts inputting the
% metrics files in question.
%
% The first argument consists of code that will be executed after the
% group has been closed and opened, but before any metrics is inputed.
% \changes{1.900}{1999/02/13}
% {Use \cs{process_csep_list} for file-list. (LH)}
% \changes{1.914}{2000/05/26}{Redefined to suite \cs{file_list_metrics}.
% In particular, there will now be a comma at the end of
% \cs{curr_file_list} and \cs{prev_file_list}. (LH)}
% \begin{macrocode}
\def\input_metrics#1#2{
\let\metrics=\file_list_metrics
\xdef\curr_file_list{#2,}
\let\metrics=\x_relax
\ifx\prev_file_list\curr_file_list\else
\egroup\bgroup
#1
\expandafter\process_csep_list \expandafter\input_mtx_file
\curr_file_list\process_csep_list,
\global\let\prev_file_list=\curr_file_list
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\file_list_metrics}
% The |\file_list_metrics| macro is a definition of |\metrics| that
% is used in the \meta{file-list} argument of |\install|\-|font| and
% |\install|\-|raw|\-|font| when that is |\xdef|ed by |\input_metrics|.
% This special definition prevents the succeeding \meta{metric
% commands} from getting expanded.
% \changes{1.914}{2000/05/26}{Macro added. (LH)}
% \begin{macrocode}
\def\file_list_metrics#1,{
\iffalse{\fi}
\a_toks=\expandafter{\curr_file_list\x_relax#1,}
\xdef\curr_file_list{\the\a_toks \iffalse}\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\installfontas}
% The |\installfontas| command has the syntax
% \begin{isyntax}
% |\installfontas|\marg{font-info}\marg{encoding}\marg{family}^^A
% \penalty0\marg{series}\penalty0\marg{shape}\penalty0\marg{size}
% \end{isyntax}
% The precise definition of a \meta{font-info} can be found in
% \cite[Sec.~4]{fntguide}, here it suffices to say that a font name
% (name of (V)PL file) is a valid \meta{font-info}. The |\installfontas|
% command adds an entry for the \meta{font-info} font to a font
% definition file, giving it the NFSS attributes \meta{encoding}^^A
% \texttt{/}\nolinebreak[1]\meta{family}\texttt{/}\nolinebreak[1]^^A
% \meta{series}\texttt{/}\nolinebreak[1]\meta{shape}\texttt{/}^^A
% \nolinebreak[1]\meta{size}. The substitution mechanism will act on
% \meta{series} and \meta{shape}, and it is therefore possible that
% \meta{font-info} will appear in more than one |\Declare|\-|Font|\-^^A
% |Shape| command. \meta{size} can be either some \meta{size-infos},
% as defined in \cite[Sec.~4]{fntguide}, or a \package{fontinst}
% shorthand for a such, declared using |\declaresize|.
% \changes{1.912}{2000/01/16}{Command added. (LH)}
% \changes{1.913}{2000/03/02}{Specification changed to allow
% arbitrary \meta{font-info}s as first argument. (LH)}
% \changes{1.921}{2002/03/27}{Automatically doing an
% \cs{installfamily} if that has not been done. (LH) Suggested
% by Rowland McDonnell.}
% \begin{macrocode}
\def\installfontas#1#2#3#4#5#6{
\if_undefined{#2-#3-#4-#5}\then
\let\do_shape=\x_relax
\if_undefined{#2-#3}\then
\x_cs\let{#2-#3}\empty_command
\autoinstallfamily{#2}{#3}
\fi
\x_cs\xdef{#2-#3}{
\csname#2-#3\endcsname
\do_shape{#2}{#3}{#4}{#5}
}
\fi
\let\do_size=\x_relax
\x_cs\xdef{#2-#3-#4-#5}{
\if_defined{#2-#3-#4-#5}\then
\csname#2-#3-#4-#5\endcsname
\fi
\do_size{#6}{#1}
}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\autoinstallfamily}
% This command is called by |\installfontas| when it is asked to
% install a font for which no |\installfamily| has been given. The
% syntax is
% \begin{quote}
% |\autoinstallfamily|\marg{encoding}\marg{family}
% \end{quote}
% It defaults to calling |\installfamily| in the obvious way, but
% it can be redefined if the user wants something different.
% \changes{1.924}{2003/02/08}{Macro added. (LH)}
% \begin{macrocode}
\def\autoinstallfamily#1#2{\installfamily{#1}{#2}{}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endinstallfonts}
% Finish the installation by processing the |\family_toks|
% token register, which contains the accumulated information
% to be written out to |.fd| files.
%
% \begin{macrocode}
\def\endinstallfonts{
\global\let\setsomething_global=\x_relax
\let\do_shape=\fd_shape
\let\do_size=\fd_size
\the\family_toks
\global\family_toks{}
\egroup
}
% \end{macrocode}
% \end{macro}
%
%
% The |\installfont| command has traditionally allowed that names of
% base fonts (MTX files) are suffixed by a
% \verb*" scaled "\meta{factor} that would cause the \texttt{rawscale}
% integer to be set and thereby scale everything that was in that base
% font by the said \meta{factor}. There is now a more general approach
% to this. If the control sequence
% \describecsfamily{IFKW-\meta{keyword}}|IFKW-|\meta{keyword} is
% defined then \meta{keyword} may be used as \texttt{scaled} is above;
% this control sequence should grab all the ``arguments'' of the
% keyword, process them as necessary, and end with the |\get_keyword|
% macro so that another keyword may be processed. As a rule, the
% arguments and keywords are delimited from each other by single spaces.
% A macro grabbing an argument grabs also the space after it. The
% \texttt{IFKW} is for \texttt{I}nstall\texttt{F}ont
% \texttt{K}ey\texttt{W}ord.
%
% \changes{1.923}{2002/10/09}{Added support for keywords other than
% \texttt{scaled} in the second argument of \cs{installfont} and
% such. (LH)}
%
% \begin{macro}{\input_mtx_file}
% The |\input_mtx_macro| takes one undelimited argument. It
% interprets this argument as if it was one item in the \meta{file-list}
% argument of |\install|\-|font| or |\install|\-|rawfont|, and does
% the corresponding processing. The argument should be one of the
% following three things:
% \begin{quote}
% \meta{font}\meta{optional modifiers}\\
% |\metrics| \meta{metric commands}\\
% \meta{nothing}
% \end{quote}
% If, in the first case, an MTX file for \meta{font} does not
% exist then it is generated on the fly from a corresponding |.pl|,
% |.afm|, or |.vpl| file in the call to |\fromany|. In the second
% case, the \meta{metric commands} simply get executed. In the third
% case, nothing happens.
%
% The \meta{optional modifiers} is either empty or has the form
% \meta{modifier clause}\meta{optional modifiers}. A \meta{modifier
% clause} generally has the form
% \begin{quote}
% \verb*" "\meta{keyword}\verb*" "\meta{argument(s)}
% \end{quote}
% e.g.,
% \begin{quote}
% \verb*| scaled |\meta{rawscale factor}
% \end{quote}
%
% \changes{1.904}{1999/06/16}{Now using \cs{fromany} to make an MTX
% file when necessary. Furthermore testing for empty argument using
% \cs{ifx} rather than \cs{if}. (LH)}
% \changes{1.912}{2000/01/15}{Added error message. (LH) Suggested by
% Alexei Kostin.}
% \changes{1.914}{2000/05/26}{Can now accept arbitrary metric
% commands in argument. (LH)}
% \begin{macrocode}
\def\input_mtx_file#1{
\reset_modifiers_hook
\ifx\x_relax#1\x_relax
% \end{macrocode}
% This tests for an empty argument, but it also lets explicit metric
% commands be executed.
% \begin{macrocode}
\else
\identity_one{\get_file_name #1~}~\par
% \end{macrocode}
% The two spaces have the effect of putting an empty keyword modifier
% last in the \meta{optional modifiers}. If everything is all right
% then this will gobble the |\par|. However, if the user forgot some
% argument of the last keyword then there will be an error message
% when |\get_keyword| will try to grab the next keyword.
%
% If an encoding has been specified then the source file must be a PL
% or VPL file (since these are the only ones for which it makes sense
% to specify an encoding), otherwise we rely on |\fromany| to find a
% font metrics file.
% \changes{1.926}{2003/07/10}{Only looking for PL and VPL files when
% an encoding is specified. (LH)}
% \changes{1.929}{2005/01/13}{Missing space in message inserted. (LH)
% Pointed out by Peter Dyballa.}
% \begin{macrocode}
\ifx \pl_encoding\empty_command
\fromany\file_name
\else
\metrics_given_encoding{\file_name}{\pl_encoding}
\fi
\ifisstr{afm-name}\then
\inputmtx{\str{afm-name}}
\else
\fontinsterror{\string\install...}{
Font/MTX~file~\file_name\space not~found
}{
You~can~insert~an~\string\inputmtx\space command~here
\messagebreak to~input~some~other~MTX~file~instead.
\ifisint{rawscale}\then \messagebreak
The~requested~raw~scaling~will~then~be~applied~on~that.
\fi
}
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\metrics_given_encoding}
% This macro is a cousin of |\fromany|, for the case that metrics are
% taken from a (V)PL file that furthermore is assigned nonstandard
% metrics. The syntax is
% \begin{quote}
% |\metrics_given_encoding|\marg{font}\marg{etx}
% \end{quote}
% and the generated MTX file is named
% \meta{font}\texttt{-}\meta{etx}\texttt{.mtx} to avoid that it is
% picked up by |\fromany| by mistake.
% \changes{1.929}{2005/01/12}{The \texttt{afm-name} string usually has
% a value at this point, so it is necessary to reset it. (LH,
% sighing because he knows this isn't the first time this problem
% occurred) First to be hit by this bug was Michael Zedler.}
% \begin{macrocode}
\def\metrics_given_encoding#1#2{
\x_cs\edef{s-afm-name}{#1-#2}
\if_file_exists{#1.pl}\then
\generalpltomtx{#1}{#1-#2}{pl}{#2}
\else
\if_file_exists{#1.vpl}\then
\generalpltomtx{#1}{#1-#2}{vpl}{#2}
\else
\unsetstr{afm-name}
\fi\fi
}
% \end{macrocode}
% \end{macro}
%
%
% \definechange{option-keyword}{1.924}{2002/02/16}{Added mechanism
% for passing options to MTX and ETX files. (LH)}
%
% \begin{macro}{\reset_modifiers_hook}
% The |\reset_modifiers_hook| macro contains code that initialises
% all parameters that are modified by some \meta{modifier clause} to
% their default values. If you need to add some initialisations due
% to that you define additional keywords then you should append
% these initialisations to this macro.
% \usechange{option-keyword}
% \begin{macrocode}
\def\reset_modifiers_hook{
\unsetint{rawscale}
\let\glyph_name_modifier\identity_one
\let\pl_encoding\empty_command
\let\list_of_options\empty_command
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\get_file_name}
% The macro |\get_file_name| grabs the base font (or other MTX file)
% name and starts the processing of the \meta{optional modifiers}.
% \begin{macrocode}
\def\get_file_name #1~{
\edef\file_name{#1}
\get_keyword
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\get_keyword}
% \begin{macro}{\gobble_keywords}
% The |\get_keyword| macro expects to be expanded in the context
% \begin{quote}
% |\get_keyword|\,\meta{keyword}\verb*" "
% \end{quote}
% where the \meta{keyword} is a possible keyword. If
% |\IFKW-|\meta{keyword} is defined then the above expands to it,
% otherwise the above expands to an error message followed by a
% |\gobble_keywords|, which will gobble the rest of the list of
% keywords and arguments.
% \begin{macrocode}
\def\get_keyword #1~{
\if_defined{IFKW-#1}\then
\csname IFKW-#1 \expandafter\endcsname
\else
\fontinsterror{\string\install...}{
`#1'~is~not~a~defined~keyword
}{
\error_help_a\messagebreak
Extra~tokens~will~be~flushed.
}
\expandafter\gobble_keywords
\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\gobble_keywords#1\par{}
% \end{macrocode}
% \end{macro}\end{macro}
%
% \begin{macro}{\IFKW-}
% The empty keyword is used to flag the end of the \meta{optional
% modifiers}.
% \begin{macrocode}
\x_cs\let{IFKW-}=\gobble_keywords
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\IFKW-scaled}
% This macro handles grabbing the argument of the traditional
% \texttt{scaled} keyword.
% \changes{1.900}{1999/02/05}{Changed \cs{setint} to \cs{resetint}.
% (LH)}
% \begin{macrocode}
\x_cs\def{IFKW-scaled}#1~{
\ifnum #1=\one_thousand
\unsetint{rawscale}
\else
\x_resetint{rawscale}{#1}
\fi
\get_keyword
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\IFKW-suffix}
% This macro handles grabbing the argument of the \texttt{suffix}
% keyword. The effect of `\texttt{suffix} \meta{suffix}' is that
% \meta{suffix} will be appended to the name of every glyph defined
% by the next MTX file to be read in.
% \begin{macrocode}
\x_cs\def{IFKW-suffix}#1~{
\def\glyph_name_modifier##1{##1#1}
\get_keyword
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\IFKW-encoding}
% \begin{macro}{\pl_encoding}
% This macro handles grabbing the argument of the \texttt{encoding}
% keyword. The effect of `\texttt{encoding} \meta{etx}' is that
% \meta{etx} will be used as encoding when converting a PL or VPL
% file to MTX. |\pl_encoding| is used for storing the argument
% value. Its expansion is normally empty, which means |\fromafm|
% handles locating the metrics file and the encoding used for a PL
% or VPL is determined by its codingscheme.
% \begin{macrocode}
\x_cs\def{IFKW-encoding}#1~{
\def\pl_encoding{#1}
\get_keyword
}
\let\pl_encoding=\empty_command
% \end{macrocode}
% \end{macro}\end{macro}
%
%
% \begin{macro}{\IFKW-option}
% This macro handles grabbing the argument of the \texttt{option}
% keyword. One can test using |\ifoption| whether a particular option
% was specified.
% \usechange{option-keyword}
% \begin{macrocode}
\x_cs\def{IFKW-option}#1~{
\add_to\list_of_options{\do{#1}}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifoption}
% \usechange{option-keyword}
% \begin{macro}{\list_of_options}
% \usechange{option-keyword}
% The |\ifoption| command is used to test whether a particular option
% is present on the list of options. The syntax is
% \begin{quote}
% |\ifoption|\marg{string}|\then|
% \end{quote}
% and it is tested whether the \meta{string} was one of the options
% given. Like strings in general, the \meta{string} is expanded
% before it is compared to the options listed in |\list_of_options|.
%
% The |\list_of_options| is a sequence of items on the form
% \begin{quote}
% |\do|\marg{option}
% \end{quote}
% where each \meta{option} is an already expanded string of
% characters.
% \begin{macrocode}
\def\ifoption#1\then{
\_a_false
\edef\a_macro{#1}
\def\do##1{
\if_a_ \else
\def\b_macro{##1}
\ifx \a_macro\b_macro \_a_true \fi
\fi
}
\list_of_options
\if_a_
}
%
%<*doc>
\def\ifoption#1\then{%
\generic@if{option \TypesetStringExpression{#1}}%
}
%
%<*pkg>
\let\list_of_options\empty_command
% \end{macrocode}
% \end{macro}\end{macro}
%
%
% \subsection{Writing font definition files}
%
% \begin{macro}{\fd_family}
% |\fd_family{ENCODING}{FAMILY}{FD-COMMANDS}|
%
% Writes out an |.fd| file for the specified |ENCODING| and |FAMILY|
% processing the accumulated information and default substitutions.
%
% \begin{macrocode}
\def\fd_family#1#2#3{
\a_toks{#3}
\edef\lowercase_file{\lowercase{
\edef\noexpand\lowercase_file{#1#2.fd}}}
\lowercase_file
\open_out{\lowercase_file}
\out_line{\percent_char~Filename:~\lowercase_file}
\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{\lowercase_file}}
\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}\x_relax
\out_line{}
\out_line{\string\endinput}
\close_out{Font~definitions}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fd_shape}
% |\fd_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}|
%
% \begin{macrocode}
\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{}}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fd_size}
% |\fd_size{SIZE}{FONT-NAME}|
%
% \begin{macrocode}
\def\fd_size#1#2{
\x_cs\ifx{siz-#1}\x_relax
\out_lline{#1~#2}
\else
\out_lline{\csname siz-#1\endcsname\space #2}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\remove_shape}
% |\remove_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}|
%
% \begin{macrocode}
\def\remove_shape#1#2#3#4{
\x_cs\g_let{#1-#2-#3-#4}\x_relax
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\substitute_shape}
% |\substitute_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}|
%
% \begin{macrocode}
\def\substitute_shape#1#2#3#4{
\edef\orig_shape{#4}
\substitute_series{#1}{#2}{#3}{\orig_shape}
\x_cs\ifx{sub-\orig_shape}\x_relax\else
\edef\subst_shape{\csname sub-\orig_shape\endcsname}
\x_cs\ifx{#1-#2-#3-\subst_shape}\x_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
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\substitute_series}
% |\substitute_series{ENCODING}{FAMILY}{SERIES}{SHAPE}|
%
% \begin{macrocode}
\def\substitute_series#1#2#3#4{
\edef\orig_series{#3}
\x_cs\ifx{sub-\orig_series}\x_relax\else
\edef\subst_series{\csname sub-\orig_series\endcsname}
\x_cs\ifx{#1-#2-\subst_series-#4}\x_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
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\substitutesilent}
% \begin{macro}{\substitutenoisy}
% These commands specify a default substitution for series or shape
% \meta{to}, which points to the series or shape \meta{from}.
% \begin{quote}
% |\substitutesilent|\marg{to}\marg{from}\\
% |\substitutenoisy|\marg{to}\marg{from}
% \end{quote}
% There can be at most one \meta{to} for every \meta{from}; later
% substitutions will override previous ones. If \meta{to} and
% \meta{from} are equal, then any existing substitution from
% \meta{from} is disabled.
%
% The way this is implemented is that if a font has been installed
% with shape or series \meta{from}, but no entry for \meta{to} has
% been written, then write an entry also for \meta{to} consisting of
% a substitution by \meta{from}. (After doing that, an entry has been
% written also for \meta{to}, so the process may repeat itself with
% the old \meta{to} as a new \meta{from}.)
%
% \begin{macro}{\substitute_generic}
% This is the common part of |\substitutesilent| and
% |\substitutenoisy|. The syntax is
% \begin{quote}
% |\substitute_generic|\marg{type}\marg{to}\marg{from}
% \end{quote}
% where \meta{type} is |ssub| or |sub| respectively.
% \changes{1.931}{2005/05/12}{Macro added, to support explicit
% disabling of substitutions. (LH)}
% \begin{macrocode}
\def\substitute_generic#1#2#3{
\edef\a_macro{#2}
\edef\b_macro{#3}
\ifx \a_macro \b_macro
\x_cs\let{sub-#3}\undefined_command
\else
\x_cs\let{sub-#3}\a_macro
\x_cs\def{typ-#3}{#1}
\fi
}
% \end{macrocode}
% \end{macro}
% \begin{macrocode}
\def\substitutesilent{\substitute_generic{ssub}}
\def\substitutenoisy{\substitute_generic{sub}}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macrocode}
\substitutesilent{bx}{b}
\substitutesilent{b}{bx}
\substitutesilent{b}{sb}
\substitutesilent{b}{db}
\substitutesilent{m}{mb}
\substitutesilent{m}{l}
% \end{macrocode}
% \begin{macrocode}
\substitutenoisy{ui}{it}
% \end{macrocode}
%
% I don't think we want these since in OT1 encoding it will
% cause the old || vs || problem. (ASAJ)
% --- Oh yes we do. (SPQR)
%
% \begin{macrocode}
\substitutesilent{sl}{it}
\substitutesilent{it}{sl}
% \end{macrocode}
%
%
% \subsection{New font substitution mechanism}
%
% \textbf{Note:} This subsection contains (part of) a new implementation
% of the font substitution mechanism, but it is uncertain whether it
% will ever be completed.
% \begin{macrocode}
%<*underconstruction>
% \end{macrocode}
%
%
% \subsubsection{The substitution graph}
%
% Which substitutions are performed are determined by the substitution
% graph. The vertices of this graph are all combinations of a series and
% a shape. The arcs (directed edges) of this graph are the substitutions
% that can be made. Each arc has a wheight---a real number in the range
% $[0,1]$---that describes how much of the quality of the font that is
% preserved with this substitution.
%
% As an example, consider the case that there is an arc from \texttt{m/it}
% to \texttt{m/sl} and that the wheight of this arc is $0.5$. This means
% that it is OK to substitute the medium italic (\texttt{m/it}) font as a
% medium slanted (\texttt{m/sl}) font if there is no medium slanted font,
% but that the medium italic font is only considered as being half
% ($0.5$) as good a medium slanted font as it is a medium italic font.
%
% The main problem the substitution mechanism has to solve in this
% context is to find the best possible way of substituting a font, given
% the real fonts which has actually been installed (using |\installfont|
% or |\installrawfont|). The solution to this problem is computed by a
% brute force approach---all possible substitution paths are followed
% and during this process the best solution so far, for each vertex
% separately, is stored.
% \medskip
%
% In practice, the substitution graph $G$ is constructed as the cartesian
% product of one graph $G\sb{1}$ of series substitutions and one graph
% $G\sb{2}$ of shape substitutions, with the option of adding some
% additional arcs to this product. The reason for this is that one
% usually wants to make the same shape substitutions in all series and
% vice versa, so by only storing the $G\sb{1}$ and $G\sb{2}$ graphs, plus
% perhaps a handfull of extra edges, one gets away with using fewer
% tokens.
% The wheights of the arcs are stored as integers in the range 0--1000,
% where 0 means the real number $0$ and 1000 means the real number $1$.
% \medskip
%
% \DescribeMacro\do_arc
% The |\do_arc| macro is probably the most common in the data
% structures that constitute the substitution graph. Its syntax is
% always
% \begin{quote}
% |\do_arc|\marg{series}\marg{shape}\marg{wheight}
% \end{quote}
% but it is meant to be redefined whenever one needs to do something
% ``for all arcs'' (usually all arcs at a given vertex or so). There are
% three families of macros which consist of |\do_arc| lists, namely
% \begin{quote}
% |\sub1-|\meta{series}\\
% |\sub2-|\meta{shape}\\
% |\sub-|\meta{series}|-|\meta{shape}
% \end{quote}
% These macros store arcs going out from a vertex. The
% |\sub1-|\meta{series} macross store the arcs incident with the vertex
% \meta{series} in the series substitution graph $G\sb{1}$. The
% |\sub2-|\meta{shape} macros store the arcs incident with the vertex
% \meta{shape} in the shape substitution graph $G\sb{2}$. The
% |\sub-|\meta{series}|-|\meta{shape} macros store the arcs of $G$ that
% are incident with the vertex \meta{series}|/|\meta{shape} but do
% \emph{not} appear in the cartesian product $G\sb{1} \times G\sb{2}$.
%
% The \meta{series} and \meta{shape} arguments of |\do_arc| tells which
% vertex the arc goes to, hence for example |\do_arc{b}{it}{600}| in the
% macro |\sub-db-sl| corresponds to an arc going from the |db/sl| vertex
% to the |b/it| vertex and having a wheight of $0.6$.
%
% \DescribeMacro\curr_series
% \DescribeMacro\curr_shape
% The above omits one important detail, namely that the \meta{shape}
% argument for a |\do_arc| in a |\sub1-|\textellipsis\ must be able to
% be \emph{all} shapes since the shape is not determined for arcs in
% $G\sb{1}$ and the series is likewise for arcs in $G\sb{2}$. To make things
% work anyway, there are two macros |\curr_series| and |\curr_shape|
% which contain this missing information. Furthermore, a |\do_arc| item
% for an arc in $G\sb{1}$ will always have the structure
% \begin{quote}
% |\do_arc|\marg{series}|\curr_shape|\marg{wheight}
% \end{quote}
% and a |\do_arc| item for an arc in $G\sb{2}$ will have the structure
% \begin{quote}
% |\do_arc\curr_series|\marg{shape}\marg{wheight}
% \end{quote}
%
%
% \begin{macro}{\substituteshape}
% \begin{macro}{\substituteseries}
% \begin{macro}{\substituteseriesshape}
% |\substituteshape|\marg{to}\marg{from}\marg{wheight}\\
% |\substituteseries|\marg{to}\marg{from}\marg{wheight}\\
% |\substituteseriesshape|\marg{toseries}\marg{toshape}^^A
% \marg{fromseries}\marg{fromshape}\marg{wheight}
%
% \begin{macrocode}
\def\substituteshape#1#2#3{
\round_wheight{#3}
\edef\temp_command{#1}
\edef\sub_suffix{#2}
\ifx \temp_command\sub_suffix \else
\def\sub_suffix##1##2{2-##2}
\def\do_arc##1##2##3{
\x_cs\ifx{sub2-##2}R \else
\noexpand\do_arc\noexpand\curr_series{##2}{##3}
\fi
}
\update_do_arc_list{}{#2}{}{#1}{\noexpand\curr_series{#1}}
\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\substituteseries#1#2#3{
\round_wheight{#3}
\edef\temp_command{#1}
\edef\sub_suffix{#2}
\ifx \temp_command\sub_suffix \else
\def\sub_suffix##1##2{1-##1}
\def\do_arc##1##2##3{
\x_cs\ifx{sub1-##1}R \else
\noexpand\do_arc{##1}\noexpand\curr_shape{##3}
\fi
}
\update_do_arc_list{#2}{}{#1}{}{{#1}\noexpand\curr_shape}
\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\substituteseriesshape#1#2#3#4#5{
\round_wheight{#5}
\edef\temp_command{#1-#2}
\edef\sub_suffix{#3-#4}
\ifx \temp_command\sub_suffix \else
\def\sub_suffix##1##2{-##1-##2}
\def\do_arc##1##2##3{
\x_cs\ifx{sub-##1-##2}R \else
\noexpand\do_arc{##1}{##2}{##3}
\fi
}
\update_do_arc_list{#3}{#4}{#1}{#2}{{#1}{#2}}
\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\round_wheight#1{
\eval_expr{#1}
\ifnum \one_thousand<\result
\result=\one_thousand
\else \ifnum 0>\result
\result=\z@
\fi\fi
}
% \end{macrocode}
%
% |\update_do_arc_list|\marg{update-series}\marg{update-shape}^^A
% \allowbreak\marg{tag-series}\allowbreak\marg{tag-shape}^^A
% \allowbreak\marg{inserted series+shape}
%
% \begin{macrocode}
\def\update_do_arc_list#1#2#3#4#5{
\bgroup
\edef\temp_command{sub\sub_suffix{#1}{#2}}
\x_cs\let{sub\sub_suffix{#3}{#4}}=R
\x_cs\xdef\temp_command{
\x_cs\ifx\temp_command\relax \else
\csname\temp_command\endcsname
\fi
\ifnum 0<\result
\noexpand\do_arc #5{\the\result}
\fi
}
\egroup
}
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
%
%
% \begin{macro}{\substitutesilent}
% \begin{macro}{\substitutenoisy}
% |\substitutesilent{TO}{FROM}|\\
% |\substitutenoisy{TO}{FROM}|
%
% Specifies a default substitution for family or shape |TO|,
% which is substituted by family or shape |FROM|.
%
% \begin{macrocode}
\def\substitutesilent#1#2{
\substituteseries{#1}{#2}{900}
\substituteshape{#1}{#2}{900}
}
\def\substitutenoisy#1#2{
\substituteseries{#1}{#2}{500}
\substituteshape{#1}{#2}{500}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macrocode}
\a_count=900 % Silent substitution wheight
\b_count=500 % Noisy substitution wheight
\substituteseries{bx}{b}{\a_count}
\substituteseries{b}{bx}{\a_count}
\substituteseries{b}{sb}{\a_count}
\substituteseries{b}{db}{\a_count}
\substituteseries{m}{mb}{\a_count}
\substituteseries{m}{l}{\a_count}
% \end{macrocode}
% \begin{macrocode}
\substituteshape{ui}{it}{\b_count}
% \end{macrocode}
%
% I don't think we want these since in OT1 encoding it will
% cause the old || vs || problem. (ASAJ)
% --- Oh yes we do. (SPQR)
%
% \begin{macrocode}
\substituteshape{sl}{it}{\a_count}
\substituteshape{it}{sl}{\a_count}
% \end{macrocode}
%
%
% \subsubsection{Listing reachable vertices}
%
% While determining the optimal substitutions, there is a need to store
% some---more or less temporary---information for each vertex. Such
% information will be called a \emph{property} of the vertex and it is
% stored in the |\v-|\meta{series}|-|\meta{shape} family of macros.
%
% The following are the basic properties:
% \begin{list}{}{^^A
% ^^A How does one make the label go on a line of its own??
% }
% \item[\cs{real_font}\marg{quality}]
% This expresses that this vertex corresponds to a font that has
% actually been installed with a nominal quality of \meta{quality}.
% \item[\cs{subs_font}\marg{series}\marg{shape}\marg{quality}]
% This expresses that this vertex corresponds to a font for which
% the font \meta{series}|/|\meta{shape} has been substituted.
% \meta{quality} is the quality this substitution is considered to
% have.
% \item
% \end{list}
%
%
% There will also be some lists of vertices. These will consist of simple
% |\do|\marg{series}\marg{shape} triples.
%
% \begin{macrocode}
\def\list_subs_vertices{
\def\subs_vertex_list{}
\let\do_arc=\subs_do_arc
\let\do=\never_do
\def\real_font##1{\c_count=\@MM}
\def\subs_font##1##2##3{\c_count=##3\relax}
\real_vertex_list
}
\def\subs_do_arc#1#2#3{
\b_count=#3
\multiply \b_count \a_count
\divide \b_count \one_thousand
\c_count=-\max_mathchardef
\csname v-#1-#2\endcsname
\ifnum \c_count<\b_count
\ifnum \c_count=-\max_mathchardef
\edef\subs_vertex_list{\subs_vertex_list\do{#1}{#2}}
\fi
\x_cs\edef{v-#1-#2}{\noexpand\subs_font{\subs_series}
{\subs_shape}{\the\b_count}}
\toks_a=\expandafter{\the\a_toks \do_subs{#1}{#2}}
\fi
}
\def\do_subs#1#2{
\edef\curr_series{#1}
\edef\curr_shape{#2}
\csname v-#1-#2\endcsname
\a_count=\c_count
\a_toks={}
\csname sub-#1-#2\endcsname
\csname sub1-#1\endcsname
\csname sub2-#2\endcsname
\the\a_toks
}
\def\start_subs_at#1#2{
\edef\subs_series{#1} \let\curr_series=\subs_series
\edef\subs_shape{#2} \let\curr_shape=\subs_shape
\a_count=\x_cs\second_of_two{v-#1-#2}
\a_toks={}
\csname sub-#1-#2\endcsname
\csname sub1-#1\endcsname
\csname sub2-#2\endcsname
\the\a_toks
}
% \end{macrocode}
%
%
% \begin{macrocode}
%
% \end{macrocode}
%
%
% \subsection{Default encodings and font sizes}
%
% \begin{macro}{\declareencoding}
% |\declareencoding{CODINGSCHEME}{ENCODING}|
%
% Declare a macro |\enc-CODINGSCHEME| which expands to |ENCODING|.
% This is used to determine the encoding in |\pltomtx|.
% \changes{1.927}{2004/07/31}{Lowercased encoding file names. (LH)}
%
% \begin{macrocode}
\def\declareencoding#1#2{\x_cs\edef{enc-#1}{#2}}
% \end{macrocode}
% \end{macro}
%
% Old \TeX{} text font encodings.
% \begin{macrocode}
\declareencoding{TEX~TEXT}{ot1}
\declareencoding{TEX~TEXT~WITHOUT~F-LIGATURES}{ot1}
\declareencoding{TEX~TYPEWRITER~TEXT}{ot1tt}
% \end{macrocode}
%
% Old \TeX{} math font encodings.
% \begin{macrocode}
\declareencoding{TEX~MATH~ITALIC}{oml}
\declareencoding{TEX~MATH~SYMBOLS}{oms}
\declareencoding{TEX~MATH~EXTENSION}{omx}
\declareencoding{LATEX~SYMBOLS}{lasy}
% \end{macrocode}
%
% Euler math font encodings.
% \begin{macrocode}
\declareencoding{TEX~TEXT~SUBSET}{eufrak}
\declareencoding{TEX~MATH~ITALIC~SUBSET}{eurm}
\declareencoding{TEX~MATH~SYMBOLS~SUBSET}{euscr}
\declareencoding{EULER~SUBSTITUTIONS~ONLY}{euex}
% \end{macrocode}
%
% New \TeX{} text font encodings.
% \begin{macrocode}
\declareencoding{EXTENDED~TEX~FONT~ENCODING~-~LATIN}{t1}
\declareencoding{TEX~TEXT~COMPANION~SYMBOLS~1---TS1}{ts1}
% \end{macrocode}
%
% Rencoded PostScript font encdings.
% \begin{macrocode}
\declareencoding{TEXBASE1ENCODING}{8r}
\declareencoding{TEX~TYPEWRITER~AND~WINDOWS~ANSI}{8y}
% \end{macrocode}
%
% \begin{macro}{\declaresize}
% |\declaresize{FONTSIZE}{LATEXSIZE}|
%
% \begin{macrocode}
\def\declaresize#1#2{\x_cs\edef{siz-#1}{#2}}
% \end{macrocode}
% \end{macro}
%
% Default sizes. An empty size argument is equivalent to |<->|,
% for use with scalable fonts.
%
% \begin{macrocode}
\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>}
% \end{macrocode}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Debugging}
%
% \begin{macro}{\NOFILES}
% |\NOFILES| switches off file generation, and causes
% \package{fontinst} to only generate empty files. It only affects the
% user level commands, so it is primarily of use when debugging
% commands that build on these, such as for example the
% |\latin|\-|family| command.
% \changes{1.914}{2000/05/20}{Added \cs{reglyphfont}. (LH)}
% \begin{macrocode}
\def\NOFILES{
\def\transformfont##1##2{
\touch_file{##1.mtx}
\touch_file{##1.pl}
}
\def\reglyphfont##1##2{\touch_file{##1.mtx}}
\def\installfonts{}
\def\endinstallfonts{}
\def\installfont##1##2##3##4##5##6##7##8{
\touch_file{##1.vpl}
}
\def\installrawfont##1##2##3##4##5##6##7##8{
\touch_file{##1.pl}
}
\def\installfamily##1##2##3{\touch_file{##1##2.fd}}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\touch_file}
% \begin{macrocode}
\def\touch_file#1{
\edef\lowercase_file{\lowercase{
\edef\noexpand\lowercase_file{#1}}}
\lowercase_file
\open_out{\lowercase_file}
\out_line{\percent_char~TEST~FILE.}
\out_line{\percent_char~Created~whilst~debugging~fontinst.}
\close_out{Test~file}
}
%
% \end{macrocode}
% \end{macro}
%
% \Finale
\endinput