The fontinst utility

Alan Jeffrey, Sebastian Rahtz, Ulrik Vieth

June 30, 1998

Contents

The fontinst documentation 3

1 About this version of fontinst 3

2 About previous fontinst releases 3

3 About this fontinst release 4

4 Notes on using fontinst 5

5 Notes on small caps and olstyle fonts 6

The fontinst package 7

6 Preliminaries 7 6.1 Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 6.2 Plain TEX macros from fontinst.ini . . . . . . . . . . . . . . . . 8 6.3 Declaring variables and constants . . . . . . . . . . . . . . . . . . . 9 6.4 Trigonometry macros . . . . . . . . . . . . . . . . . . . . . . . . . . 10

7 TEX hackery 10 7.1 Utiltiy macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 7.2 Writing to .fd files . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 7.3 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 7.4 Setting variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 7.5 Integer expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

8 Reading and parsing input files 15 8.1 Converting an ENC file to an ETX file . . . . . . . . . . . . . . . . . 15 8.2 Converting an AFM file to an MTX file . . . . . . . . . . . . . . . . . 16 8.3 Converting a PL file to an MTX file . . . . . . . . . . . . . . . . . . . 21

9 Encoding files 24 10 Metric files 25

10.1 Kerning information . . . . . . . . . . . . . . . . . . . . . . . . . . 26 10.2 Glyph information . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 10.3 Glyph commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

11 Writing output files 33 11.1 Converting an ETX file to a (V)PL file . . . . . . . . . . . . . . . . . 33 11.2 Converting an MTX file to a PL file . . . . . . . . . . . . . . . . . . . 41

12 Font installation commands and .fd files 42 12.1 Default encodings and font sizes . . . . . . . . . . . . . . . . . . . 47

13 Font transformations 48

14 Installing Latin families 51 14.1 Processing a list of weights, widths and shapes . . . . . . . . . . . 53 14.2 Faking font shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 14.3 Faking font widths . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 14.4 Installing reencoded fonts . . . . . . . . . . . . . . . . . . . . . . . 64 14.5 Default weights, widths and shapes . . . . . . . . . . . . . . . . . . 66

15 Version numbers 68

16 Debugging 68

17 Final cleanup 69

The fontdoc package 71

18 Overview 71

19 Implementation 71

About the fontinst package

1 About this version of fontinst

This document describes version 1.8 of the fontinst utility, which was converted to docstrip format by Ulrik Vieth in June 1998. It is based on Sebastian Rahtz’s “unofficial” fontinst releases v 1.6 and 1.7 as of February 1997 and May 1998, which, in turn, are based on Alan Jeffrey’s versions v 1.500 and 1.504 of September 1995 and January 1996. In addition, this version also incorporates some code from Alan Jeffrey’s last beta version, v 1.511, which dates back to June 1996, but was never released to the general public for some reason.

It should be noted that all these versions differ significantly from the last “official” version v 1.335 as of September 1994, which is still to be found in the fontinst directory on CTAN, but should be considered obsolete.

It is the intention of the fontinst hacker community, as represented on the fontinst mailing list, to adopt this version, v 1.8, as the new officially endorsed version, on which all further additions and enhancements can be based.

2 About previous fontinst releases

v 0.01 was begun by Alan Jeffrey in February 1993. This was the very first version recorded in the CHANGES file.

v 0.19 was completed in April 1993 and presented at the TUG ’93 conference in July 1993. It is described in the proceedings in TUGboat 14#3 and represents one of the earliest release versions, in which the user interface was still subject to change.

v 1.0 was begun in August 1993 right after the conference and represents the beginning of a complete re-write from scratch.

v 1.333 was presented one year later at the TUG ’94 conference and is described in the proceedings in TUGboat 15#3. It uses a different user interface, which is largely the same as in the present version, although the internals of the implementation have subsequently changed quite a bit.

v 1.335 was released in September 1994 and was the last “official” release version by Alan Jeffrey still to be found on CTAN. It is considered obsolete and should not be used any longer.

v 1.400 was prepared in November 1994 and was the first version which used 8r-encoded raw fonts as a basis for virtual fonts.

v 1.500 appeared on CTAN in psfonts/tools in September 1995 together with Sebastian Rahtz’s Unix shell scripts to automate the installation. This version included a completely revised implementation of \latinfamily and added the \installrawfont command to install ligfull raw fonts.

v 1.504 appeared on CTAN in psfonts/tools in January 1996. It added code to install (real or faked) small caps fonts and to fake narrow fonts, if they don’t exists. v 1.511 was one of the last beta versions by Alan Jeffrey which dates back to

June 1996, but for some reason was never released. It uses the encodings 9o and 9d instead of 9t and 9e to install expertized oldstyle fonts, but this change never found its way into subsequent “unofficial” releases until v 1.8.

v 1.6 appeared on CTAN in psfonts/tools in February 1997 and was the first “unofficial” version of fontinst maintained by Sebastian Rahtz. It contains only minor changes compared to v 1.504, such as switching to lowercase file names, searching for .pl files before .afm files, and adding the textcomp installation to the distribution.

v 1.6 was re-issued on CTAN in September 1997, when the Unix shell scripts were replaced by Perl scripts. The fontinst package itself didn’t change apart from minor changes of the debugging messages.

v 1.7 is the latest “unofficial version”, which was released on CTAN in May 1998. It includes some changes to the mapping between fontname and L^{A}TEX weight codes proposed by Ulrik Vieth, as well as some code to support the use of 8r-encoded .afm files generated by ttf2afm.

3 About this fontinst release

• fontinst.dtx (the file you are reading) is used to generate the files

fontinst.sty, fontinst.ini and fontdoc.sty from a single documented

source.

• The functionality of \textcompfamily originally defined in textcomp.tex is now fully integrated into \latinfamily, which means that \latinfamily now installs the OT1, T1 and TS1 encodings by default.

• \latinfamily{<FAM>j}{} installs expertized fonts with oldstyle digits using the 9d and 9o encodings instead of 9e and 9t. The \parse_family macro now sets the switch \if_oldstyle when installing an expertized oldstyle family.

• \latinfamily{<FAM>9}{} (retained for backwards compatibility) is treated

exactly as \latinfamily{<FAM>j}{}.

• A lot of debugging info was added to \latinfamily to make it easier to understand what is really going on.

• Instead of playing with \setcommand\digit trickery, oldstyle encodings are now installed by redefining \encoding_shape, so that different encoding files OT1j.etx or T1j.etx are used instead.

• Nearly all .etx and .mtx files were touched up, so that they can be typeset and printed properly. In particular the documentation of slots in t1.etx,

ts1.etx, 8r.etx and 8y.etx was polsihed.

• 8y.etx and 8y.mtx were added and may be used as an optional alternative

to 8r.etx and 8r.mtx, if \raw_encoding is redefined in fontinst.rc.

• ts1.etx and \textcomp.mtx were updated to reflect the latest TC fonts as of EC fonts 1.0. A number of slots were added and several glyphs are faked whenever this is easily possible.

   • \setleftrightkerning is now defined in fontinst.sty instead of repeating

the definition in several .mtx files.

• fontdoc.sty now support an automatic documentation feature for .etx files using default slot comments.

4 Notes on using fontinst

The primary purpose of fontinst is to simplify the installation of PostScript or TrueType text fonts. Leaving aside unusual variants which require special attention such as alternate or swash fonts, almost all standard font families can be installed automatically using the \latinfamily command, optionally making use of the corresponding expert fonts as well.

Depending on what kind of fonts you have and want to install, \latinfamily supports three different modes of operation:

\latinfamily{<fam>}{} installs a normal font family using 8a-encoded standard fonts (reencoded to 8r) and nothing else. It installs .fd files for the L^{A}TEX families 8r<fam>, OT1<fam>, T1<fam> and TS1<fam>, and generates virtual fonts for the 7t, 8t and 8c encodings. This is the only option available for most typefaces which do not have an expert set.

\latinfamily{<fam>x}{} installs an expertized font family using 8a-encoded standard fonts (reencoded to 8r) and 8x-encoded expert fonts. It installs .fd files for the L^{A}TEX families, OT1<fam>x, T1<fam>x and TS1<fam>x, and generates virtual fonts for the 9t, 9e and 9c encodings.

\latinfamily{<fam>j}{} installs an expertized font family with oldstyle digits using 8a-encoded standard fonts (reencoded to 8r) and 8x-encoded expert fonts. It installs .fd files for the L^{A}TEX families, OT1<fam>j, T1<fam>j and TS1<fam>j, and generates virtual fonts for the 9o, 9d and 9c encodings. Since TS1 has oldstyle digits by default, the 9c-encoded fonts should be the same as in the previous case. Finally, \latinfamily{<fam>9}{} is also supported as an alternative to \latinfamily{<fam>j}{} for backwards compatibility.

The whole installation process relies on certain assumptions about the symbol complement of Adobe’s expert fonts. In particular, it is assumed that the expert fonts include the oldstyle digits and a complete set of small caps glyphs, which is an assumption that’s not always statisfied for expert fonts by other suppliers. If these glyphs are not included in the expert fonts, the only way to get them is from real small caps fonts, but this requires some reshuffling of glyph names.

To support such unusual cases, this source file contains some optional code embedded between <*oldstyle> … </oldstyle>, which extends the behaviour of \latinfamily for expertized encodings with oldstyle digits. Instead of relying only on the glyphs of the 8r-reencoded raw font and the 8x-encoded expert font, this version also looks for corresponding OsF or SC&OsF fonts and uses the default digits from those fonts as oldstyle digits.

5 Notes on small caps and olstyle fonts

The \latinfamily command is supposed to do a reasonably good job of installing a complete font family based on all the .afm files it can find. If it doesn’t find a suitable font shape, it is sometimes possible to fake it by default substitutions. However, in the case of small caps fonts, there are several options which may require some clarification.

For the majority of typefaces, a font family typically consists only of of roman and italic fonts in several weights. Since real small caps fonts are not included, they have to be faked from the roman fonts, which is implemented by setting \encoding_shape to ‘c’, so that different encoding files OT1c.etx or T1c.etx are used. Since these files call for glyph names such as ‘Asmall’ which are not found in the roman font, the default substitutions in latin.mtx are eventaully used to approximate fake small caps glyphs by scaling and letterspacing. The outcome is just an approximation for a small caps font, but it is better than nothing.

For a small number of typefaces, the standard fonts are complemented by an expert collection, which ususally includes two sets of fonts. First, for each standard font there is a corresponding expert font containing additional glyphs such as extra ligatures and symbols, oldstyle digits and small capital letters. For Adobe expert fonts this set is sufficient to build a complete small caps font from the standard and expert glyphs. Furthermore, the expert collection usually also contains a number of real small caps font corresponding to the roman fonts and some OsF fonts corresponding to the italic fonts. If these fonts are available, there are several options how to install small caps fonts.

By default, \latinfamily first tries to find a real small caps font. If it is found, it is installed using the default encoding files and metric files, just like any roman or slanted font. However, once \latinfamily has taken this choice, it will fail to find a corresponding expert font, since it is actually looking for an expert font in small caps shape which doesn’t exist. (In fact, it would be an error to substitute an expert font in normal shape.) The outcome will be a virtual font based only on glyphs from the real small caps raw font, which implies ending up with oldstyle digits as the default set of digits, but allows to inherit the kerning information of the real small caps font.

Another option for an expertized installation would be to make the real small caps fonts unavailable, so that \latinfamily will attempt to fake a small caps font using glyphs from the standard and expert fonts in normal shape. This means that \encoding_shape is again set to ‘c’, so that OT1c.etx and T1c.etx are used, but this time a glyph named ‘Asmall’ does exist in the expert font and will be used instead of faked one generated by scaling. The outcome will be a font based on normal and small caps glyphs from the standard and expert fonts. The oldstyle digits will only be used if they are called for, otherwise the default digits from the roman font are used. The only drawback of this approach is that the kerning around small capital letters will be based on the scaled kern amounts of the capital letters rather than on the kern pairs from the real small caps font.

Finally, the most promising approach of all these options would be to combine the glyphs from standard and expert fonts with kern pairs from the real small caps fonts. Although it is possible to achieve this with extensive reshuffling of glyph names and using a modified version of latin.mtx, it would be far too complicated to integrate into the \latinfamily, so it is not implemented in this version, although it would be a worthwile approach.

The fontinst package

6 Preliminaries

6.1 Initialization

Some default catcode assignments, in case we are using iniTEX.

1 ⟨∗pkg⟩

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

6 ⟨/pkg⟩

\fontinstversion If we are running under iniTEX we cannot put the identification stuff any earlier than this. Note that \fontinstversion is not just used for indentification but

also in \needsfontinstversion.

7 ⟨∗pkg | doc⟩

 8 \def\fontinstversion{1.800}
 9 \def\filedate{1998/06/30}
10 \def\docdate{1998/06/30}

11 ⟨/pkg | doc⟩

If we are running under iniTEX or plain, we have to get around the L^{A}TEX-

specific \ProvidesPackage stuff.

12 ⟨∗pkg | doc⟩

13 \ifx\ProvidesPackage\undefined
14 \def\NeedsTeXFormat#1{}
15 \def\ProvidesPackage#1[#2]{}
16 \fi

17 ⟨/pkg | doc⟩

Now we can identify ourselves as usual.

18 ⟨doc⟩\ProvidesPackage{fontdoc}
19 ⟨pkg⟩\ProvidesPackage{fontinst}
20 ⟨pkg | doc⟩[\filedate\space v\fontinstversion\space
21 ⟨doc⟩ fontinst documentation package]
22 ⟨pkg⟩ fontinst installation package]

Save the current values of the catcodes: @ and _are made letters, ~ is made a space, and space and newline are ignored.

23 ⟨∗pkg⟩

24 \edef\spacecatcode{\the\catcode`\ }
25 \edef\nlcatcode{\the\catcode`\^^M}
26 \edef\atcatcode{\the\catcode`\@}
27 \edef\underscorecatcode{\the\catcode`\_}
28 \edef\tildecatcode{\the\catcode`\~}
29 \catcode`\ =9
30 \catcode`\^^M=9
31 \catcode`\@=11
32 \catcode`\_=11
33 \catcode`\~=10

6.2 Plain TEX macros from fontinst.ini

If we’re running in iniTEX we input some definitions taken from plain.

34 \ifx\@ne\undefined_command
35 \input fontinst.ini\relax
36 \fi

37 ⟨/pkg⟩

38 ⟨∗ini⟩

39 \chardef\active=13

40

41 \chardef\@ne=1
42 \chardef\tw@=2
43 \chardef\thr@@=3
44 \chardef\sixt@@n=16
45 \chardef\@cclv=255
46 \mathchardef\@cclvi=256
47 \mathchardef\@m=1000
48 \mathchardef\@M=10000
49 \mathchardef\@MM=20000

50

51 \count10=22 % allocates \count registers 23, 24, ...
52 \count11=9 % allocates \dimen registers 10, 11, ...
53 \count15=9 % allocates \toks registers 10, 11, ...
54 \count16=-1 % allocates input streams 0, 1, ...
55 \count17=-1 % allocates output streams 0, 1, ...
56 \count20=255 % allocates insertions 254, 253, ...
57 \countdef\insc@unt=20 % the insertion counter
58 \countdef\allocationnumber=21 % the most recent allocation
59 \countdef\m@ne=22 \m@ne=-1 % a handy constant
60 \def\wlog{\immediate\write\m@ne} % write on log file (only)

61

62 \countdef\count@=255
63 \dimendef\dimen@=0

64

65 \outer\def\newcount{\alloc@0\count\countdef\insc@unt}
66 \outer\def\newdimen{\alloc@1\dimen\dimendef\insc@unt}
67 \outer\def\newtoks{\alloc@5\toks\toksdef\@cclvi}
68 \outer\def\newread{\alloc@6\read\chardef\sixt@@n}
69 \outer\def\newwrite{\alloc@7\write\chardef\sixt@@n}

70

71 \def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
72 \ch@ck#1#4#2% make sure there's still room
73 \allocationnumber=\count1#1%
74 \global#3#5=\allocationnumber
75 \wlog{\string#5=\string#2\the\allocationnumber}}
76 \outer\def\newinsert#1{\global\advance\insc@unt by\m@ne
77 \ch@ck0\insc@unt\count
78 \ch@ck1\insc@unt\dimen
79 \ch@ck2\insc@unt\skip
80 \ch@ck4\insc@unt\box
81 \allocationnumber=\insc@unt
82 \global\chardef#1=\allocationnumber
83 \wlog{\string#1=\string\insert\the\allocationnumber}}
84 \def\ch@ck#1#2#3{\ifnum\count1#1<#2%

 85 \else\errmessage{No~room~for~a~new~#3}\fi}

86

 87 \outer\def\newif#1{\count@\escapechar \escapechar\m@ne
 88 \expandafter\expandafter\expandafter
 89 \edef\@if#1{true}{\let\noexpand#1=\noexpand\iftrue}%
 90 \expandafter\expandafter\expandafter
 91 \edef\@if#1{false}{\let\noexpand#1=\noexpand\iffalse}%
 92 \@if#1{false}\escapechar\count@} % the condition starts out false
 93 \def\@if#1#2{\csname\expandafter\if@\string#1#2\endcsname}
 94 {\uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}} % `if' is required

95

 96 \newdimen\p@ \p@=1pt % this saves macro space and time
 97 \newdimen\z@ \z@=0pt % can be used both for 0pt and 0

98

 99 \def\space{~}
100 \let\bgroup={
101 \let\egroup=}

102

103 \def\loop#1\repeat{\def\body{#1}\iterate}
104 \def\iterate{\body \let\next\iterate \else\let\next\relax\fi \next}
105 \let\repeat=\fi % this makes \loop...\if...\repeat skippable

106

107 \def\supereject{\par\penalty-\@MM}
108 \outer\def\bye{\par\vfill\supereject\end}
109 \everyjob{%
110 \csname~if_file_exists\endcsname{fontinst.rc}\then
111 \primitiveinput~fontinst.rc
112 \else
113 \immediate\write16{No~file~fontinst.rc.}
114 \fi

115 } 116 ⟨/ini⟩

6.3 Declaring variables and constants

Some temporary variables:

117 ⟨∗pkg⟩

118 \newcount\a_count
119 \newcount\b_count
120 \newcount\c_count
121 \newcount\d_count
122 \newcount\e_count
123 \newcount\f_count
124 \newcount\g_count
125 \newdimen\a_dimen
126 \newdimen\b_dimen
127 \newdimen\c_dimen
128 \newdimen\d_dimen
129 \newtoks\a_toks
130 \newtoks\b_toks
131 \newtoks\c_toks

\out_file Some global variables:

132 \newwrite\out_file

Some constants:

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

6.4 Trigonometry macros

Include David Carlisle’s trigonometry macros. First, do some hacks to get round all that \NeedsTeXFormat{LaTeX2e} stuff that David put in :-) In v1.8 these hacks been moved to an earlier place since we put in \ProvidesPackage ourselves.

135 \let\@tempdima\a_dimen
136 \let\@tempdimb\b_dimen
137 \input trig.sty

7 TEX hackery

7.1 Utiltiy macros

\x_cs \x_relax \g_let
138 \def\x_cs#1#2{\expandafter#1\csname#2\endcsname}
139 \let\x_relax=\relax
140 \def\g_let{\global\let}
\empty_command
\gobble_one
\gobble_two
\gobble_three
\identity_one
\first_of_two
\second_of_two

141 \def\empty_command{}
142 \def\gobble_one#1{}
143 \def\gobble_two#1#2{}
144 \def\gobble_three#1#2#3{}
145 \def\identity_one#1{#1}
146 \def\first_of_two#1#2{#1}
147 \def\second_of_two#1#2{#2}
\percent_char
\left_brace_char
\right_brace_char

148 \bgroup
149 \catcode`\[=1
150 \catcode`\]=2
151 \catcode`\%=12
152 \catcode`\{=12
153 \catcode`\}=12
154 \gdef\percent_char[%]
155 \gdef\left_brace_char[{]
156 \gdef\right_brace_char[}]
157 \egroup

\lose_measure Get rid of a trailing pt when converting dimension.

158 {

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

162 }

\first_char Return the first character of a string.

163 \def\first_char#1#2={#1}

\add_to Append a element list to a token list.

164 \def\add_to#1#2{
165 \ifx#1\relax
166  \def#1{#2}
167 \else
168  \expandafter\def\expandafter#1\expandafter{#1#2}
169 \fi

170 }

\never_do The command \do, protected from expansion.

171 \def\never_do{\noexpand\do}

7.2 Writing to .fd files

\open_out \close_out \out_line \out_lline \out_llline
172 \def\open_out#1{
173 \immediate\openout\out_file=#1 \def\out_filename{#1}}
174 \def\close_out#1{
175 \immediate\write16{#1~written~on~\out_filename.}
176 \immediate\closeout\out_file}
177 \def\out_line#1{\immediate\write\out_file{#1}}
178 \def\out_lline#1{\out_line{\space\space\space#1}}
179 \def\out_llline#1{\out_lline{\space\space\space#1}}

7.3 Conditionals

\if_true \if_false In order to write macros that expand out to nested \if-statements, I say:

      \ifblah...\then...\else...\fi

In order to match the \fi, \then has to be an \if.

180 \let\then=\iffalse
181 \def\if_false{\iffalse}
182 \def\if_true{\iftrue}

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

183 \def\if_or#1\or_else#2\then{
184 #1\then
185  \expandafter\if_true
186 \else
187  #2\then
188  \expandafter\expandafter\expandafter\if_true
189  \else
190  \expandafter\expandafter\expandafter\if_false
191  \fi
192 \fi

193 }

\if_file_exists  \if_file_exists checks to see if a file exits, using \openin.
194 \def\if_file_exists#1\then{
195 \immediate\openin1=#1\relax
196 \ifeof1\relax
197  \immediate\closein1
198  \expandafter\if_false
199 \else
200  \immediate\closein1
201  \expandafter\if_true
202 \fi

203 }

\primitiveinput If \@@input is defined, I’ll assume it’s the L^{A}TEX version of the TEX \input primitive. I need this so that I can say \expandafter\primitiveinput foo, which doesn’t work with the L^{A}TEX version of \input.

204 \x_cs\ifx{@@input}\relax
205 \let\primitiveinput=\input
206 \else
207 \let\primitiveinput=\@@input
208 \fi

7.4 Setting variables

\setint The macros:

\setstr
\setdim
\setcommand

\setint{INT}{INTEGER EXPRESSION}
\setstr{STR}{STRING}
\setdim{DIM}{DIMENSION}
\setcommand \COMMAND DEFINITION
define new macros \i-INT, \s-STR, \d-DIM or \COMMAND.

\resetint The macros:

\resetstr
\resetdim
\resetcommand

\resetint{INT}{INTEGER EXPRESSION}
\resetstr{STR}{STRING}
\resetdim{DIM}{DIMENSION}
\resetcommand \COMMAND DEFINITION
redefine the macros \i-INT, \s-STR, \d-DIM or \COMMAND.

\int The macros:

\str
\dim

\int{INT}
\str{STR}
\dim{DIM}
\COMMAND
return the values of \i-INT, \s-STR, \d-DIM or \COMMAND.

\ifisint The macros:

\ifisstr
\ifisdim
\ifiscommand

\ifisint{INT}\then
\ifisstr{STR}\then
\ifisdim{DIM}\then
\ifiscommand\COMMAND\then

 return \if_true if \i-INT, \s-STR or \d-DIM have been defined, and \if_false

otherwise.

\unsetint The macros:

\unsetstr
\unsetdim
\unsetcommand

      \unsetint{INT}
      \unsetstr{STR}
      \unsetdim{DIM}
      \unsetcommand \COMMAND
 undefine \i-INT, \s-STR, \d-DIM or \COMMAND.

Integers are kept as \mathchardefs if possible. I compared the version where you try to keep ints as \mathchardefs with the version where you don’t bother, and for a sample font without \mathchardefs I got:

114673 words of memory out of 150001 Time elapsed: 135.0 seconds

and with, I got:

114050 words of memory out of 150001 Time elapsed: 134.5 seconds

so I’ve saved a little memory and time. Not brilliant, but I may as well keep it in.

\setint \setstr \setdim \setcommand
209 \def\setint#1#2{
210 \x_cs\ifx{i-#1}\relax
211  \resetint{#1}{#2}
212 \fi

213 }

214 \def\setstr#1#2{\x_cs\ifx{s-#1}\relax
215 \x_cs\edef{s-#1}{#2}\fi}
216 \def\setdim#1#2{\x_cs\ifx{d-#1}\relax
217 \a_dimen=#2\relax\x_cs\edef{d-#1}{\the\a_dimen}\fi}
218 \def\setcommand#1{\ifx#1\undefined_command
219 \expandafter\def\expandafter#1\else
220 \expandafter\def\expandafter\a_command\fi}
\resetint
\resetstr
\resetdim
\resetcommand

221 \def\resetint#1#2{
222 \eval_expr{#2}
223 \ifnum\result<\max_mathchardef
224  \ifnum\result<0
225  \x_cs\edef{i-#1}{\the\result}
226  \else
227  \x_cs\mathchardef{i-#1}=\result
228  \fi
229 \else
230  \x_cs\edef{i-#1}{\the\result}
231 \fi

232 }

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

\int \str \dim
236 \def\int#1{\csname~i-#1\endcsname}
237 \def\str#1{\csname~s-#1\endcsname}
238 \def\dim#1{\csname~d-#1\endcsname}
\ifisint
\ifisstr
\ifisdim
\ifiscommand

239 \def\ifisint#1\then{\x_cs\ifx{i-#1}\relax\expandafter\if_false
240 \else\expandafter\if_true\fi}
241 \def\ifisstr#1\then{\x_cs\ifx{s-#1}\relax\expandafter\if_false
242 \else\expandafter\if_true\fi}
243 \def\ifisdim#1\then{\x_cs\ifx{d-#1}\relax\expandafter\if_false
244 \else\expandafter\if_true\fi}
245 \def\ifiscommand#1\then{\ifx#1\undefined_command\expandafter\if_false
246 \else\expandafter\if_true\fi}
\unsetint
\unsetstr
\unsetdim
\unsetcommand

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

7.5 Integer expressions

\eval_expr \eval_expr_to \g_eval_expr_to The macro:
      \eval_expr{INTEGER EXPRESSION}

globally assigns \result to the value of INTEGER EXPRESSION, and changes the value of no other counters.

The macro:

      \eval_expr_to{VARIABLE}{INTEGER EXPRESSION}
 locally assigns the value of INTEGER EXPRESSION to VARIABLE. \g_eval_expr_to

does the same globally.

251 \newcount\result
252 \def\eval_expr#1{\global\result=#1\relax}
253 \def\eval_expr_to#1#2{\eval_expr{#2}#1=\result}
254 \def\g_eval_expr_to#1#2{\eval_expr{#2}\global#1=\result}

\neg \add \sub \mul \div \max \min \scale These macros return an integer expression:

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

255 \def\neg#1{#1\global\result=-\result}
256 \def\add#1#2{#1{\a_count=\result\eval_expr{#2}
257 \global\advance\result by \a_count}}
258 \def\sub#1#2{#1{\a_count=\result\eval_expr{#2}
259 \advance\a_count by -\result
260 \global\result=\a_count}}
261 \def\mul#1#2{#1{\a_count=\result\eval_expr{#2}
262 \global\multiply\result by \a_count}}
263 \def\div#1#2{#1{\a_count=\result\eval_expr{#2}
264 \divide\a_count by \result
265 \global\result=\a_count}}
266 \def\max#1#2{#1{\a_count=\result\eval_expr{#2}
267 \ifnum\a_count>\result \global\result=\a_count \fi}}
268 \def\min#1#2{#1{\a_count=\result\eval_expr{#2}
269 \ifnum\a_count<\result \global\result=\a_count \fi}}
270 \def\scale#1#2{#1{\a_count=\result\eval_expr{#2}
271 \global\multiply\result by \a_count
272 \global\divide\result by \one_thousand}}

8 Reading and parsing input files

8.1 Converting an ENC file to an ETX file

\enctoext The macro:
      \enctoetx{ENCFILE}{ETXFILE}

reads ENCFILE.enc and writes the same information to ETXFILE.etx, in a format TEX can read more easily.

Each /GLYPH command is recorded in a macro \o-GLYPH, which expands to a

 corresponding \setslot{GLYPH} ... \endslot statement.
273 \newif\ifmissingslots
274 \x_cs\def{o-.notdef}#1{\global\missingslotstrue}
\enctoext

275 {

276 \catcode`\/=\active
277 \catcode`\]=\active
278 \gdef\enctoetx#1#2{{
279  \catcode`\/=\active
280  \catcode`\]=\active
281  \def/##1[{
282  \a_count=0
283  \global\missingslotsfalse
284  \def/####1~{
285  \csname~o-####1\endcsname{
286  \ifmissingslots
287  \out_line{\string\nextslot{\the\a_count}}
288  \fi
289  \global\missingslotsfalse
290  \out_line{\string\setslot{####1}}
291  \out_line{\string\endsetslot}
292  \out_line{}

294  \advance\a_count by 1

295 } 296 }

297  \def]~def{}
298  \make_etx{#1}{#2}

299 }} 300 }

    \make_etx finishes the job of \enctoext.
301 \def\make_etx#1#2{
302 \open_out{\temp_prefix#2.etx}
303 \out_line{\percent_char~Filename:~#2.etx}
304 \out_line{\percent_char~Created~by:~tex~\jobname}
305 \out_line{\percent_char~Created~using:~\string\enctoetx{#1}{#2}}
306 \out_line{}
307 \out_line{\percent_char~This~file~contains~the
308  information~of~#1.enc~in~a~form}
309 \out_line{\percent_char~more~easily~read~by~TeX.
310  It~is~used~by~the~fontinst~package.}
311 \out_line{}
312 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
313 \out_line{}
314 \out_line{\string\relax}
315 \out_line{}
316 \out_line{\string\documentclass[twocolumn]{article}}
317 \out_line{\string\usepackage{fontdoc}}
318 \out_line{}
319 \out_line{\string\begin{document}}
320 \out_line{}
321 \out_line{This~document~describes~the~#1~encoding.}
322 \out_line{It~was~automatically~generated~by~the}
323 \out_line{{\string\tt\space~fontinst}~package.}
324 \out_line{}
325 \out_line{\string\encoding}
326 \out_line{}
327 \out_line{\string\needsfontinstversion{\fontinstversion}}
328 \out_line{}
329 \primitiveinput #1.enc\relax
330 \out_line{}
331 \out_line{\string\endencoding}
332 \out_line{}
333 \out_line{\string\end{document}}
334 \close_out{Encoding~vector}

335 }

8.2 Converting an AFM file to an MTX file

\afmtomtx The macro:
      \afmtomtx{AFMFILE}{MTXFILE}

reads AFMFILE.afm, and writes the same information out to MTXFILE.mtx.

\afmtomtx
336 \def\afmtomtx#1#2{{
337 \open_out{\temp_prefix#2.mtx}
338 \def\raw_font_name{#2}
339 \_italicfalse
340 \setint{minimumkern}{0}
341 \minimum_kern=\int{minimumkern}
342 \out_line{\percent_char~Filename:~#2.mtx}
343 \out_line{\percent_char~Created~by:~tex~\jobname}
344 \out_line{\percent_char~Created~using:~\string\afmtomtx{#1}{#2}}
345 \out_line{}
346 \out_line{\percent_char~This~file~contains~the
347  information~of~#1.afm~in~a~form}
348 \out_line{\percent_char~more~easily~read~by~TeX.~
349  It~is~used~by~the~fontinst~package.}
350 \out_line{}
351 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
352 \out_line{}
353 \out_line{\string\relax}
354 \out_line{\string\metrics}
355 \out_line{}
356 \out_line{\string\needsfontinstversion{\fontinstversion}}
357 \out_line{}
358 \catcode`\^^M=12
359 \catcode`\ =10
360 \expandafter\afm_line\primitiveinput #1.afm\relax
361 \out_line{}
362 \out_line{\string\endmetrics}
363 \close_out{Metrics}

364 }}

Kerns below this value are ignored.

365 \newcount\minimum_kern

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

366 \newif\if_italic

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

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

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

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

This all stops when we reach the command EndFontMetrics.

371 \x_cs\def{afm-EndFontMetrics}#1\afm_line{\endinput}
    To define an AFM command, you say \afm_def{COMMAND}(PATTERN){RESULT}
372 \def\afm_def#1(#2)#3{\x_cs\def{afm-#1}
373 \gobble_one_line#2\end_of_line{#3}}

For example, we can define the following AFM commands: (Fixed by Thierry

 Bouche <Thierry.Bouche@ujf-grenoble.fr> 1997/02/07, to get fontdimens

comparable to EC fonts.)

374 \afm_def{CharWidth}(#1){\charxwidth=#1\relax}
375 \afm_def{ItalicAngle}(#1){\calculate_it_slant{#1}}
376 \afm_def{XHeight}(#1){
377 \out_line{\string\setint{xheight}{#1}}}
378 \afm_def{CapHeight}(#1){
379 \out_line{\string\setint{capheight}{#1}}}
380 \afm_def{Ascender}(#1){
381 \out_line{\string\setint{ascender}{#1}}}
382 \afm_def{Descender}(#1){
383 \out_line{\string\setint{descender_neg}{#1}}}
384 \afm_def{UnderlineThickness}(#1){
385 \out_line{\string\setint{underlinethickness}{#1}}}
386 \afm_def{FontBBox}(#1~#2~#3~#4){
387 \out_line{\string\setint{maxheight}{#4}}
388 \out_line{\string\setint{maxdepth_neg}{#2}}}
389 \afm_def{IsFixedPitch}(#1){
390 \if\first_char#1=f
391 \else\out_line{\string\setint{monowidth}{1}}
392 \fi

393 }

Processing kern pairs. If one of the glyph name starts with a dot as in .notdef or .null the kern pair is ignored.

394 \afm_def{KP}(#1~#2~#3~#4){
395 \if\first_char#1=.\else
396 \if\first_char#2=.\else
397  \ifnum#3>\minimum_kern\relax
398  \out_line{\string\setkern{#1}{#2}{#3}}
399  \else\ifnum#3<-\minimum_kern\relax
400  \out_line{\string\setkern{#1}{#2}{#3}}
401  \fi\fi
402 \fi\fi

403 }

404 \afm_def{KPX}(#1~#2~#3~#4){
405 \if\first_char#1=.\else
406 \if\first_char#2=.\else
407  \ifnum#3>\minimum_kern\relax
408  \out_line{\string\setkern{#1}{#2}{#3}}
409  \else\ifnum#3<-\minimum_kern\relax
410  \out_line{\string\setkern{#1}{#2}{#3}}
411  \fi\fi
412 \fi\fi

413 }

Processing char metrics.

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

Processing composite chars.

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

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

417 \newcount\char_slot
418 \newcount\char_x_width
419 \newcount\x_width
420 \newcount\bbox_llx
421 \newcount\bbox_lly
422 \newcount\bbox_urx
423 \newcount\bbox_ury
424 \let\char_name=\empty_command

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

425 \def\init_afm#1{
426 \char_slot=#1\relax
427 \x_width=\char_x_width
428 \bbox_llx=0
429 \bbox_lly=0
430 \bbox_urx=0
431 \bbox_ury=0
432 \let\char_name=\empty_command

433 }

\afm_char writes the values of these variables to the .mtx file, and saves them in a macro \g-GLYPHNAME, in the form:

      {WIDTH}{HEIGHT}{DEPTH}{ITALIC}

These are needed, because the (grumble grumble) syntax of CC commands doesn’t include the glyph measurements, so we have to remember them.

434 \def\afm_char{
435 \a_count=-\bbox_lly
436 \if_italic
437  \b_count=-\x_width
438  \advance\b_count by \bbox_urx
439  \ifnum\b_count>0\else
440  \b_count=0
441  \fi
442 \else
443  \b_count=0
444 \fi
445 \out_line{
446  \ifnum\char_slot>-1
447  \string\setrawglyph
448  \else
449  \string\setnotglyph
450  \fi
451  {\char_name}
452  {\raw_font_name}
453  {10pt}
454  {\the\char_slot}
455  {\the\x_width}
456  {\the\bbox_ury}
457  {\the\a_count}
458  {\the\b_count}

459 } 460 }

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

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

464 }

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

468 }

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

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

477 }

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

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

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

484 }

485 \def\gobble_one_semi#1;{}

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

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

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

487 \list_def{W}(#1~#2){\x_width=#1\relax}
488 \list_def{WX}(#1){\x_width=#1\relax}
489 \list_def{WY}(#1){}
490 \list_def{N}(#1){\def\char_name{#1}}
491 \list_def{B}(#1~#2~#3~#4){
492 \bbox_llx=#1\relax
493 \bbox_lly=#2\relax
494 \bbox_urx=#3\relax
495 \bbox_ury=#4\relax

496 }

497 \list_def{PCC}(#1~#2~#3){
498 \out_lline{\string\glyphpcc{#1}{#2}{#3}}

499 }

8.3 Converting a PL file to an MTX file

\pltomtx The macro:

      \pltomtx{PLFILE}{MTXFILE}

reads PLFILE.pl, and writes the same information out to MTXFILE.mtx. It can’t cope with SKIP commands.

\pltomtx
500 \def\pltomtx#1#2{{
501 \def\raw_font_name{#1}
502 \open_out{\temp_prefix#2.mtx}
503 \out_line{\percent_char~Filename:~#2.mtx}
504 \out_line{\percent_char~Created~by:~tex~\jobname}
505 \out_line{\percent_char~Created~using:~\string\pltomtx{#1}{#2}}
506 \out_line{}
507 \out_line{\percent_char~This~file~contains~the~
508  information~of~#1.pl~in~a~form}
509 \out_line{\percent_char~more~easily~read~by~TeX.~
510  It~is~used~by~the~fontinst~package.}
511 \out_line{}
512 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
513 \out_line{}
514 \out_line{\string\relax}
515 \out_line{\string\metrics}
516 \out_line{}
517 \out_line{\string\needsfontinstversion{\fontinstversion}}
518 \out_line{}
519 \catcode`\(=0 \catcode`\)=9
520 \let\/=\ignore_parens
521 \let\do_pl_glyph=\relax
522 \primitiveinput #1.pl\relax
523 \do_pl_glyph
524 \out_line{}
525 \out_line{\string\endmetrics}
526 \close_out{Metrics}

527 }}

To parse a .pl file, we first make ( the escape character, make ) ignored, then define the various PL commands.

We can ignore a parenthesis matched string by making ( and ) the group delimiters, then gobbling them up.

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

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

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

Convert a PL int to a TEX int, assuming it’s prefixed by C, D, O, or H.

534 \def\pl_int#1#2{

535 \ifx#1C `#2
536 \else\ifx#1D #2
537 \else\ifx#1O '#2
538 \else\ifx#1H "#2
539 \else\errmessage{Unknown~PL~number~prefix~`#1'}
540 \fi\fi\fi\fi

541 }

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

542 \let\COMMENT=\ignore_parens
543 \let\FAMILY=\ignore_parens
544 \let\FACE=\ignore_parens
545 \let\CHECKSUM=\ignore_parens
546 \let\BOUNDARYCHAR=\ignore_parens
547 \let\LIG=\ignore_parens
548 \let\NEXTLARGER=\ignore_parens
549 \let\VARCHAR=\ignore_parens

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

The corresponding ENCODING is specified by \declareencoding statements (see

 below). Each \declare_encdoing defines a macro \enc-CODINGSCHEME which

expands to ENCODING.

550 \def\CODINGSCHEME{\bgroup\catcode`\)=12\relax\CODINGSCHEME_cont}
551 \def\CODINGSCHEME_cont#1){
552 \egroup
553 \x_cs\ifx{enc-#1}\relax
554  \errhelp{The~encoding~`#1'~has~not~been~declared.^^J
555  You~should~declare~it~with~\string\declareencoding{#1}{ETXFILE}.^^J
556  Press~<RETURN>~to~carry~on~with~fingers~crossed,^^J
557  or~X~<RETURN>~to~exit.}
558  \errmessage{Undeclared~encoding~`#1'}
559 \else
560  \def\do_slot{\x_cs\let{name-\the\slot_number}\slot_name}
561  \catcode`\(=12 \catcode`\)=12
562  \x_cs\inputetx{enc-#1}\relax
563  \catcode`\(=0 \catcode`\)=9
564 \fi

565 }

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

569 }

570 \def\DESIGNUNITS~#1~#2~{
571 \a_dimen=#2pt
572 \out_line{\string\setdim{designunits}{\the\a_dimen}}

573 }

The following fontdimens are converted to ints and written out to the .mtx file.

574 \let\FONTDIMEN=\relax
575 \def\SLANT~R~#1~{\out_line{\string\setint{italicslant}{\pl_real{#1}}}}

576 \def\SPACE~R~#1~{\out_line{\string\setint{interword}{\pl_real{#1}}}}
577 \def\STRETCH~R~#1~{\out_line{\string\setint{stretchword}{\pl_real{#1}}}}
578 \def\SHRINK~R~#1~{\out_line{\string\setint{shrinkword}{\pl_real{#1}}}}
579 \def\XHEIGHT~R~#1~{\out_line{\string\setint{xheight}{\pl_real{#1}}}}
580 \def\QUAD~R~#1~{\out_line{\string\setint{quad}{\pl_real{#1}}}}
581 \def\EXTRASPACE~R~#1~{\out_line{\string\setint{extraspace}{\pl_real{#1}}}}
582 \def\DEFAULTRULETHICKNESS~R~#1~{
583 \out_line{\string\setint{underlinethickness}{\pl_real{#1}}}

584 }

The following fontdimens are ignored.

585 \def\HEADER~#1~#2~#3~#4~{}
586 \def\SEVENBITSAFEFLAG~#1~{}
587 \def\PARAMETER~#1~#2~#3~#4~{}
588 \def\NUM#1~#2~#3~{}
589 \def\DENOM#1~#2~#3~{}
590 \def\SUP#1~#2~#3~{}
591 \def\SUB#1~#2~#3~{}
592 \def\SUBDROP~#1~#2~{}
593 \def\SUPDROP~#1~#2~{}
594 \def\DELIM#1~#2~#3~{}
595 \def\AXISHEIGHT~#1~#2~{}
596 \def\BIGOPSPACING#1~#2~#3~{}

The following ligtable commands are processed.

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

605 }

606 \def\write_pl_krn#1#2#3{
607 \f_count=#1
608 \g_count=#3
609 \out_line{\string\setkern{\csname~name-\the\g_count\endcsname}
610  {\csname~name-\the\f_count\endcsname}
611  {#2}}

612 }

The following character metrics are processed.

613 \def\CHARWD~R~#1~{\b_count=\pl_real{#1}}
614 \def\CHARHT~R~#1~{\c_count=\pl_real{#1}}
615 \def\CHARDP~R~#1~{\d_count=\pl_real{#1}}
616 \def\CHARIC~R~#1~{\e_count=\pl_real{#1}}
617 \def\CHARACTER~#1~#2~{
618 \do_pl_glyph
619 \a_count=\pl_int{#1}{#2}
620 \b_count=0
621 \c_count=0
622 \d_count=0
623 \e_count=0

624 \let\do_pl_glyph=\write_pl_glyph

625 }

626 \def\write_pl_glyph{
627  \x_cs\ifx{name-\the\a_count}\relax\else
628  \out_line{\string\setrawglyph
629  {\csname~name-\the\a_count\endcsname}
630  {\raw_font_name}
631  {\the\a_dimen}
632  {\the\a_count}
633  {\the\b_count}
634  {\the\c_count}
635  {\the\d_count}
636  {\the\e_count}}
637  \fi

638 }

9 Encoding files

\inputetx The macro:
      \inputetx{FILENAME}

inputs FILENAME.etx, ignoring anything between \relax and \encoding, and anything after \endencoding.

The file name is transformed to lowercase before opening.

\inputetx
639 \def\inputetx#1{
640 \edef\lowercase_file{\lowercase{
641  \edef\noexpand\lowercase_file{#1}}}
642 \lowercase_file
643 \slot_number=0
644 \def\relax{\let\relax=\x_relax\iffalse}
645 \let\encoding=\fi
646 \let\endencoding=\endinput
647 \primitiveinput \lowercase_file.etx\x_relax
648 \let\relax=\x_relax

649 }

\setslot \endsetslot \slot_name  \setslot{NAME} SLOT COMMANDS \endsetslot

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

650 \def\setslot#1{\edef\slot_name{#1}\do_slot}
651 \def\endsetslot{\end_do_slot\advance\slot_number by 1\relax}
652 \let\do_slot\empty_command
653 \let\do_new_slot\empty_command
654 \let\end_do_slot\empty_command
\nextslot \skipslots \slot_number  \nextslot{INTEGER EXPRESSION}
 \skipslots{INTEGER EXPRESSION}

\nextslot sets the \slot_number. \skipslots addvances the \slot_number.
655 \newcount\slot_number
656 \def\nextslot#1{\slot_number=#1\relax}
657 \def\skipslots#1{\advance\slot_number by #1\relax}
\ligature \nextlarger \varchar \comment The SLOT COMMANDS are:
\ligature{LIG}{GLYPH}{GLYPH}
\nextlarger{GLYPH}
\varchar VARCHAR COMMANDS \endvarchar
\comment{TEXT}
\usedas{COMMAND}{TYPE}

By default, these do nothing, but are over-ridden later.

658 \let\ligature=\gobble_three
659 \let\nextlarger=\gobble_one
660 \let\varchar=\empty_command
661 \let\endvarchar=\empty_command
662 \let\comment=\gobble_one
663 \let\usedas=\gobble_two
\vartop \varmid \varbot \varrep The VARCHAR COMMANDS are:
\vartop{GLYPH}
\varmid{GLYPH}
\varbot{GLYPH}
\varrep{GLYPH}
664 \let\vartop=\gobble_one
665 \let\varmid=\gobble_one
666 \let\varbot=\gobble_one
667 \let\varrep=\gobble_one
\useexamplefont \slotexample \setslotcomment \resetslotcomment \unsetslotcomment These macros were recently added in the fontdoc package. They do nothing in

fontinst, just gobble their arguments.

668 \let\useexamplefont=\gobble_one
669 \let\slotexample=\empty_command
670 \let\setslotcomment=\gobble_one
671 \let\resetslotcomment=\gobble_one
672 \let\unsetslotcomment=\empty_command

10 Metric files

\inputmtx The macro:
\inputmtx{FILENAME}

inputs FILENAME.mtx, ignoring anything between \relax and \metrics, and any-

thing after \endmetrics.
\inputmtx
673 \def\inputmtx#1{
674 \a_count=0

675 \def\relax{\let\relax=\x_relax\iffalse}
676 \let\metrics=\fi
677 \let\endmetrics=\endinput
678 \primitiveinput #1.mtx\x_relax
679 \let\relax=\x_relax

680 }

10.1 Kerning information

The kerning information is kept in the macros \l-NAME and \r-NAME, containing information about how NAME kerns on the left and on the right, respectively. The \l-NAME macro should expand out to a series of \k\r-NAME\AMOUNT macros, and vice versa.

Where possible, we avoid re-scaling, which saves a bit of time and memory. With a sample font, the version where we didn’t avoid re-scaling used:

114050 words of memory out of 150001 Time elapsed: 134.5 seconds

whereas the version where we do avoid it used:

113786 words of memory out of 150001 Time elapsed: 124.9 seconds

We keep the names of the glyphs to kern with as \l-NAME and \r-NAME to save on token space, and this got the resources used down to:

88574 words of memory out of 150001 Time elapsed: 106.1 seconds

Keeping track of the kern amounts as \AMOUNT got the resources used down to:

75424 words of memory out of 150001 Time elapsed: 97.2 seconds

Mind you, I then added all the \transformfont stuff, and it went back to:

77079 words of memory out of 150001 Time elapsed: 97.7 seconds

\setkern  \setkern{GLYPH1}{GLYPH2}{INTEGER EXPERESSION}

Sets a kern pair between GLYPH1 and GLYPH2 to the specified value, which is typically a value returned by \kerning{GLYPH3}{GLYPH4}.

681 \def\setkern#1#2#3{
682 \x_cs\ifx{i-rawscale}\relax
683  \expandafter\set_kern
684  \csname~r-#1\expandafter\endcsname
685  \csname~l-#2\endcsname{#3}
686 \else
687  \expandafter\set_kern
688  \csname~r-#1\expandafter\endcsname
689  \csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}}
690 \fi

691 }

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

695 }

696 \def\set_kern_cs#1#2#3{
697 \add_to#2{\k#3#1}
698 \add_to#3{\k#2#1}

699 }

\setleftkerning \setrightkerning \setleftrightkerning  \setleftkerning{GLYPH1}{GLYPH2}{SCALED}
 \setrightkerning{GLYPH1}{GLYPH2}{SCALED}
 \setleftrightkerning{GLYPH1}{GLYPH2}{SCALED}

Sets left or right kerning of GLYPH1 to that of GLYPH2 scaled by SCALED.

 \setleftrightkerning does both.
700 \def\setleftkerning#1#2#3{
701 \eval_expr_to\b_count{#3}
702 \expandafter\set_kerning
703  \csname~l-#1\expandafter\endcsname
704  \csname~l-#2\endcsname

705 }

706 \def\setrightkerning#1#2#3{
707 \eval_expr_to\b_count{#3}
708 \expandafter\set_kerning
709  \csname~r-#1\expandafter\endcsname
710  \csname~r-#2\endcsname

711 }

712 \def\setleftrightkerning#1#2#3{
713 \eval_expr_to\b_count{#3}
714 \expandafter\set_kerning
715  \csname~l-#1\expandafter\endcsname
716  \csname~l-#2\endcsname
717 \expandafter\set_kerning
718  \csname~r-#1\expandafter\endcsname
719  \csname~r-#2\endcsname

720 }

721 \def\set_kerning#1#2{
722 \if\b_count=\one_thousand
723  \def\k##1##2{
724  \set_kern_cs##2##1#1

725 }

726 \else
727  \def\k##1##2{
728  \set_kern##1#1{
729  \scale\b_count{\expandafter\gobble_one\string##2}

730 } 731 }

732 \fi

733 #2 734 }

\kerning  \kerning{GLYPH1}{GLYPH2}

Returns the value of kern pair between GLYPH1 and GLYPH2 as an integer. Returns a value of zero if such a kern pair doesn’t exist.

735 \def\kerning#1#2{0\relax
736 \def\k##1{\csname~set-\string##1\endcsname\gobble_one}
737 \bgroup
738 \x_cs\def{set-\string\l-#2}##1##2{
739  \global\result=\expandafter\gobble_one\string##2\egroup

740 }

741 \csname~r-#1\endcsname
742 \csname~set-\string\l-#2\endcsname\gobble_one{00}

743 }

10.2 Glyph information

The glyph information is kept in the macros \g-NAME, which expands out to:

      {WIDTH}{HEIGHT}{DEPTH}{ITALIC}{MAPCOMMANDS}{MAPFONTS}

where the MAPCOMMANDS will write out VPL MAP fragments to a .vpl file, and the MAPFONTS will produce any MAPFONT instructions that are needed.

\width \height \depth \italic  \width{GLPYH}
 \height{GLPYH}
 \depth{GLPYH}
 \italic{GLPYH}

These macros return the width, height, depth and italic correction of GLYPH as an integer.

744 \def\width{\glyph_parameter\first_of_six}
745 \def\height{\glyph_parameter\second_of_six}
746 \def\depth{\glyph_parameter\third_of_six}
747 \def\italic{\glyph_parameter\fourth_of_six}
748 \def\mapcommands{\glyph_parameter\fifth_of_six}
749 \def\mapfonts{\glyph_parameter\sixth_of_six}
750 \def\glyph_parameter#1#2{
751 \expandafter\expandafter\expandafter
752  #1\csname~g-#2\endcsname

753 }

754 \def\first_of_six#1#2#3#4#5#6{#1}
755 \def\second_of_six#1#2#3#4#5#6{#2}
756 \def\third_of_six#1#2#3#4#5#6{#3}
757 \def\fourth_of_six#1#2#3#4#5#6{#4}
758 \def\fifth_of_six#1#2#3#4#5#6{#5}
759 \def\sixth_of_six#1#2#3#4#5#6{#6}

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

760 \let\saved_scale\relax
761 \let\saved_mapfont\relax
762 \let\saved_raw\relax
763 \let\saved_rule\relax
764 \let\saved_special\relax
765 \let\saved_warning\relax
766 \let\saved_movert\relax
767 \let\saved_moveup\relax

768 \let\saved_push\relax
769 \let\saved_pop\relax

When the glyph is being constructed by

      \setglyph{GLYPH} GLYPH COMMANDS \endsetglyph

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 ... \pop pairs. In addition, the current vertical offset is kept locally in

 \glyph_voffset.
770 \newcount\glyph_width
771 \newcount\glyph_height
772 \newcount\glyph_depth
773 \newcount\glyph_italic
774 \newtoks\glyph_map_commands
775 \newtoks\glyph_map_fonts
776 \newcount\glyph_voffset
\setglyph The \setglyph{NAME} command defines \g-NAME, unless \g-NAME has already

been defined.

777 \def\setglyph#1{
778 \ifisglyph{#1}\then
779  \expandafter\gobble_glyph
780 \else
781  \x_cs\def{g-#1}{{\the\glyph_width}{\the
782  \glyph_height}{\the\glyph_depth}{\the\glyph_italic}{\the
783  \glyph_map_commands}{\the\glyph_map_fonts}}
784  \resetglyph{#1}
785 \fi

786 }

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

\resetglyph The \resetglyph{NAME} command redefines \g-NAME, regardless of whether \g-NAME has already been defined.

788 \def\resetglyph#1{
789 \def\glyphname{#1}
790 \glyph_width=0
791 \global\glyph_height=0
792 \global\glyph_depth=0
793 \global\glyph_italic=0
794 \glyph_voffset=0
795 \global\glyph_map_commands={}
796 \global\glyph_map_fonts={}

797 }

\endsetglyph
\endresetglyph
798 \def\endsetglyph{
799 \x_cs\edef{g-\glyphname}
800  {{\the\glyph_width}{\the\glyph_height}
801  {\the\glyph_depth}{\the\glyph_italic}
802  {\the\glyph_map_commands}{\the\glyph_map_fonts}}

803 }

804 \let\endresetglyph=\endsetglyph

\setrawglyph  \setrawglyph{GLYPH}{FONT}{SIZE}{SLOT}{WIDTH}{HEIGHT}{DEPTH}{ITALIC}

These commands are generated automatically, when an .mtx file is written out

 by \afmtomtx, \pltomtx, or \mtxtomtx.
805 \def\setrawglyph#1#2#3#4#5#6#7#8{
806 \x_cs\ifx{g-#1}\relax
807  \x_cs\ifx{i-rawscale}\relax
808  \x_cs\def{g-#1}{
809  {#5}
810  {#6}
811  {#7}
812  {#8}
813  {\saved_raw{#2}{#4}{#1}}
814  {\saved_mapfont{#2}{#3}}

815 }

816  \else
817  \eval_expr_to\e_count{\int{rawscale}}
818  \eval_expr_to\a_count{\scale{#5}\e_count}
819  \eval_expr_to\b_count{\scale{#6}\e_count}
820  \eval_expr_to\c_count{\scale{#7}\e_count}
821  \eval_expr_to\d_count{\scale{#8}\e_count}
822  \x_cs\edef{g-#1}{
823  {\the\a_count}
824  {\the\b_count}
825  {\the\c_count}
826  {\the\d_count}
827  {\saved_scale{\the\e_count}
828  {\saved_raw{#2}{#4}{#1}}}
829  {\saved_scale{\the\e_count}
830  {\saved_mapfont{#2}{#3}}}

831 }

832  \fi
833 \fi

834 }

\setnotglyph
835 \def\setnotglyph#1#2#3#4#5#6#7#8{
836 \x_cs\ifx{g-#1-not}\relax
837  \x_cs\ifx{i-rawscale}\relax
838  \x_cs\def{g-#1-not}{
839  {#5}
840  {#6}
841  {#7}
842  {#8}

843 {} 844 {} 845 }

846  \else
847  \eval_expr_to\e_count{\int{rawscale}}
848  \eval_expr_to\a_count{\scale{#5}\e_count}
849  \eval_expr_to\b_count{\scale{#6}\e_count}
850  \eval_expr_to\c_count{\scale{#7}\e_count}
851  \eval_expr_to\d_count{\scale{#8}\e_count}
852  \x_cs\edef{g-#1-not}{
853  {\the\a_count}

854  {\the\b_count}
855  {\the\c_count}
856  {\the\d_count}

857 {} 858 {} 859 }

860  \fi
861 \fi

862 }

\unsetglyph The \unsetglyph{NAME} command makes \g-NAME undefined.
863 \def\unsetglyph#1{\x_cs\let{g-#1}\relax}

10.3 Glyph commands

 The GLYPH COMMANDS are:
\glyph  \glyph{GLPYH}{SCALE}
864 \def\glyph#1#2{
865 \eval_expr_to\b_count{#2}
866 \eval_expr_to\glyph_width{\add\glyph_width{\scale\b_count{\width{#1}}}}
867 \g_eval_expr_to\glyph_height{\max\glyph_height
868  {\add{\scale\b_count{\height{#1}}}\glyph_voffset}}
869 \g_eval_expr_to\glyph_depth{\max\glyph_depth
870  {\sub{\scale\b_count{\depth{#1}}}\glyph_voffset}}
871 \g_eval_expr_to\glyph_italic{\scale\b_count{\italic{#1}}}
872 \edef\temp_command{\the\glyph_map_commands
873  \saved_scale{\the\b_count}{\mapcommands{#1}}}
874 \global\glyph_map_commands\expandafter{\temp_command}
875 \edef\temp_command{\the\glyph_map_fonts
876  \saved_scale{\the\b_count}{\mapfonts{#1}}}
877 \global\glyph_map_fonts\expandafter{\temp_command}

878 }

\glyphrule  \glyphrule{WIDTH}{HEIGHT}
879 \def\glyphrule#1#2{
880 \eval_expr_to\b_count{#1} \eval_expr_to\c_count{#2}
881 \advance\glyph_width by \b_count
882 \g_eval_expr_to\glyph_depth{\max\glyph_depth{-\glyph_voffset}}
883 \g_eval_expr_to\glyph_height{\max\glyph_height{\add\glyph_voffset\c_count}}
884 \global\glyph_italic=0
885 \edef\temp_command{\the\glyph_map_commands
886  \saved_rule{\the\b_count}{\the\c_count}}
887 \global\glyph_map_commands\expandafter{\temp_command}

888 }

\glyphspecial \glyphwarning  \glyphspecial{STRING}
 \glyphwarning{STRING}
889 \def\glyphspecial#1{
890 \edef\temp_command{\the\glyph_map_commands\saved_special{#1}}
891 \global\glyph_map_commands\expandafter{\temp_command}}
892 \def\glyphwarning#1{
893 \edef\temp_command{\the\glyph_map_commands\saved_warning{#1}}
894 \global\glyph_map_commands\expandafter{\temp_command}}

\movert \moveup  \movert{XOFFSET}
 \moveup{YOFFSET}
895 \def\movert#1{
896 \eval_expr{#1}
897 \ifnum\result=0\else
898  \advance\glyph_width by \result
899  \edef\temp_command{\the\glyph_map_commands\saved_movert{\the\result}}
900  \global\glyph_map_commands\expandafter{\temp_command}
901 \fi}
902 \def\moveup#1{
903 \eval_expr{#1}
904 \ifnum\result=0\else
905  \advance\glyph_voffset by \result
906  \edef\temp_command{\the\glyph_map_commands\saved_moveup{\the\result}}
907  \global\glyph_map_commands\expandafter{\temp_command}
908 \fi}

{\push \atop \pop}

909 \def\push{\bgroup
910 \edef\temp_command{\the\glyph_map_commands\saved_push}
911 \global\glyph_map_commands\expandafter{\temp_command}}
912 \def\pop{\egroup
913 \edef\temp_command{\the\glyph_map_commands\saved_pop}
914 \global\glyph_map_commands\expandafter{\temp_command}}
\resetwidth \resetheight \resetdepth \resetitalic  \resetwidth{WIDTH}
 \resetheight{HEIGHT}
 \resetdepth{DEPTH}
 \resetitalic{ITALIC}
915 \def\resetwidth#1{\movert{\sub{#1}\glyph_width}}
916 \def\resetheight{\g_eval_expr_to\glyph_height}
917 \def\resetdepth{\g_eval_expr_to\glyph_depth}
918 \def\resetitalic{\g_eval_expr_to\glyph_italic}

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

    \glyphpcc{GLYPH}{XOFFSET}{YOFFSET}
919 \def\glyphpcc#1#2#3{
920 \push
921  \movert{#2}
922  \moveup{#3}
923  \glyph{#1}{\one_thousand}
924 \pop

925 }

\samesize  \samesize{GLYPH}
926 \def\samesize#1{
927 \expandafter\expandafter\expandafter
928  \same_size\csname g-#1\endcsname

929 }

930 \def\same_size#1#2#3#4#5#6{
931 \movert{\sub{#1}\glyph_width}
932 \global\glyph_height=#2

933 \global\glyph_depth=#3
934 \global\glyph_italic=#4

935 }

\ifisglyph The control flow command:

936 \def\ifisglyph#1\then{
937 \x_cs\ifx{g-#1}\relax
938  \expandafter\if_false
939 \else
940  \expandafter\if_true
941 \fi

942 }

11 Writing output files

11.1 Converting an ETX file to a (V)PL file

\etxtovpl The macro:
      \etxtovpl{ENCODING}{VPLFILE}

writes a virtual font (as a virtual property list) with the encoding ENCODING. (This macro is called by \installfont.)

\etxtopl The macro:

      \etxtopl{ENCODING}{PLFILE}

writes a font (as a property list) with the encoding ENCODING. (This macro is called

 by \installrawfont.)
\etxtovpl \etxtopl
943 \def\etxtovpl#1#2{{
944 \def\vpl_extension{vpl}
945 \def\vpl_title{COMMENT}
946 \def\vpl_font{virtual~font}
947 \def\vpl_Font{Virtual~font}
948 \def\vpl_caller{\string\etxtovpl}
949 \def\vpl_to_vf##1{vpltovf~##1.vpl~##1.vf~##1.tfm}
950 \etx_to_font{#1}{#2}

951 }}

952 \def\etxtopl#1#2{{
953 \def\vpl_extension{pl}
954 \def\vpl_title{COMMENT}
955 \def\vpl_font{font}
956 \def\vpl_Font{Font}
957 \def\vpl_caller{\string\etxtopl}
958 \def\vpl_to_vf##1{pltotfm~##1.pl~##1.tfm}
959 \let\make_mapfonts\gobble_one
960 \let\do_character_map\relax
961 \etx_to_font{#1}{#2}

962 }}

\etx_to_vpl
963 \def\etx_to_font#1#2{
964 \def\do_slot{\resetint\slot_name\slot_number}
965 \inputetx{#1}
966 \open_out{#2.\vpl_extension}
967 \out_line{(\vpl_title\space\vpl_font\space
968  #2~created~by~fontinst~v\fontinstversion)}
969 \out_line{}
970 \out_line{(COMMENT~Filename:~#2.\vpl_extension)}
971 \out_line{(COMMENT~Created~by:~tex~\jobname)}
972 \out_line{(COMMENT~Created~using:~\vpl_caller{#1}{#2})}
973 \out_line{}
974 \out_line{(COMMENT~This~file~can~be~turned~into~a~\vpl_font~with)}
975 \out_line{(COMMENT~\vpl_to_vf{#2})}
976 \out_line{}
977 \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
978 \out_line{}
979 \make_font{#1}
980 \out_line{}
981 \out_line{(COMMENT~END~OF~FILE~#2.\vpl_extension)}
982 \close_out{\vpl_Font}

983 }

    \afmconvert\DIMEN=INTEGER EXPRESSION; converts a count into a dimen, as-

suming the count is a number of AFM units. I’ll assume that the largest dimension I’ll have to deal with is 131pt, to try to minimize rounding errors.

984 \newdimen\scaled_design_size
985 \def\afm_convert#1=#2;{
986 \eval_expr{#2}
987 #1=\scaled_design_size
988 \divide#1 by 8
989 \multiply #1 by \result
990 \divide #1 by \one_thousand
991 \multiply#1 by 8

992 }

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

993 \def\vpl_real#1{R~\expandafter\lose_measure\the#1}
994 \def\vpl_int#1{D~\the#1}
    \make_font{ENCODING} makes a .vpl file.
995 \def\make_font#1{
996 \make_header{#1}
997 \make_mapfonts{#1}
998 \make_fontdimens{#1}
999 \make_ligtable{#1}
1000 \make_characters{#1}
1001 \make_tidy{#1}

1002 }

1003 \newcount\boundary_char
1004 \newdimen\side_bearings
1005 \newdimen\curr_bearings

1006 \def\make_header#1{
1007 \global\font_count=0
1008 \setdim{designsize}{10pt}
1009 \scaled_design_size=\dim{designsize}
1010 \out_line{(DESIGNSIZE~\vpl_real\scaled_design_size)}
1011 \out_line{(DESIGNUNITS~\vpl_real\scaled_design_size)}
1012 \setstr{codingscheme}{UNKNOWN}
1013 \out_line{(CODINGSCHEME~\str{codingscheme})}
1014 \ifisint{boundarychar}\then
1015  \boundary_char=\int{boundarychar}
1016  \out_line{(BOUNDARYCHAR~\vpl_int\boundary_char)}
1017 \else
1018  \boundary_char=-1

1019 \fi

1020 \setint{letterspacing}{0}
1021 \afm_convert\side_bearings=\div{\int{letterspacing}}{2};
1022 \ifdim\side_bearings=0pt
1023  \let\do_character_sidebearings=\relax

1024 \fi

1025 \out_line{}

1026 }

1027 \def\make_mapfonts#1{
1028 \let\saved_scale\vpl_scale
1029 \let\saved_mapfont\vpl_mapfont
1030 \let\saved_raw\vpl_raw
1031 \let\saved_rule\vpl_rule
1032 \let\saved_special\vpl_special
1033 \let\saved_warning\vpl_warning
1034 \let\saved_movert\vpl_movert
1035 \let\saved_moveup\vpl_moveup
1036 \let\saved_push\vpl_push
1037 \let\saved_pop\vpl_pop
1038 \let\do_slot=\do_mapfont
1039 \inputetx{#1}
1040 \out_line{}

1041 }

1042 \def\make_fontdimens#1{
1043 \out_line{(FONTDIMEN}
1044  \ifisint{fontdimen(1)}\then
1045  \a_dimen=\int{fontdimen(1)}pt
1046  \divide\a_dimen by \one_thousand
1047  \out_lline{(PARAMETER~D~1~\vpl_real\a_dimen)}

1048 \fi

1049  \a_count=2
1050  \loop\ifnum\a_count<256
1051  {\ifisint{fontdimen(\the\a_count)}\then
1052  \afm_convert\a_dimen=\int{fontdimen(\the\a_count)};
1053  \out_lline{(PARAMETER~\vpl_int\a_count\space\vpl_real\a_dimen)}
1054  \fi}
1055  \advance\a_count by 1 \repeat
1056 \out_lline{)}
1057 \out_line{}

1058 }

1059 \def\make_ligtable#1{
1060 \bgroup
1061  \out_line{(LIGTABLE}
1062  \let\do_slot=\relax
1063  \let\end_do_slot=\vpl_kerning
1064  \let\ligature=\vpl_ligature
1065  \let\k=\vpl_kern
1066  \inputetx{#1}
1067  \out_lline{)}
1068 \egroup
1069 \out_line{}

1070 }

1071 \def\make_characters#1{
1072 \bgroup
1073  \let\do_slot=\do_character
1074  \let\end_do_slot=\end_do_character
1075  \let\nextlarger=\vpl_nextlarger
1076  \let\varchar=\vpl_varchar
1077  \let\endvarchar=\end_vpl_varchar
1078  \let\vartop=\vpl_vartop
1079  \let\varmid=\vpl_varmid
1080  \let\varbot=\vpl_varbot
1081  \let\varrep=\vpl_varrep
1082  \inputetx{#1}
1083 \egroup

1084 }

1085 \def\make_tidy#1{
1086 \a_count=0\loop\ifnum\a_count<\font_count
1087  \edef\temp_command{\csname~f-\the\a_count\endcsname}
1088  \global\x_cs\let\temp_command\relax
1089  \advance\a_count by 1
1090 \repeat
1091 \global\font_count=0

1092 }

    \vpl_ligature{TYPE}{NAME}{NAME} produces a ligtable entry for glyph \slot_name.
1093 \def\vpl_ligature#1#2#3{
1094 \ifisint{#2}\then
1095  \ifisint{#3}\then
1096  \ifisglyph{#3}\then
1097  \a_count=\int{#2}
1098  \b_count=\int{#3}
1099  \vpl_liglabel
1100  \out_lline{(#1~\vpl_int\a_count\space \vpl_int\b_count)~
1101  (COMMENT~#2~#3)}
1102  \else
1103  \immediate\write16{Warning:~\string\ligature\space
1104  for~unknown~slot~`#3'.}

1105 \fi

1106  \else
1107  \immediate\write16{Warning:~\string\ligature\space
1108  for~unknown~slot~`#3'.}

1109 \fi

1110 \else
1111  \immediate\write16{Warning:~\string\ligature\space
1112  for~unknown~slot~`#2'.}

1113 \fi 1114 }

\vpl_kerning writes out kerning instructions.

1115 \def\vpl_kerning{\csname~r-\slot_name\endcsname\vpl_ligstop}
    \vpl_kern\l-NAME\AMOUNT writes out a KRN instruction.
1116 \def\vpl_kern#1#2{
1117 \edef\temp_command{\expandafter\gobble_three\string#1}
1118 \ifisint\temp_command\then
1119  \vpl_liglabel
1120  \a_count=\int\temp_command
1121  \afm_convert\a_dimen=\expandafter\gobble_one\string#2;
1122  \out_lline{
1123  (KRN~\vpl_int\a_count\space \vpl_real\a_dimen)~
1124  (COMMENT~\temp_command)

1125 } 1126 \fi 1127 }

\vpl_liglabel writes out a LIGLABEL instruction if appropriate.

1128 \def\out_liglabel{
1129 \out_lline{(LABEL~\vpl_int\slot_number)~(COMMENT~\slot_name)}
1130 \ifnum\slot_number=\boundary_char
1131  \out_lline{(LABEL~BOUNDARYCHAR)}

1132 \fi

1133 \let\vpl_liglabel=\relax
1134 \let\vpl_ligstop=\out_ligstop

1135 }

1136 \let\vpl_liglabel=\out_liglabel

\vpl_ligstop writes out a LIGSTOP instruction if appropriate.

1137 \def\out_ligstop{\out_lline{(STOP)}
1138 \let\vpl_liglabel=\out_liglabel
1139 \let\vpl_ligstop=\relax}
1140 \let\vpl_ligstop=\relax

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

1141 \def\do_mapfont{
1142 \ifisglyph\slot_name\then
1143  \mapfonts\slot_name

1144 \fi 1145 }

The following commands can be used in a MAPFONT:

1146 \def\vpl_scale#1#2{{
1147 \divide \scaled_design_size by 8
1148 \multiply \scaled_design_size by #1
1149 \divide \scaled_design_size by \one_thousand
1150 \multiply \scaled_design_size by 8

1151 #2 1152 }}

1153 \def\vpl_mapfont#1#2{
1154 \a_dimen=#2
1155 \x_cs\ifx{#1-\the\scaled_design_size}\relax
1156  \x_cs\xdef{#1-\the\scaled_design_size}{\the\font_count}
1157  \x_cs\xdef{f-\the\font_count}{#1-\the\scaled_design_size}
1158  \out_line{(MAPFONT~\vpl_int\font_count\space
1159  (FONTNAME~#1)~
1160  (FONTDSIZE~\vpl_real\a_dimen)~
1161  (FONTAT~\vpl_real\scaled_design_size))}
1162  \global\advance\font_count by 1

1163 \fi 1164 }

1165 \newcount\font_count
1166 \newcount\next_mapfont
1167 \newcount\prev_mapfont

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

1168 \def\do_character{
1169 \x_cs\ifx{g-\slot_name}\relax
1170  \expandafter\gobble_setslot
1171 \else
1172  \ifx\slot_name\notdef_name\else
1173  \out_line{(CHARACTER~\vpl_int\slot_number\space
1174  (COMMENT~\slot_name)}
1175  \afm_convert\a_dimen=\width\slot_name;
1176  \do_character_sidebearings
1177  \out_lline{(CHARWD~\vpl_real\a_dimen)}
1178  \afm_convert\a_dimen=\height\slot_name;
1179  \out_lline{(CHARHT~\vpl_real\a_dimen)}
1180  \afm_convert\a_dimen=\depth\slot_name;
1181  \out_lline{(CHARDP~\vpl_real\a_dimen)}
1182  \afm_convert\a_dimen=\italic\slot_name;
1183  \ifnum\a_dimen>0
1184  \out_lline{(CHARIC~\vpl_real\a_dimen)}

1185 \fi

1186  \do_character_map

1187 \fi 1188 \fi 1189 }

1190 \def\do_character_sidebearings{
1191 \ifisint{\slot_name-spacing}\then
1192  \afm_convert\curr_bearings=\int{\slot_name-spacing};
1193  \divide\curr_bearings by 2
1194 \else
1195  \curr_bearings=\side_bearings

1196 \fi

1197 \afm_convert\a_dimen=\width\slot_name;
1198 \advance\a_dimen by 2\curr_bearings

1199 }

1200 \def\do_character_map{
1201 \global\prev_mapfont=0 \out_lline{(MAP}
1202  \ifdim \curr_bearings=0pt

1203  \mapcommands\slot_name
1204  \else
1205  \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
1206  \mapcommands\slot_name
1207  \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}

1208 \fi

1209 \out_llline{)}

1210 }

Now the version without:

1211 \def\do_character_no_letterspacing{
1212 \x_cs\ifx{g-\slot_name}\relax
1213  \expandafter\gobble_setslot
1214 \else
1215  \ifx\slot_name\notdef_name\else
1216  \out_line{(CHARACTER~\vpl_int\slot_number\space
1217  (COMMENT~\slot_name)}
1218  \afm_convert\a_dimen=\width\slot_name;
1219  \out_lline{(CHARWD~\vpl_real\a_dimen)}
1220  \afm_convert\a_dimen=\height\slot_name;
1221  \out_lline{(CHARHT~\vpl_real\a_dimen)}
1222  \afm_convert\a_dimen=\depth\slot_name;
1223  \out_lline{(CHARDP~\vpl_real\a_dimen)}
1224  \afm_convert\a_dimen=\italic\slot_name;
1225  \ifnum\a_dimen>0 \out_lline{(CHARIC~\vpl_real\a_dimen)} \fi
1226  \global\prev_mapfont=0 \out_lline{(MAP}
1227  \mapcommands\slot_name
1228  \out_llline{)}

1229 \fi 1230 \fi 1231 }

1232 \def\gobble_setslot#1\endsetslot{\endsetslot}
1233 \def\end_do_character{
1234 \ifisglyph\slot_name\then
1235  \out_lline{)}

1236 \fi 1237 }

1238 \def\notdef_name{.notdef}
    \vpl_nextlarger{NAME} produces a NEXTLARGER entry.
1239 \def\vpl_nextlarger#1{
1240 \ifisint{#1}\then
1241  \out_lline{(NEXTLARGER~D~\the\int{#1})~(COMMENT~#1)}
1242 \else
1243  \immediate\write16{Warning:~\string\nextlarger\space
1244  for~unknown~slot~`#1'}

1245 \fi 1246 }

    \vpl_varchar VARCHAR COMMANDS \end_vpl_varchar produces a VARCHAR

entry.

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

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

1254 \fi 1255 }

1256 \def\vpl_varmid#1{
1257 \ifisint{#1}\then
1258  \out_llline{(MID~D~\the\int{#1})~(COMMENT~#1)}
1259 \else
1260  \immediate\write16{Warning:~\string\varmid\space
1261  for~unknown~slot~`#1'}

1262 \fi 1263 }

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

1270 \fi 1271 }

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

1278 \fi 1279 }

1280 \def\end_vpl_varchar{\out_llline{)}}

The following commands can be used in a glyph:

1281 \def\vpl_raw#1#2#3{
1282 \global\next_mapfont=\csname~#1-\the\scaled_design_size\endcsname\relax
1283 \ifnum\next_mapfont=\prev_mapfont\else
1284  \out_llline{(SELECTFONT~\vpl_int\next_mapfont)~
1285  (COMMENT~#1~at~\the\scaled_design_size)}

1286 \fi

1287 \out_llline{(SETCHAR~D~#2)~(COMMENT~#3)}
1288 \global\prev_mapfont=\next_mapfont

1289 }

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

1294 }

1295 \def\vpl_special#1{
1296 \out_llline{(SPECIAL~#1)}}
1297 \def\vpl_warning#1{
1298 \out_llline{(SPECIAL~Warning:~#1)}

1299 \immediate\write16{Warning:~#1.}

1300 }

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

1304 }

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

1308 }

1309 \def\vpl_push{\out_llline{(PUSH)}}
1310 \def\vpl_pop{\out_llline{(POP)}}

11.2 Converting an MTX file to a PL file

\mtxtopl The macro:

      \mtxtopl{MTXFILE}{PLFILE}

writes a font from the \setrawglyph instructions in MTXFILE to PLFILE. It ignores any font dimensions and kerning, so the resulting font is only useful for generating virtual fonts from. (This macro is called by \transformfont.)

\mtxtopl
1311 \def\mtxtopl#1#2{{
1312 \open_out{#2.pl}
1313 \out_line{(COMMENT~raw~font~#2~created~by~fontinst~v\fontinstversion)}
1314 \out_line{}
1315 \out_line{(COMMENT~Filename:~#2.pl)}
1316 \out_line{(COMMENT~Created~by:~tex~\jobname)}
1317 \out_line{(COMMENT~Created~using:~\string\mtxtopl{#1}{#2})}
1318 \out_line{}
1319 \out_line{(COMMENT~This~file~can~be~turned~into~a~TeX~font~with)}
1320 \out_line{(COMMENT~pltotfm~#2.pl~#2.tfm)}
1321 \out_line{}
1322 \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
1323 \out_line{}
1324 \out_line{(DESIGNSIZE~R~10.0)}
1325 \out_line{(DESIGNUNITS~R~10.0)}
1326 \out_line{}
1327 \scaled_design_size=10pt
1328 \let\setglyph=\iffalse
1329 \let\endsetglyph=\fi
1330 \let\setkern=\gobble_three
1331 \let\setrawglyph=\pl_raw_glyph
1332 \inputmtx{#1}
1333 \out_line{}
1334 \out_line{(COMMENT~END~OF~FILE~#2.pl)}
1335 \close_out{Raw~font}

1336 }}

1337 \def\pl_raw_glyph#1#2#3#4#5#6#7#8{
1338 \a_count=#4

1339 \afm_convert\a_dimen=#5;
1340 \afm_convert\b_dimen=#6;
1341 \afm_convert\c_dimen=#7;
1342 \afm_convert\d_dimen=#8;
1343 \out_line{(CHARACTER~\vpl_int\a_count\space(COMMENT~#1)}
1344 \out_lline{(CHARWD~\vpl_real\a_dimen)}
1345 \out_lline{(CHARHT~\vpl_real\b_dimen)}
1346 \out_lline{(CHARDP~\vpl_real\c_dimen)}
1347 \out_lline{(CHARIC~\vpl_real\d_dimen)}
1348 \out_lline{)}

1349 }

12 Font installation commands and .fd files

\installfonts The macro:
\endinstallfonts
     \installfonts INSTALL COMMANDS \endinstallfonts

is the top-level interface for installing a number of fonts and creating .fd files for them.

\installfamily  The INSTALL COMMANDS are:
\installfont
\installrawfont

     \installfamily{ENCODING}{FAMILY}{FD-COMMANDS}
     \installfont{FONT-NAME}{FILE-LIST}{ETX}
       {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE}
     \installrawfont{FONT-NAME}{FILE-LIST}{ETX}
       {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE}

Each \installfamily command causes the generation of an .fd file for ENCODING and 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.)

\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.

1350 \newtoks\family_toks
1351 \def\installfonts{
1352 \bgroup
1353 \global\family_toks={}
1354 \gdef\prev_file_list{}

1355 }

\installfamily  \installfamily{ENCODING}{FAMILY}{FD-COMMANDS}
   Adds the command \fd_family{ENCODING}{FAMILY}{FD-COMANNDS} to the
token list \family_toks and defines a macro \ENCODING-FAMILY.
1356 \def\installfamily#1#2#3{
1357 \global\family_toks=\expandafter{\the\family_toks\fd_family{#1}{#2}{#3}}
1358 \global\x_cs\let{#1-#2}\empty_command

1359 }

\installfont \installrawfont  \installfont{FONT-NAME}{FILE-LIST}{ETX}
    {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE}
  \installrawfont{FONT-NAME}{FILE-LIST}{ETX}
    {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE}
1360 \def\installfont#1#2#3#4#5#6#7#8{
1361 \install_font{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{\etxtovpl}

1362 }

1363 \def\installrawfont#1#2#3#4#5#6#7#8{
1364 \install_font{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{\etxtopl}

1365 }

\install_font  \install_font{FONT-NAME}{FILE-LIST}{ETX}
    {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE}{CONVERTER}

Installs a font shape by writing out a (V).pl font using the given converter function and adding an entry to the .fd file.

1366 \def\install_font#1#2#3#4#5#6#7#8#9{
1367 \xdef\curr_file_list{#2}
1368 \ifx\prev_file_list\curr_file_list\else
1369  \egroup\bgroup
1370  \expandafter\input_mtx_files\curr_file_list,
1371  \relax,\end_input_mtx_files
1372  \global\let\prev_file_list=\curr_file_list

1373 \fi

1374 #9{#3}{#1}
1375 \x_cs\ifx{#4-#5-#6-#7}\relax
1376  \let\do_shape=\relax
1377  \x_cs\xdef{#4-#5}{
1378  \x_cs\ifx{#4-#5}\relax\else
1379  \csname#4-#5\endcsname

1380 \fi

1381  \do_shape{#4}{#5}{#6}{#7}

1382 } 1383 \fi

1384 \let\do_size=\relax
1385 \x_cs\xdef{#4-#5-#6-#7}{
1386  \x_cs\ifx{#4-#5-#6-#7}\relax\else
1387  \csname#4-#5-#6-#7\endcsname

1388 \fi

1389  \do_size{#8}{#1}

1390 } 1391 }

\endinstallfonts Finish the installation by processing the \family_toks token register, which contains the accumulated information to be written out to .fd files.

1392 \def\endinstallfonts{
1393 \let\do_shape=\fd_shape
1394 \let\do_size=\fd_size
1395 \the\family_toks
1396 \global\family_toks{}
1397 \egroup

1398 }

\input_mtx_files  \input_mtx_files{FILE-LIST}

Process a comma-separated list of .mtx files and call \imput_mtx_file for each file.

1399 \def\input_mtx_files#1,#2\end_input_mtx_files{
1400 \if\relax#1
1401  \expandafter\gobble_one
1402 \else
1403  \expandafter\identity_one
1404 \fi{
1405  \input_mtx_file{#1}
1406  \input_mtx_files#2\end_input_mtx_files

1407 } 1408 }

\input_mtx_file  \input_mtx_file{FILE}

Process an .mtx file specified in the FILE-LIST argument of \installfont or \installrawfont. If an .mtx file doesn’t exists, it is generated on the fly from a corresponding .pl or .afm file with \pltomtx or \afmtomtx. (.mtx files generated from .afm files are also written out as raw .pl files with \mtxtopl.)

1409 \def\input_mtx_file#1{
1410 \if\relax#1\relax\else
1411  \get_file_name #1~scaled~1000~;
1412  \if_file_exists{\file_name.mtx}\then
1413  \inputmtx\file_name
1414  \else
1415  % changed the order (SPQR, 15/01/97) because of cmr*.afm
1416  % files found in TEXMF/fonts/afm hierarchy
1417  \if_file_exists{\file_name.pl}\then
1418  \pltomtx\file_name\file_name
1419  \else
1420  \if_file_exists{\file_name.afm}\then
1421  \afmtomtx\file_name\file_name
1422  \mtxtopl\file_name\file_name

1423 \fi 1424 \fi

1425  \inputmtx\file_name

1426 \fi 1427 \fi 1428 }

    \get_file_name FILENAME scaled SCALE JUNK ;
1429 \def\get_file_name #1~scaled~#2~#3;{
1430 \edef\file_name{#1}
1431 \ifnum#2=\one_thousand
1432  \unsetint{rawscale}
1433 \else
1434  \setint{rawscale}{#2}

1435 \fi 1436 }

\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.

1437 \def\fd_family#1#2#3{
1438 \a_toks{#3}
1439 \edef\lowercase_file{\lowercase{
1440  \edef\noexpand\lowercase_file{#1#2.fd}}}
1441 \lowercase_file
1442 \open_out{\lowercase_file}
1443 \out_line{\percent_char~Filename:~\lowercase_file}
1444 \out_line{\percent_char~Created~by:~tex~\jobname}
1445 \out_line{\percent_char~Created~using~fontinst~v\fontinstversion}
1446 \out_line{}
1447 \out_line{\percent_char~THIS~FILE~SHOULD~BE~PUT~IN~A~TEX~INPUTS~DIRECTORY}
1448 \out_line{}
1449 \out_line{\string\ProvidesFile{\lowercase_file}}
1450 \out_lline{[
1451  \the\year/
1452  \ifnum10>\month0\fi\the\month/
1453  \ifnum10>\day0\fi\the\day\space
1454  Fontinst~v\fontinstversion\space
1455  font~definitions~for~#1/#2.

1456 ]}

1457 \out_line{}
1458 \out_line{\string\DeclareFontFamily{#1}{#2}{\the\a_toks}}

1459 {

1460  \csname #1-#2\endcsname
1461  \out_line{}
1462  \let\do_shape=\substitute_shape
1463  \csname #1-#2\endcsname
1464  \let\do_shape=\remove_shape
1465  \csname #1-#2\endcsname

1466 }

1467 \x_cs\g_let{#1-#2}\relax
1468 \out_line{}
1469 \out_line{\string\endinput}
1470 \close_out{Font~definitions}

1471 }

\fd_shape  \fd_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1472 \def\fd_shape#1#2#3#4{
1473 \out_line{}
1474 \out_line{\string\DeclareFontShape{#1}{#2}{#3}{#4}\left_brace_char}
1475 \csname #1-#2-#3-#4\endcsname
1476 \x_cs\g_let{#1-#2-#3-#4}\empty_command
1477 \out_line{\right_brace_char{}}

1478 }

\fd_size  \fd_size{SIZE}{FONT-NAME}
1479 \def\fd_size#1#2{
1480 \x_cs\ifx{siz-#1}\relax
1481  \out_lline{#1~#2}
1482 \else
1483  \out_lline{\csname siz-#1\endcsname\space #2}

1484 \fi 1485 }

\remove_shape  \remove_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1486 \def\remove_shape#1#2#3#4{
1487 \x_cs\g_let{#1-#2-#3-#4}\relax

1488 }

\substitute_shape  \substitute_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1489 \def\substitute_shape#1#2#3#4{
1490 \edef\orig_shape{#4}
1491 \substitute_series{#1}{#2}{#3}{\orig_shape}
1492 \x_cs\ifx{sub-\orig_shape}\relax\else
1493  \edef\subst_shape{\csname sub-\orig_shape\endcsname}
1494  \x_cs\ifx{#1-#2-#3-\subst_shape}\relax
1495  \out_line{
1496  \string\DeclareFontShape{#1}{#2}{#3}{\subst_shape}{
1497  <->\csname typ-\orig_shape\endcsname\space *~#2/#3/\orig_shape

1498 }{} 1499 }

1500  \x_cs\let{#1-#2-#3-\subst_shape}\empty_command
1501  \substitute_shape{#1}{#2}{#3}{\subst_shape}

1502 \fi 1503 \fi 1504 }

\substitute_series  \substitute_series{ENCODING}{FAMILY}{SERIES}{SHAPE}
1505 \def\substitute_series#1#2#3#4{
1506 \edef\orig_series{#3}
1507 \x_cs\ifx{sub-\orig_series}\relax\else
1508  \edef\subst_series{\csname sub-\orig_series\endcsname}
1509  \x_cs\ifx{#1-#2-\subst_series-#4}\relax
1510  \out_line{
1511  \string\DeclareFontShape{#1}{#2}{\subst_series}{#4}{
1512  <->\csname typ-\orig_series\endcsname\space *~#2/\orig_series/#4

1513 }{} 1514 }

1515  \x_cs\let{#1-#2-\subst_series-#4}\empty_command
1516  \substitute_series{#1}{#2}{\subst_series}{#4}

1517 \fi 1518 \fi 1519 }

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

Specifies a default substitution for family or shape TO, which is substituted by family or shape FROM.

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

1523 }

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

1527 }

1528 \substitutesilent{bx}{b}
1529 \substitutesilent{b}{bx}
1530 \substitutesilent{b}{sb}
1531 \substitutesilent{b}{db}
1532 \substitutesilent{m}{mb}
1533 \substitutesilent{m}{l}
1534 \substitutenoisy{ui}{it}

I don’t think we want these since in OT1 encoding it will cause the old <sterling> vs <dollar> problem. (ASAJ) — Oh yes we do. (SPQR)

1535 \substitutesilent{sl}{it}
1536 \substitutesilent{it}{sl}

12.1 Default encodings and font sizes

\declareencoding  \declareencoding{CODINGSCHEME}{ENCODING}

Declare a macro \enc-CODINGSCHEME which expands to ENCODING. This is used to determine the encoding in \pltomtx.

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

Old TEX text font encodings.

1538 \declareencoding{TEX~TEXT}{OT1}
1539 \declareencoding{TEX~TEXT~WITHOUT~F-LIGATURES}{OT1}
1540 \declareencoding{TEX~TYPEWRITER~TEXT}{OT1TT}

Old TEX math font encodings.

1541 \declareencoding{TEX~MATH~ITALIC}{OML}
1542 \declareencoding{TEX~MATH~SYMBOLS}{OMS}
1543 \declareencoding{TEX~MATH~EXTENSION}{OMX}
1544 \declareencoding{LATEX~SYMBOLS}{lasy}

Euler math font encodings.

1545 \declareencoding{TEX~TEXT~SUBSET}{eufrak}
1546 \declareencoding{TEX~MATH~ITALIC~SUBSET}{eurm}
1547 \declareencoding{TEX~MATH~SYMBOLS~SUBSET}{euscr}
1548 \declareencoding{EULER~SUBSTITUTIONS~ONLY}{euex}

New TEX text font encodings.

1549 \declareencoding{EXTENDED~TEX~FONT~ENCODING~-~LATIN}{T1}
1550 \declareencoding{TEX~TEXT~COMPANION~SYMBOLS~1---TS1}{TS1}

Rencoded PostScript font encdings.

1551 \declareencoding{TEXBASE1ENCODING}{8r}
1552 \declareencoding{TEX~TYPEWRITER~AND~WINDOWS~ANSI}{8y}
\declaresize  \declaresize{FONTSIZE}{LATEXSIZE}
1553 \def\declaresize#1#2{\x_cs\edef{siz-#1}{#2}}

Default sizes. An empty size argument is equivalent to <->, for use with scalable fonts.

1554 \declaresize{}{<->}
1555 \declaresize{5}{<5>}
1556 \declaresize{6}{<6>}

1557 \declaresize{7}{<7>}
1558 \declaresize{8}{<8>}
1559 \declaresize{9}{<9>}
1560 \declaresize{10}{<10>}
1561 \declaresize{11}{<10.95>}
1562 \declaresize{12}{<12>}
1563 \declaresize{14}{<14.4>}
1564 \declaresize{17}{<17.28>}
1565 \declaresize{20}{<20.74>}
1566 \declaresize{25}{<24.88>}

13 Font transformations

\transformfont The macro:
      \transformfont{FONT-NAME}{TRANSFORMED FONT}

transforms a raw font.

\fromafm  The TRANSFORMED FONT commands are:
\frommtx
\frompl
\scalefont
\xscalefont
\yscalefont
\slantfont
\reencodefont

      \fromafm{AFMFILE}
      \frompl{PLFILE}
      \frommtx{MTXFILE}
      \scalefont{INTEGER EXPRESSION}{TRANSFORMED FONT}
      \xscalefont{INTEGER EXPRESSION}{TRANSFORMED FONT}
      \yscalefont{INTEGER EXPRESSION}{TRANSFORMED FONT}
      \slantfont{INTEGER EXPRESSION}{TRANSFORMED FONT}
      \reencodefont{ETX}{TRANSFORMED FONT}

Each \transformfont command generates an .mtx file for FONT-NAME and a corresponding raw .pl file, which is written out by \mtxtopl.

Each \fromafm or \frommtx command also generates an .mtx file, which is written out by \afmtomtx or \pltomtx. In addition, \fromafm also generates a corresponding raw .pl file by \mtxtopl.

\transformfont
1567 \def\transformfont#1#2{{
1568 \unsetstr{afm-name}
1569 \unsetstr{etx-name}
1570 \resetint{x-scale}{\one_thousand}
1571 \resetint{y-scale}{\one_thousand}
1572 \resetint{slant-scale}{0}

1573 #2

1574 \mtxtomtx{\str{afm-name}}{#1}
1575 \mtxtopl{#1}{#1}

1576 }}

\fromafm \frompl \frommtx
1577 \def\fromafm#1{
1578 \setstr{afm-name}{#1}
1579 \afmtomtx{#1}{#1}
1580 \mtxtopl{#1}{#1}

1581 }

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

1585 }

1586 \def\frommtx#1{
1587 \setstr{afm-name}{#1}

1588 }

\scalefont
\xscalefont
\yscalefont
\slantfont
\reencodefont

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

1592 #2 1593 }

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

1596 #2 1597 }

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

1600 #2 1601 }

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

1604 #2 1605 }

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

1608 #2 1609 }

\mtxtomtx  The macro:
      \mtxtomtx{MTX}{MTX}

converts the first .mtx file to the second, using the current values of \int{x-scale},

  \int{y-scale}, \int{slant-scale} and \str{etx-name}.

NOTE: this doesn’t convert arbitrary .mtx files, just ones created with

  \afmtomtx or \pltomtx.
\mtxtomtx
1610 \def\mtxtomtx#1#2{{
1611 \ifisstr{etx-name}\then
1612  \def\do_slot{\resetint\slot_name\slot_number}
1613  \inputetx{\str{etx-name}}

1614 \fi

1615 \open_out{\temp_prefix#2.mtx}
1616 \def\raw_font_name{#2}
1617 \out_line{\percent_char~Filename:~#2.mtx}
1618 \out_line{\percent_char~Created~by:~tex~\jobname}
1619 \out_line{\percent_char~Created~using:~\string\mtxtomtx{#1}{#2}}
1620 \out_line{}
1621 \out_line{\percent_char~This~file~is~used~by~the~fontinst~package.}
1622 \out_line{}

1623 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
1624 \out_line{}
1625 \out_line{\string\relax}
1626 \out_line{\string\metrics}
1627 \out_line{}
1628 \out_line{\string\needsfontinstversion{\fontinstversion}}
1629 \out_line{}
1630 \let\setint=\mtxtomtx_setint
1631 \let\setrawglyph=\mtxtomtx_setrawglyph
1632 \let\setnotglyph=\mtxtomtx_setrawglyph
1633 \let\setkern=\mtxtomtx_setkern
1634 \let\setglyph=\mtxtomtx_setglyph
1635 \let\glyphpcc=\mtxtomtx_glyphpcc
1636 \let\samesize=\mtxtomtx_samesize
1637 \let\endsetglyph=\mtxtomtx_endsetglyph
1638 \inputmtx{#1}
1639 \out_line{}
1640 \out_line{\string\endmetrics}
1641 \close_out{Transformed~metrics}

1642 }}

1643 \def\mtxtomtx_setint#1#2{
1644 \def\temp_command{#1}
1645 \ifx\temp_command\italicslant_name
1646  \eval_expr_to\a_count{
1647  \add{\int{slant-scale}}
1648  {\div{\mul{\int{x-scale}}{#2}}{\int{y-scale}}}

1649 }

1650 \else
1651  \eval_expr_to\a_count{\scale{#2}{\int{y-scale}}}

1652 \fi

1653 \out_line{\string\setint{#1}{\the\a_count}}

1654 }

1655 \def\italicslant_name{italicslant}
1656 \def\mtxtomtx_setrawglyph#1#2#3#4#5#6#7#8{
1657 \eval_expr_to\a_count{\scale{#5}{\int{x-scale}}}
1658 \eval_expr_to\b_count{\scale{#6}{\int{y-scale}}}
1659 \eval_expr_to\c_count{\scale{#7}{\int{y-scale}}}
1660 \eval_expr_to\d_count{
1661  \add{\scale{#8}{\int{x-scale}}}
1662  {\scale\b_count{\int{slant-scale}}}

1663 }

1664 \ifisstr{etx-name}\then
1665  \ifisint{#1}\then
1666  \e_count=\int{#1}
1667  \else
1668  \e_count=-1

1669 \fi

1670 \else
1671  \e_count=#4

1672 \fi

1673 \out_line{
1674  \ifnum\e_count>-1
1675  \string\setrawglyph

1676  \else
1677  \string\setnotglyph

1678 \fi

1679  {#1}{\raw_font_name}{#3}{\the\e_count}
1680  {\the\a_count}{\the\b_count}{\the\c_count}{\the\d_count}

1681 } 1682 }

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

1686 }

1687 \def\mtxtomtx_setglyph#1{\out_line{\string\setglyph{#1}}}
1688 \def\mtxtomtx_samesize#1{\out_lline{\string\samesize{#1}}}
1689 \def\mtxtomtx_endsetglyph{\out_line{\string\endsetglyph}}
1690 \def\mtxtomtx_glyphpcc#1#2#3{
1691 \eval_expr_to\b_count{\scale{\int{y-scale}}{#3}}
1692 \eval_expr_to\a_count{
1693  \add{\scale{\int{x-scale}}{#2}}
1694  {\scale\b_count{\int{slant-scale}}}

1695 }

1696 \out_lline{\string\glyphpcc{#1}{\the\a_count}{\the\b_count}}

1697 }

14 Installing Latin families

\latinfamily The macro:
      \latinfamily{FAMILY}{COMMANDS}

installs a Latin font family.

1698 \def\latinfamily#1#2{{
1699 \edef\temp_command{#1}
1700 \expandafter\parse_family\temp_command
1701  \empty_command\empty_command\end_parse_family
1702 \installfonts
1703  \if_file_exists{\raw_encoding.mtx}\then
1704  \installfamily{\raw_encoding}{\latex_family}{#2}

1705 \fi

1706  \installfamily{OT1}{\latex_family}{#2}
1707  \installfamily{T1}{\latex_family}{#2}

1708 ⟨∗textcomp⟩

1709  \installfamily{TS1}{\latex_family}{#2}

1710 ⟨/textcomp⟩

1711  \latin_weights
1712 \endinstallfonts

1713 }}

\parse_family \font_family \font_variant \raw_variant \latex_variant  \parse_family FAMILY\end_parse_family

Intializes \latex_family to FAMILY, \font_family to first three characters of FAMILY, \font_variant and \raw_variant to fourth and fifth character (if present).

SPQR 02/95: If the fourth parameter is x or 9, then its an expert indication, not a variant. So initialy set \raw_variant to #4, but unset it if the expert test succeeds. When #4 is used for a real variant, it passes through.

SPQR 05/95: If it is an expert font, then the variantness is expressed by the encoding, not a variant letter, so unset \font_variant.

UV 06/98: Added \if_oldstyle_code from Alan’s v 1.511 beta. If the fourth parameter is 9, treat it as if j was given.

Note that instead of using \setcommand\digit, we now use separate encoding files for T1j.etx, etc.

1714 \def\parse_family #1#2#3#4#5\end_parse_family{
1715 \gdef\font_family{#1#2#3}
1716 \gdef\font_variant{#4#5}
1717 \gdef\raw_variant{#4#5}
1718 \gdef\latex_family{#1#2#3#4#5}
1719 \_expert_false
1720 \_oldstyle_false
1721 \ifx#4x
1722  \_expert_true
1723  \gdef\raw_variant{#5}
1724  \gdef\font_variant{#5}
1725  %\setcommand\digit##1{##1}
1726 \else\ifx#4j
1727  \_expert_true
1728  \_oldstyle_true
1729  \gdef\raw_variant{#5}
1730  \gdef\font_variant{#5}
1731  %\setcommand\digit##1{##1oldstyle}
1732 \else\ifx#49
1733  \gdef\latex_family{#1#2#3j#5}
1734  \_expert_true
1735  \_oldstyle_true
1736  \gdef\raw_variant{#5}
1737  \gdef\font_variant{#5}
1738  %\setcommand\digit##1{##1oldstyle}
1739 \else
1740  \_expert_false
1741  \_oldstyle_false
1742  %\setcommand\digit##1{##1}
1743 \fi\fi\fi

1744 ⟨∗debug⟩

1745 \if_oldstyle_
1746 \immediate\write16{INFO>~parse~family~<#1#2#3><#5>~(oldstyle)}
1747 \else\if_expert_
1748 \immediate\write16{INFO>~parse~family~<#1#2#3><#5>~(expert)}
1749 \else
1750 \immediate\write16{INFO>~parse~family~<#1#2#3><#4#5>}
1751 \fi\fi

1752 ⟨/debug⟩ 1753 }

\if_expert_
\if_oldstyle_
1754 \newif\if_expert_
1755 \newif\if_oldstyle_

14.1 Processing a list of weights, widths and shapes

\latin_weight \font_weight \latex_weight  \latin_weight{FONTWEIGHT}{LATEXWEIGHT}
1756 \def\latin_weight#1#2{
1757 \gdef\font_weight{#1}%
1758 \gdef\latex_weight{#2}%
1759 \latin_widths

1760 }

\latin_width \font_width \latex_width  \latin_width{FONTWIDTH}{LATEXWIDTH}
1761 \def\latin_width#1#2{
1762 \gdef\font_width{#1}
1763 \gdef\latex_width{#2}
1764 \latin_shapes

1765 }

\latin_shape \font_shape \raw_shape \encoding_shape \latex_shape \encoding_switches  \latin_shape{FONTSHAPE}{RAWSHAPE}{ENCODINGSHAPE}{LATEXSHAPE}{SWITCHES}
    Calls \fake_width_WIDTH and \fake_shape_SHAPE to generate an 8r-reencoded

.mtx file. If successful, calls \latin_encodings.

UV 06/98: Added a fifth argument SWITCHES, which may be used to set

  \if_textcomp_before it is evaluated in \latin_encodings.
1766 \def\latin_shape#1#2#3#4#5{
1767 \gdef\font_shape{#1}
1768 \gdef\raw_shape{#2}
1769 \gdef\encoding_shape{#3}
1770 \if_oldstyle_
1771  \gdef\encoding_shape{#3\oldstyle_shape}

1772 \fi

1773 \gdef\latex_shape{#4}
1774 \gdef\encoding_switches{#5}

1775 ⟨∗debug⟩

1776 \immediate\write16{
1777  INFO>~to~make~LaTeX~font~shape~<\latex_family,
1778  \latex_weight,\latex_shape,\latex_width>~seek~
1779  \font_family\font_weight\raw_shape
1780  \raw_variant\raw_encoding\font_width.mtx}

1781 ⟨/debug⟩

1782 \csname fake_width_\font_width\endcsname
1783 \csname fake_shape_\raw_shape\endcsname
1784 \if_file_exists{
1785  \font_family\font_weight\raw_shape
1786  \raw_variant\raw_encoding\font_width.mtx
1787 }\then
1788  \latin_encodings

1789 \fi 1790 }

14.2 Faking font shapes

(CK) changed font faking code; based on SPQR’s code (still in this file). I am not sure that know what I am doing here; let’s hope I won’t be caught. Also changed: Order of \font_width and \font_encoding in MANY places. Also added tests which prevent multiple calls to the same font faking routine. (Seems to be necessary in some cases and can’t hurt.) — (ASAJ) I think CK knows more about what he’s doing than he’s letting on.

\fake_shape_Check if an 8a-encoded .afm file exists for current combination of font attributes, and, if so, call \fake_shape_raw_encoding. For expert fonts, also check if an 8xencoded .afm file exists, and call \fake_shape_expert_encoding, if approporiate.

UV, 06/98: Cut down lengthy \fake_shape_routine into several subroutines

  \fake_shape_raw_encoding and optionally \fake_shape_expert_encoding and
  \fake_shape_oldstyle_encoding.

UV, 06/98: Added experimental code to install OsF or SC&OsF fonts.

1791 \def\fake_shape_{
1792 \if_file_exists{
1793  \font_family\font_weight\raw_shape\raw_variant
1794  \adobe_encoding\font_width.afm
1795 }\then
1796  \fake_shape_raw_encoding

1797 \fi

1798 \if_expert_
1799  \if_file_exists{
1800  \font_family\font_weight\raw_shape\raw_variant
1801  \expert_encoding\font_width.afm
1802  }\then
1803  \fake_shape_expert_encoding

1804 \fi 1805 \fi 1806 ⟨∗oldstyle⟩

1807 \if_oldstyle_
1808  \gdef\oldstyle_variant{\oldstyle_shape}
1809  \if_file_exists{
1810  \font_family\font_weight\raw_shape\oldstyle_variant
1811  \adobe_encoding\font_width.afm
1812  }\then
1813  \fake_shape_oldstyle_encoding
1814  \else
1815  \gdef\oldstyle_variant{\caps_shape}
1816  \if_file_exists{
1817  \font_family\font_weight\raw_shape\oldstyle_variant
1818  \adobe_encoding\font_width.afm
1819  }\then
1820  \fake_shape_oldstyle_encoding

1821 \fi 1822 \fi 1823 \fi 1824 ⟨/oldstyle⟩ 1825 }

\fake_shape_raw_encoding Called from \fake_shape_if an 8a-encoded .afm file was found. Invokes
      \transformfont{<FONT>8r}
        {\reencodefont{8r}{\fromafm{<FONT>8a}}}

to generate an 8r-reencoded .mtx file (and a raw .pl file), followed by

      \installrawfont{<FONT>8r}{<FONT>8r,8r}{8r}...

to install a ligfull .pl file.

1826 \def\fake_shape_raw_encoding{
1827 \if_file_exists{
1828  \font_family\font_weight\raw_shape\raw_variant
1829  \raw_encoding\font_width.mtx
1830 }\then % no action required
1831 \else

1832 ⟨∗debug⟩

1833  \immediate\write16{
1834  INFO>~run~\string\transformfont\space\space
1835  <\font_family\font_weight\raw_shape\raw_variant
1836  \raw_encoding\font_width>~from~
1837  <\font_family\font_weight\raw_shape\raw_variant
1838  \adobe_encoding\font_width>

1839 } 1840 ⟨/debug⟩

1841  \transformfont{
1842  \font_family\font_weight\raw_shape\raw_variant
1843  \raw_encoding\font_width

1844 }{

1845  \reencodefont{\raw_encoding}{
1846  \fromafm{
1847  \font_family\font_weight\raw_shape\raw_variant
1848  \adobe_encoding\font_width

1849 } 1850 } 1851 }

1852  \if_file_exists{ \raw_encoding.mtx }\then

1853 ⟨∗debug⟩

1854  \immediate\write16{
1855  INFO>~run~\string\installrawfont\space
1856  <\font_family\font_weight\font_shape\raw_variant
1857  \raw_encoding\font_width>
1858  <\font_family\font_weight\raw_shape\raw_variant
1859  \raw_encoding\font_width,
1860  \raw_encoding>
1861  <\raw_encoding>
1862  <\raw_encoding>
1863  <\latex_family>
1864  <\latex_weight\latex_width>
1865  <\latex_shape>}

1866 ⟨/debug⟩

1867  \installrawfont{
1868  \font_family\font_weight\raw_shape\raw_variant
1869  \raw_encoding\font_width
1870  }{ \font_family\font_weight\raw_shape\raw_variant
1871  \raw_encoding\font_width,
1872  \raw_encoding
1873  }{ \raw_encoding
1874  }{ \raw_encoding
1875  }{ \latex_family
1876  }{ \latex_weight\latex_width
1877  }{ \latex_shape

1878 }{} 1879 \fi 1880 \fi 1881 }

\fake_shape_expert_encoding Called from \fake_shape_if an 8x-encoded .afm file was found. Invokes
      \fromafm{<FONT>8x}

to generate an 8x-encoded .mtx file (and a raw .pl file).

1882 \def\fake_shape_expert_encoding{
1883 \if_file_exists{
1884  \font_family\font_weight\raw_shape\raw_variant
1885  \expert_encoding\font_width.mtx
1886 }\then % no action required
1887 \else
1888  \fromafm{
1889  \font_family\font_weight\raw_shape\raw_variant
1890  \expert_encoding\font_width

1891 } 1892 \fi 1893 }

\fake_shape_oldstyle_encoding Called from \fake_shape_if an OsF or SC&OsF variant of an 8a-encoded .afm

file was found. Invokes

      \transformfont{<FONT>j8r}
        {\reencodefont{8r}{\fromafm{<FONT>j8a}}}

to generate an 8r-reencoded .mtx file (and a raw .pl file).

1894 ⟨∗oldstyle⟩

1895 \def\fake_shape_oldstyle_encoding{
1896 \if_file_exists{
1897  \font_family\font_weight\raw_shape\oldstyle_variant
1898  \adobe_encoding\font_width.mtx
1899 }\then % no action required
1900 \else

1901 ⟨∗debug⟩

1902  \immediate\write16{
1903  INFO>~run~\string\transformfont\space\space
1904  <\font_family\font_weight\raw_shape\oldstyle_variant
1905  \raw_encoding\font_width>~from~
1906  <\font_family\font_weight\raw_shape\oldstyle_variant
1907  \adobe_encoding\font_width>

1908 } 1909 ⟨/debug⟩

1910  \transformfont{
1911  \font_family\font_weight\raw_shape\oldstyle_variant
1912  \raw_encoding\font_width

1913 }{

1914  \reencodefont{\raw_encoding}{
1915  \fromafm{
1916  \font_family\font_weight\raw_shape\oldstyle_variant
1917  \adobe_encoding\font_width

1918 } 1920 } 1921 \fi 1922 } 1923 ⟨/oldstyle⟩

\fake_shape_c Check if an 8a-encoded .afm file exists for the small caps shape. If so, call \fake_shape_to generate an 8r-reencoded MTX file and to install a ligfull .pl file. If not, reset \raw_shape to the default shape and \encoding_shape to small caps before calling \fake_shape_to install a faked small caps font.

1924 \def\fake_shape_c{
1925 \if_file_exists{
1926  \font_family\font_weight\raw_shape\raw_variant
1927  \adobe_encoding\font_width.afm
1928 }\then
1929  \fake_shape_
1930 \else
1931  % If real smallcaps font doesn't exist, fake it from the roman.
1932  \gdef\raw_shape{}
1933  \if_oldstyle_
1934  \gdef\encoding_shape{cj}
1935  \else
1936  \gdef\encoding_shape{c}

1937 \fi

1938  \fake_shape_

1939 \fi 1940 }

\fake_shape_o Check if an 8a-encoded .afm file exists for the oblique shape. If so, call \fake_shape_to generate an 8r-reencoded MTX file and to install a ligfull .pl file. If not, call macros to fake a oblique fonts.

1941 \def\fake_shape_o{
1942 \if_file_exists{
1943  \font_family\font_weight\raw_shape\raw_variant
1944  \adobe_encoding\font_width.afm
1945 }\then
1946  \fake_shape_
1947 \else
1948  \fake_shape_o_raw_encoding
1949  \if_expert_
1950  \fake_shape_o_expert_encoding

1951 \fi 1952 ⟨∗oldstyle⟩

1953  \if_oldstyle_
1954  \fake_shape_o_oldstyle_encoding

1955 \fi 1956 ⟨/oldstyle⟩ 1957 \fi 1958 }

\fake_shape_o_raw_encoding Called from \fake_shape_o if the oblique shape needs to be faked. Invokes

      \transformfont{<FONT>o8r}
        {\slantfont{SLANT}{\frommtx{<FONT>8r}}}

to generate an 8r-reencoded .mtx file (and a raw .pl file), followed by

      \installrawfont{<FONT>o8r}{<FONT>o8r,8r}{8r}...

to install a ligfull .pl file.

1959 \def\fake_shape_o_raw_encoding{
1960 \if_file_exists{
1961  \font_family\font_weight\raw_variant
1962  \raw_encoding\font_width.mtx
1963 }\then
1964  \if_file_exists{
1965  \font_family\font_weight\font_shape\raw_variant
1966  \raw_encoding\font_width.mtx
1967  }\then % no action required
1968  \else

1969 ⟨∗debug⟩

1970  \immediate\write16{
1971  INFO>~run~\string\transformfont\space\space
1972  <\font_family\font_weight\font_shape\raw_variant
1973  \raw_encoding\font_width>~from~
1974  <\font_family\font_weight\raw_variant
1975  \raw_encoding\font_width>~(faking~oblique)

1976 } 1977 ⟨/debug⟩

1978  %%% WARNING: famtool.pl relies on this message format!!!
1979  \immediate\write16{
1980  Faking~oblique~font~
1981  \font_family\font_weight\font_shape\raw_variant
1982  \raw_encoding\font_width
1983  \space from~
1984  \font_family\font_weight\raw_variant
1985  \raw_encoding\font_width

1986 }

1987  \transformfont{
1988  \font_family\font_weight\font_shape\raw_variant
1989  \raw_encoding\font_width

1990 }{

1991  \slantfont{\SlantAmount}{
1992  \frommtx{
1993  \font_family\font_weight\raw_variant
1994  \raw_encoding\font_width

1995 } 1996 } 1997 }

1998  \if_file_exists{ \raw_encoding.mtx }\then

1999 ⟨∗debug⟩

2000  \immediate\write16{
2001  INFO>~run~\string\installrawfont\space
2002  <\font_family\font_weight\font_shape\raw_variant
2003  \raw_encoding\font_width>
2004  <\font_family\font_weight\font_shape\raw_variant
2005  \raw_encoding\font_width,
2006  \raw_encoding>
2007  <\raw_encoding>

2008  <\raw_encoding>
2009  <\latex_family>
2010  <\latex_weight\latex_width>
2011  <\latex_shape>}

2012 ⟨/debug⟩

2013  \installrawfont{
2014  \font_family\font_weight\font_shape\raw_variant
2015  \raw_encoding\font_width
2016  }{ \font_family\font_weight\font_shape\raw_variant
2017  \raw_encoding\font_width,
2018  \raw_encoding
2019  }{ \raw_encoding
2020  }{ \raw_encoding
2021  }{ \latex_family
2022  }{ \latex_weight\latex_width
2023  }{ \latex_shape

2024 }{} 2025 \fi 2026 \fi 2027 \fi 2028 }

\fake_shape_o_expert_encoding Called from \fake_shape_o if the oblique shape needs to be faked. Invokes

      \transformfont{<FONT>o8x}
        {\slantfont{SLANT}{\frommtx{<FONT>8x}}}

to generate an 8x-reencoded .mtx file (and a raw .pl file).

2029 \def\fake_shape_o_expert_encoding{
2030 \if_file_exists{
2031  \font_family\font_weight\raw_variant
2032  \expert_encoding\font_width.mtx
2033 }\then
2034  \if_file_exists{
2035  \font_family\font_weight\font_shape\raw_variant
2036  \expert_encoding\font_width.mtx
2037  }\then % no action required
2038  \else

2039 ⟨∗debug⟩

2040  \immediate\write16{
2041  INFO>~run~\string\transformfont\space\space
2042  <\font_family\font_weight\font_shape\raw_variant
2043  \expert_encoding\font_width>~from~
2044  <\font_family\font_weight\raw_variant
2045  \expert_encoding\font_width>~(faking~oblique)

2046 } 2047 ⟨/debug⟩

2048  %%% WARNING: famtool.pl relies on this message format!!!
2049  \immediate\write16{
2050  Faking~oblique~font~
2051  \font_family\font_weight\font_shape\raw_variant
2052  \expert_encoding\font_width
2053  \space from~
2054  \font_family\font_weight\raw_variant

2055  \expert_encoding\font_width

2056 }

2057  \transformfont{
2058  \font_family\font_weight\font_shape\raw_variant
2059  \expert_encoding\font_width

2060 }{

2061  \slantfont{\SlantAmount}{
2062  \frommtx{
2063  \font_family\font_weight\raw_variant
2064  \expert_encoding\font_width

2065 } 2066 } 2067 } 2068 \fi 2069 \fi 2070 }

\fake_shape_o_oldstyle_encoding Called from \fake_shape_o if the oblique shape needs to be faked. Invokes

      \transformfont{<FONT>oj8r}
        {\slantfont{SLANT}{\frommtx{<FONT>j8r}}}

to generate an 8r-reencoded .mtx file (and a raw .pl file).

2071 ⟨∗oldstyle⟩

2072 \def\fake_shape_o_oldstyle_encoding{
2073 \if_file_exists{
2074  \font_family\font_weight\oldstyle_variant
2075  \raw_encoding\font_width.mtx
2076 }\then
2077  \if_file_exists{
2078  \font_family\font_weight\font_shape\oldstyle_variant
2079  \raw_encoding\font_width.mtx
2080  }\then % no action required
2081  \else

2082 ⟨∗debug⟩

2083  \immediate\write16{
2084  INFO>~run~\string\transformfont\space\space
2085  <\font_family\font_weight\font_shape\oldstyle_variant
2086  \raw_encoding\font_width>~from~
2087  <\font_family\font_weight\oldstyle_variant
2088  \raw_encoding\font_width>~(faking~oblique)

2089 } 2090 ⟨/debug⟩

2091  %%% WARNING: famtool.pl relies on this message format!!!
2092  \immediate\write16{
2093  Faking~oblique~font~
2094  \font_family\font_weight\font_shape\oldstyle_variant
2095  \raw_encoding\font_width
2096  \space from~
2097  \font_family\font_weight\oldstyle_variant
2098  \raw_encoding\font_width

2099 }

2100  \transformfont{
2101  \font_family\font_weight\font_shape\oldstyle_variant

2102  \raw_encoding\font_width

2103 }{

2104  \slantfont{\SlantAmount}{
2105  \frommtx{
2106  \font_family\font_weight\oldstyle_variant
2107  \raw_encoding\font_width

2108 } 2109 } 2110 } 2111 \fi 2112 \fi 2113 } 2114 ⟨/oldstyle⟩

\fake_shape_i Call \fake_shape_to generate an 8r-reencoded .mtx file and a ligfull .pl file, if a corresponding 8a-encoded .afm file exists. Otherwise, do nothing, since an italic shape can’t be faked.

2115 \let\fake_shape_i\fake_shape_% We must do this again!

14.3 Faking font widths

\if_fake_narrow_
2116 \newif\if_fake_narrow_
2117 \_fake_narrow_false
\fakenarrow  \fakenarrow{WIDTH}

Sets the expansion factor used to generate faked narrow fonts. If it isn’t set, do not attempt to install faked narrow fonts.

2118 \def\fakenarrow#1{
2119 \_fake_narrow_true
2120 \gdef\fake_narrow_width{#1}

2121 }

\fake_width_Do nothing for the default width or the condensed width.

2122 \def\fake_width_{}
2123 \def\fake_width_c{}

\fake_width_n If we are faking narrow fonts, check if an 8a-encoded .afm file exists for the current shape in narrow width, and if not call \fake_shape_n_raw_encoding and

  \fake_shape_n_expert_encoding.
2124 \def\fake_width_n{
2125 \if_fake_narrow_
2126  \if_file_exists{
2127  \font_family\font_weight\raw_shape\raw_variant
2128  \adobe_encoding\font_width.afm
2129  }\then % no action required
2130  \else
2131  \fake_width_n_raw_encoding
2132  \if_expert_
2133  \fake_width_n_expert_encoding

2134 \fi 2135 \fi 2136 \fi 2137 }

\fake_width_n_raw_encoding Called from \fake_width_n if the narrow width needs to be faked. Invokes

      \transformfont{<FONT>8rn}
        {\xscalefont{WIDTH}{\frommtx{<FONT>8r}}}

to generate an 8r-encoded .mtx file for a faked narrow font, followed by

      \installrawfont{<FONT>8rn}{<FONT>8rn,8r}{8r}...

to install a ligfull .pl file.

2138 \def\fake_width_n_raw_encoding{
2139 \if_file_exists{
2140  \font_family\font_weight\font_shape\raw_variant
2141  \raw_encoding.mtx
2142 }\then
2143  \if_file_exists{
2144  \font_family\font_weight\font_shape\raw_variant
2145  \raw_encoding\font_width.mtx
2146  }\then % no action required
2147  \else

2148 ⟨∗debug⟩

2149  \immediate\write16{
2150  INFO>~run~\string\transformfont\space\space
2151  <\font_family\font_weight\font_shape\raw_variant
2152  \raw_encoding\font_width>~from~
2153  <\font_family\font_weight\font_shape\raw_variant
2154  \raw_encoding>~(faking~narrow)

2155 } 2156 ⟨/debug⟩

2157  %%% WARNING: famtool.pl relies on this message format!!!
2158  \immediate\write16{
2159  Faking~narrow~font~
2160  \font_family\font_weight\font_shape\raw_variant
2161  \raw_encoding\font_width
2162  \space from~
2163  \font_family\font_weight\font_shape\raw_variant
2164  \raw_encoding

2165 }

2166  \transformfont{
2167  \font_family\font_weight\font_shape\raw_variant
2168  \raw_encoding\font_width

2169 }{

2170  \xscalefont{\fake_narrow_width}{
2171  \frommtx{
2172  \font_family\font_weight\font_shape\raw_variant
2173  \raw_encoding

2174 } 2175 } 2176 }

2177  \if_file_exists{ \raw_encoding.mtx }\then

2178 ⟨∗debug⟩

2179  \immediate\write16{

2180  INFO>~run~\string\installrawfont\space
2181  <\font_family\font_weight\font_shape\raw_variant
2182  \raw_encoding\font_width>
2183  <\font_family\font_weight\font_shape\raw_variant
2184  \raw_encoding\font_width,
2185  \raw_encoding>
2186  <\raw_encoding>
2187  <\raw_encoding>
2188  <\latex_family>
2189  <\latex_weight\latex_width>
2190  <\latex_shape>}

2191 ⟨/debug⟩

2192  \installrawfont{
2193  \font_family\font_weight\font_shape\raw_variant
2194  \raw_encoding\font_width
2195  }{ \font_family\font_weight\font_shape\raw_variant
2196  \raw_encoding\font_width,
2197  \raw_encoding
2198  }{ \raw_encoding
2199  }{ \raw_encoding
2200  }{ \latex_family
2201  }{ \latex_weight\latex_width
2202  }{ \latex_shape

2203 }{} 2204 \fi 2205 \fi 2206 \fi 2207 }

\fake_width_n_expert_encoding Called from \fake_width_n if the narrow width needs to be faked. Invokes

      \transformfont{<FONT>8xn}
        {\xscalefont{WIDTH}{\frommtx{<FONT>8x}}}

to generate an 8x-encoded .mtx file for a faked narrow font.

2208 \def\fake_width_n_expert_encoding{
2209 \if_file_exists{
2210  \font_family\font_weight\font_shape\raw_variant
2211  \expert_encoding.mtx
2212 }\then
2213  \if_file_exists{
2214  \font_family\font_weight\font_shape\raw_variant
2215  \expert_encoding\font_width.mtx
2216  }\then % no action required
2217  \else

2218 ⟨∗debug⟩

2219  \immediate\write16{
2220  INFO>~run~\string\transformfont\space\space
2221  <\font_family\font_weight\font_shape\raw_variant
2222  \expert_encoding\font_width>~from~
2223  <\font_family\font_weight\font_shape\raw_variant
2224  \expert_encoding>~(faking~narrow)

2225 } 2226 ⟨/debug⟩

2227  %%% WARNING: famtool.pl relies on this message format!!!
2228  \immediate\write16{
2229  Faking~narrow~font~
2230  \font_family\font_weight\font_shape\raw_variant
2231  \expert_encoding\font_width
2232  \space from~
2233  \font_family\font_weight\font_shape\raw_variant
2234  \expert_encoding

2235 }

2236  \transformfont{
2237  \font_family\font_weight\font_shape\raw_variant
2238  \expert_encoding\font_width

2239 }{

2240  \xscalefont{\fake_narrow_width}{
2241  \frommtx{
2242  \font_family\font_weight\font_shape\raw_variant
2243  \expert_encoding

2244 } 2245 } 2246 } 2247 \fi 2248 \fi 2249 }

14.4 Installing reencoded fonts

\latin_encoding \font_encoding \latex_encoding \latex_mtx  \latin_encoding{FONTENC}{EXPERTISED-ENC}{OLDSTYLE-ENC}{LATEXENC}{LATEXMTX}

If this is an expertised family EXPERTISED-ENC is used instead of FONTENC. If this is an expertised family with oldstyle digits OLDSTYLE-ENC is used instead of

  EXPERTISED-ENC.

UV 06/98: Added code for oldstyle encodings from Alan’s v 1.511. The

  \font_encoding is changed when \if_oldstyle_is true.

UV 06/98: Added anonther parameter for the default metrics file (which is

  usually either latin.mtx or textcomp.mtx).

UV 06/98: Added experimental code for OsF or SC&OsF fonts.

2250 \def\latin_encoding#1#2#3#4#5{
2251 \gdef\latex_encoding{#4}
2252 \gdef\latex_mtx{#5}
2253 \if_oldstyle_
2254  \gdef\font_encoding{#3}
2255 \else\if_expert_
2256  \gdef\font_encoding{#2}
2257 \else
2258  \gdef\font_encoding{#1}
2259 \fi\fi
2260 \gdef\expert_font{}
2261 \gdef\oldstyle_font{}
2262 \if_expert_
2263  \if_file_exists{
2264  \font_family\font_weight\raw_shape\raw_variant
2265  \expert_encoding\font_width.mtx
2266  }\then
2267  \gdef\expert_font{

2268  \font_family\font_weight\raw_shape\raw_variant
2269  \expert_encoding\font_width,

2270 } 2271 \fi 2272 \fi 2273 ⟨∗oldstyle⟩

2274 \if_oldstyle_
2275  \if_file_exists{
2276  \font_family\font_weight\raw_shape\oldstyle_variant
2277  \raw_variant\raw_encoding\font_width.mtx
2278  }\then
2279  \gdef\oldstyle_font{
2280  unsetnum,
2281  \font_family\font_weight\raw_shape\oldstyle_variant
2282  \raw_variant\raw_encoding\font_width,
2283  resetosf,

2284 } 2285 \fi 2286 \fi 2287 ⟨/oldstyle⟩ 2288 ⟨∗debug⟩

2289 \immediate\write16{
2290  INFO>~run~\string\installfont\space
2291  <\font_family\font_weight\font_shape\font_variant
2292  \font_encoding\font_width>
2293  <\font_family\font_weight\raw_shape\raw_variant
2294  \raw_encoding\font_width,
2295  \if_oldstyle_
2296  \ifx\font_shape\caps_shape
2297  resetosf,

2298 \fi 2299 \fi

2300  \expert_font
2301  \oldstyle_font
2302  \latex_mtx>
2303  <\latex_encoding\encoding_shape>
2304  <\latex_encoding>
2305  <\latex_family>
2306  <\latex_weight\latex_width>
2307  <\latex_shape>}

2308 ⟨/debug⟩

2309 \installfont{
2310  \font_family\font_weight\font_shape\font_variant
2311  \font_encoding\font_width

2312 }{

2313  \font_family\font_weight\raw_shape\raw_variant
2314  \raw_encoding\font_width,
2315  \if_oldstyle_
2316  \ifx\font_shape\caps_shape
2317  resetosf,

2318 \fi 2319 \fi

2320  \expert_font
2321  \oldstyle_font

2322  \latex_mtx

2323 }{

2324  \latex_encoding\encoding_shape

2325 }{

2326  \latex_encoding

2327 }{

2328  \latex_family

2329 }{

2330  \latex_weight\latex_width

2331 }{

2332  \latex_shape

2333 }{} 2334 }

14.5 Default weights, widths and shapes

Fontname: weight.map  NFSS: L^{A}TEX Companion, p. 190
a Thin Hairline  ul Ultra Light
j ExtraLight  el Extra Light
l Light  l Light
r Regular Roman  m Medium
k Book  m Medium
m Medium  mb (was: m)
d Demi  db (was: sb)
s Semibold  sb Semibold
b Bold  b Bold
h Heavy Heavyface  eb (was missing)
c Black  eb (was missing)
x ExtraBold ExtraBlack eb Extra Bold
u Ultra UltraBlack  ub Ultra Bold
p Poster  (still missing)

\latin_weights Each call to \latin_weight maps a Fontname weight code (\font_weight) to a

L^{A}TEX weight code (\latex_weight). Non-existing weights are ignored (or substituted when the .fd files are written out by \endinstallfont).

The standard values are given in the table. They may be changed, but you’d better know what you’re doing.

UV, 04/98: Changed the processing order: Do the most common shapes first. Added new mappings for c and h, changed mapping for m to newly invented L^{A}TEX weight mb.

2335 \def\latin_weights{
2336 \latin_weight{r}{m}
2337 \latin_weight{k}{m}
2338 \latin_weight{b}{b}
2339 \latin_weight{s}{sb}
2340 \latin_weight{d}{db} % was {d}{sb}, SPQR changed
2341 \latin_weight{m}{mb} % was {m}{m},  UV changed
2342 \latin_weight{c}{eb} % UV added
2343 \latin_weight{h}{eb} % UV added
2344 \latin_weight{x}{eb}
2345 \latin_weight{u}{ub}
2346 \latin_weight{l}{l}

2347 %\latin_weight{j}{el}
2348 %\latin_weight{a}{ul} % UV added

2349 }

Fontname: width.map  NFSS: L^{A}TEX Companion, p. 190
t Thin  – –
o Ultra Condensed  uc Ultra Condensed
u Ultra Compressed  uc . .
q Extra Compressed  ec Extra Condensed
c Condensed  c Condensed
p Compressed  c . .
n Narrow  c . .
– –  sc Semi Condensed
r Normal, Medium, Regular m Medium
– –  sx Semi Expanded
e Expanded  x Expanded
x Extended  x . .
v Extra Expanded  ex Extra Expanded
– –  ux Ultra Expanded
w Wide  – –

\latin_widths Each call to \latin_width maps a Fontname width code (\font_width) to a L^{A}TEX width code (\latex_width). Non-existing narrow fonts are faked only if \fakenarrow is specifically called for.

2350 \def\latin_widths{
2351 \latin_width{}{}
2352 \latin_width{n}{c}
2353 %latin_width{c}{c}
2354 %latin_width{x}{x}

2355 }

\latin_shapes The fifth argument of \latin_shape is stored in the variable \encoding_switches.
2356 \def\latin_shapes{
2357 \latin_shape{} {} {} {n} {\_textcomp_true }
2358 \latin_shape{c}{c}{} {sc}{\_textcomp_false}
2359 \latin_shape{o}{o}{} {sl}{\_textcomp_true }
2360 \latin_shape{i}{i}{i}{it}{\_textcomp_true }

2361 }

\latin_encodings  \encoding_switches is evaluated immediatley before the \if_textcomp_test to

set it as appropriate for the curent shape.

2362 \def\latin_encodings{
2363 \latin_encoding{7t}{9t}{9o}{OT1}{latin}
2364 \latin_encoding{8t}{9e}{9d}{T1} {latin}

2365 ⟨∗textcomp⟩

2366 \encoding_switches
2367 \if_textcomp_
2368  \latin_encoding{8c}{9c}{9c}{TS1}{textcomp}

2369 \fi 2370 ⟨/textcomp⟩ 2371 }

\if_textcomp_Switch to control whether or not to install a text companion encoding. It is set or unset for each shape by \latin_shapes and evaluated in \latin_encodings.

2372 \newif\if_textcomp_
\raw_encoding
\adobe_encoding
\expert_encoding

2373 \def\raw_encoding{8r}
2374 \def\adobe_encoding{8a}
2375 \def\expert_encoding{8x}
\caps_shape
\oldstyle_shape
2376 \def\caps_shape{c}
2377 \def\oldstyle_shape{j}
\SlantAmount
2378 \def\SlantAmount{167}

15 Version numbers

\needsfontinstversion The macro:
      \needsfontinstversion{NUMBER}

checks the version number.

2379 \def\needsfontinstversion#1{{
2380 \a_dimen=#1pt
2381 \b_dimen=\fontinstversion~pt\relax
2382 \ifnum\a_dimen>\b_dimen
2383  \immediate\write16{}
2384  \immediate\write16{Warning:~This~file~needs~fontinst~version~#1.}
2385  \immediate\write16{Warning:~You~are~using~version~\fontinstversion.}
2386  \immediate\write16{Warning:~This~may~cause~errors.}
2387  \immediate\write16{}

2388 \fi 2389 }}

The directory for temporary files.

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

16 Debugging

\NOFILES \NOFILES switches off file generation, and causes fontinst only to generate empty files.

2392 \def\NOFILES{
2393 \def\transformfont##1##2{
2394  \touch_file{##1.mtx}
2395  \touch_file{##1.pl}

2396 }

2397 \def\installfonts{}
2398 \def\endinstallfonts{}

2399 \def\installfont##1##2##3##4##5##6##7##8{%
2400  \touch_file{##1.vpl}

2401 }

2402 \def\installrawfont##1##2##3##4##5##6##7##8{%
2403  \touch_file{##1.pl}

2404 }

2405 \def\installfamily##1##2##3{
2406  \touch_file{##1##2.fd}

2407 } 2408 }

\touch_file
2409 \def\touch_file#1{
2410 \edef\lowercase_file{\lowercase{
2411  \edef\noexpand\lowercase_file{#1}}}
2412 \lowercase_file
2413 \open_out{\lowercase_file}
2414 \out_line{\percent_char~TEST~FILE.}
2415 \out_line{\percent_char~Created~whilst~debugging~fontinst.}
2416 \close_out{Test~file}

2417 }

By default, show as much error info as you can. (I assume fontinst users are TEXperts.)

2418 \errorcontextlines=999
    Set \newlinechar for \errhelp messages.
2419 \newlinechar=`\^^J

17 Final cleanup

If \bye hasn’t been defined, define it (for L^{A}TEX).

2420 \ifx\bye\undefined_command
2421 \def\supereject{\par\penalty-\@MM}
2422 \outer\x_cs\def{bye}{\par\vfill\supereject\@@end}

2423 \fi

Restore the catcodes we changed.

2424 \catcode`\@=\atcatcode
2425 \catcode`\^^M=\nlcatcode
2426 \catcode`\ =\spacecatcode
2427 \catcode`\~=\tildecatcode

We input the fontinst.rc file, if it exists. (Search order changed 1997/02/07

  <Thierry.Bouche@ujf-grenoble.fr>.)

UV, 06/1998: What is this fontinst.rc file good for? It turns out that you can use it to do \def\raw_encoding{8y} if you prefer to install your fonts the other way.

2428 \if_file_exists{fontinst.rc}\then
2429 \primitiveinput fontinst.rc
2430 \catcode`\_=\underscorecatcode
2431 \else

2432 \catcode`\_=\underscorecatcode
2433 \immediate\write16{No file fontinst.rc.}

2434 \fi 2435 ⟨/pkg⟩

The fontdoc package

18 Overview

The purpose of the fontdoc package is to support typesetting of .etx and .mtx files intended for use with fontinst. The typical format of these files looks something like this:

\documentclass[twocolumn]{article}
\usepackage{fontdoc}
\begin{document}

TEX commands

\encoding or \metrics
fontinst commands
\endencoding or \endmetrics

TEX commands

\end{document}

To make it work, fontdoc has to define all the user-level fontinst commands in terms of typesetting instructions.

19 Implementation

Some global variables:

2436 ⟨∗doc⟩

2437 \newdimen\a@dimen
2438 \newcount\a@count

Some useful macros and constrol structures:

2439 \def\x@cs#1#2{\expandafter#1\csname#2\endcsname}

\setcommand \resetcommand Macros that set define new commands.

2440 \def\setcommand#1{\ifx#1\undefined@command
2441 \expandafter\def\expandafter#1\else
2442 \expandafter\def\expandafter\a@command\fi}
2443 \def\resetcommand#1{\def#1}
\ifisglyph \ifisint \ifisdim \ifisstr \then All conditionals are treated as true.
2444 \def\ifisglyph#1\then{\iftrue}
2445 \def\ifisint#1\then{\iftrue}
2446 \def\ifisdim#1\then{\iftrue}
2447 \def\ifisstr#1\then{\iftrue}
2448 \let\then=\iffalse

\setdim \setint \setstr Macros that set integers, dimens or strings.

2449 \def\setdim#1#2{\a@dimen=#2\relax\Bheading{Default} #1 = \the\a@dimen}
2450 \def\setint#1#2{\Bheading{Default} #1 = $\expression0{#2}$}
2451 \def\setstr#1#2{\Bheading{Default} #1 = #2}

\resetdim \resetint \resetstr Macros that reset integers, dimens or strings.

2452 \def\resetdim#1#2{\a@dimen=#2\relax\Bheading{Value} #1 = \the\a@dimen}
2453 \def\resetint#1#2{\Bheading{Value} #1 = $\expression0{#2}$}
2454 \def\resetstr#1#2{\Bheading{Value} #1 = #2}

Utilities for typesetting nested arithmetic expressions.

2455 \def\expression#1#2{\a@count=#1\relax#2}
2456 \def\priority#1#2{
2457 \ifnum\a@count<#1
2458  \let\next=\identity
2459 \else
2460  \let\next=\bracket

2461 \fi

2462 \next{#2}}
2463 \def\identity#1{#1}
2464 \def\bracket#1{(#1)}

Plain TEX’s \int and \div are redfined as \plainint and \plaindiv, since we are going to use them for other purposes.

2465 \let\plainint=\int
2466 \let\plaindiv=\div

\int \width \height \depth \italic \kerning Macros that return integer expressions are printed in symbolic form.

2467 \def\int#1{{\fam0#1}}
2468 \def\width#1{w({\fam0#1})}
2469 \def\height#1{h({\fam0#1})}
2470 \def\depth#1{d({\fam0#1})}
2471 \def\italic#1{i({\fam0#1})}
2472 \def\kerning#1#2{k({\fam0#1})({\fam0#1})}
\neg \add \sub \mul \div \max \min \scale Nested arithmetic expressions are typeset using \expression and \priority.
2473 \def\neg#1{\priority8{-\expression6{#1}}}
2474 \def\add#1#2{\priority2{\expression2{#1}+\expression2{#2}}}
2475 \def\sub#1#2{\priority2{\expression3{#1}-\expression3{#2}}}
2476 \def\mul#1#2{\priority4{\expression4{#1}\times\expression4{#2}}}
2477 \def\div#1#2{\priority4{\expression5{#1}/\expression5{#2}}}
2478 \def\max#1#2{\priority6{\expression6{#1}\sqcup\expression6{#2}}}
2479 \def\min#1#2{\priority7{\expression7{#1}\sqcap\expression7{#2}}}
2480 \def\scale#1#2{\div{\mul{#1}{#2}}{1000}}

\Aheading and \Bheading are used to typeset various headings.

2481 \def\Aheading#1{\par\medskip\noindent{\bf#1}\par}
2482 \def\Bheading#1{\par\noindent{\bf#1}}
\needsfontinstversion  \needfontinstversion is printed out as a comment.
2483 \def\needsfontinstversion#1{\Bheading{Needs fontinst v#1}}
\encoding \endencoding \slot@number The \encoding and \endencoding macros define a group and initialize the
  \slot@number counter.
2484 \def\encoding{\bgroup\slot@number=0}
2485 \def\endencoding{\egroup}

\nextslot \skipslots  \nextslot sets the \slot@number. \skipslots advances the \slot@number.
2486 \newcount\slot@number
2487 \def\nextslot#1{\slot@number=#1\relax}
2488 \def\skipslots#1{\advance\slot@number by #1\relax}
\setslotcomment \resetslotcomment \unsetslotcomment \useexamplefont \slotexample \slot@comment \slot@font In this version of fontinst, we have added an interface for automatic documen-

tation 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:

     \useexamplefont{FONT}
     \setslotcomment{The symbol `\slotexample'.}
     \setslot{FOO}\endsetslot
     \setslot{BAR}\endsetslot
     \resetslotcomment{The character `\slotexample'.}
     \setslot{BAZ}\endsetslot

instead of having to write:

     \usepackage{PACKAGE-to-use-symbols-from-FONT}
     \setslot{FOO}\comment{The symbol `\foo'.}\endsetslot
     \setslot{BAR}\comment{The symbol `\bar'.}\endsetslot
     \setslot{BAZ}\comment{The character `\baz'.}\endsetslot
2489 \newif\ifslot@comment@
2490 \slot@comment@false
2491 \def\slot@comment{}
2492 \def\setslotcomment#1{%
2493 \slot@comment@true
2494 \gdef\slot@comment{#1}}
2495 \def\resetslotcomment#1{%
2496 \gdef\slot@comment{#1}}
2497 \def\unsetslotcomment{%
2498 \slot@comment@false
2499 \gdef\slot@comment{}}
2500 %  \end{macrocode}

2501 %

2502 %    \begin{macrocode}
2503 \let\slot@font=\nullfont
2504 \def\useexamplefont#1{\font\slot@font=#1 }
2505 \def\slotexample{{\slot@font\char\the\slot@number}}
\setslot \endsetslot \slot@name  \setslot ... \endslot commands print out the slot number, optionally followed

by a default slot comment.

2506 \def\setslot#1{\def\slot@name{#1}%
2507 \Aheading{Slot \the\slot@number\space `#1'}%
2508 \ifslot@comment@ \comment{\slot@comment}\fi}
2509 \def\endsetslot{\advance\slot@number by 1\relax}

\comment Slot comments are typeset as a text paragraph.

2510 \def\comment{\par\noindent}

\ligature Symbolic typesetting of \ligature programs requires special processing.

2511 \def\ligature#1{\Bheading{Ligature} \csname doc-#1\endcsname}
2512 \x@cs\def{doc-LIG}#1#2{%
2513 $\fam0 \slot@name * #1 \rightarrow #2$}
2514 \x@cs\def{doc-/LIG}#1#2{%
2515 $\fam0 \slot@name * #1 \rightarrow \slot@name * #2$}
2516 \x@cs\def{doc-LIG/}#1#2{%
2517 $\fam0 \slot@name * #1 \rightarrow #2 * #1$}
2518 \x@cs\def{doc-/LIG/}#1#2{%
2519 $\fam0 \slot@name * #1 \rightarrow \slot@name * #2 * #1$}
2520 \x@cs\def{doc-/LIG>}#1#2{%
2521 $\fam0 \slot@name * #1 \rightarrow \slot@name + #2$}
2522 \x@cs\def{doc-LIG/>}#1#2{%
2523 $\fam0 \slot@name * #1 \rightarrow #2 + #1$}
2524 \x@cs\def{doc-/LIG/>}#1#2{%
2525 $\fam0 \slot@name * #1 \rightarrow \slot@name + #2 * #1$}
2526 \x@cs\def{doc-/LIG/>>}#1#2{%
2527 $\fam0 \slot@name * #1 \rightarrow \slot@name + #2 + #1$}
\nextlarger \varchar \vartop \varmid \varbot \varrep  \nextlarger and \varchar ... \endvarchar commands.
2528 \def\nextlarger#1{\Bheading{Next larger} #1}
2529 \def\varchar{\Bheading{Extensible glyph:}}
2530 \def\vartop#1{\Bheading{Top} #1}
2531 \def\varmid#1{\Bheading{Middle} #1}
2532 \def\varbot#1{\Bheading{Bottom} #1}
2533 \def\varrep#1{\Bheading{Repeated} #1}
2534 \let\endvarchar\relax
\metrics \endmetrics The \metrics and \endmetrics macros just define a group.
2535 \def\metrics{\bgroup}
2536 \def\endmetrics{\egroup}
\setkern \setleftkerning \setrightkerning \setleftrightkerning Setting kern pair manipulations.
2537 \def\setkern#1#2#3{%
2538 \Bheading{Kern} ${\fam0 #1 + #2} \rightarrow \expression0{#3}$}
2539 \def\setleftkerning#1#2#3{%
2540 \Bheading{Kern} #1 on the left like #2 scaled $\expression0{#3}$}
2541 \def\setrightkerning#1#2#3{%
2542 \Bheading{Kern} #1 on the right like #2 scaled $\expression0{#3}$}
2543 \def\setleftrightkerning#1#2#3{%
2544 \Bheading{Kern} #1 on the left and right like #2 scaled $\expression0{#3}$}

\setrawglyph Setting raw glyphs.

2545 \def\setrawglyph#1#2#3#4#5#6#7#8{\Aheading{Glyph `#1'}
2546 \Bheading{Taken from} slot #4 in font #2}

\setglyph \resetglyph \endsetglyph \endresetglyph Setting and resetting glpyhs.
2547 \def\setglyph#1{\Aheading{Glyph `#1'}}
2548 \def\resetglyph#1{\Aheading{Reset glyph `#1'}}
2549 \def\endsetglyph{}
2550 \def\endresetglyph{}
\glyph \glyphrule \glyphspecial \glyphwarning Glyph commands used in \setglyph ... \endsetglyph.
2551 \def\glyph#1#2{\Bheading{Glyph} `#1' scaled $\expression0{#2}$}
2552 \def\glyphrule#1#2{%
2553 \Bheading{Rule} $\expression0{#1}$ by $\expression0{#2}$}
2554 \def\glyphspecial#1{\Bheading{Special} `#1'}
2555 \def\glyphwarning#1{\Bheading{Warning} `#1'}
\movert \moveup
2556 \def\movert#1{\Bheading{Rt}~$\expression0{#1}$}
2557 \def\moveup#1{\Bheading{Up}~$\expression0{#1}$}

{\push \atop \pop}

2558 \def\push{\Bheading{Push}}
2559 \def\pop{\Bheading{Pop}}
\resetwidth
\resetheight
\resetdepth
\resetitalic

2560 \def\resetwidth#1{\Bheading{Reset width to $\expression0{#1}$}}
2561 \def\resetheight#1{\Bheading{Reset height to $\expression0{#1}$}}
2562 \def\resetdepth#1{\Bheading{Reset depth to $\expression0{#1}$}}
2563 \def\resetitalic#1{\Bheading{Reset italic to $\expression0{#1}$}}

Some last-minute commands.

2564 \raggedright
2565 \raggedbottom
2566 \def\plain{{\tt plain}}

2567 ⟨/doc⟩

Index

Numbers written in italic refer to the page where the corresponding entry is described, the ones underlined to the code line of the definition, the rest to the code lines where the entry is used.

A

\add . . . . . . . . . . . . . . . . . . . \underline{255}, \underline{2473} \add_to . . . . . . . . . . . . . . . . . . . . . \underline{164} \adobe_encoding . . . . . . . . . . . . . \underline{2373} \afmtomtx . . . . . . . . . . . . . . . . 16, \underline{336}

C

\caps_shape . . . . . . . . . . . . . . . . . \underline{2376} \close_out . . . . . . . . . . . . . . . . . . \underline{172} \comment . . . . . . . . . . . . . . . \underline{658}, \underline{2510}

D

\declareencoding . . . . . . . . . . . . \underline{1537}

\declaresize . . . . . . . . . . . . . . . . \underline{1553} \depth . . . . . . . . . . . . . . . . . \underline{744}, \underline{2467} \dim . . . . . . . . . . . . . . . . . . . . . 12, \underline{236} \div . . . . . . . . . . . . . . . . . . . \underline{255}, \underline{2473}

E

\empty_command . . . . . . . . . . . . . . . \underline{141} \encoding . . . . . . . . . . . . . . . . . . \underline{2484} \encoding_shape . . . . . . . . . . . . . \underline{1766}

\encoding_switches . . . . . . . . . . . \underline{1766}

\enctoext . . . . . . . . . . . . . . . . 15, \underline{275} \endencoding . . . . . . . . . . . . . . . . \underline{2484}

\endinstallfonts . . . . . . . . . 42, \underline{1392}

\endmetrics . . . . . . . . . . . . . . . . . \underline{2535} \endresetglyph . . . . . . . . . . \underline{798}, \underline{2547} \endsetglyph . . . . . . . . . . . . \underline{798}, \underline{2547} \endsetslot . . . . . . . . . . . . . \underline{650}, \underline{2506} \etx_to_vpl . . . . . . . . . . . . . . . . . . \underline{963} \etxtopl . . . . . . . . . . . . . . . . . 33, \underline{943} \etxtovpl . . . . . . . . . . . . . . . . 33, \underline{943} \eval_expr . . . . . . . . . . . . . . . . . . \underline{251} \eval_expr_to . . . . . . . . . . . . . . . . \underline{251}

\expert_encoding . . . . . . . . . . . . \underline{2373}

F

\fake_shape_. . . . . . . . . . . . . . . . \underline{1791} \fake_shape_c . . . . . . . . . . . . . . . \underline{1924}

\fake_shape_expert_encoding . . . \underline{1882}

\fake_shape_i . . . . . . . . . . . . . . . \underline{2115} \fake_shape_o . . . . . . . . . . . . . . . \underline{1941}

\fake_shape_o_expert_encoding . \underline{2029}
\fake_shape_o_oldstyle_encoding  \underline{2071}
\fake_shape_o_raw_encoding . . . . \underline{1959}
\fake_shape_oldstyle_encoding . \underline{1894}
\fake_shape_raw_encoding . . . . . . \underline{1826}

\fake_width_. . . . . . . . . . . . . . . . \underline{2122} \fake_width_n . . . . . . . . . . . . . . . \underline{2124}

\fake_width_n_expert_encoding . \underline{2208}
\fake_width_n_raw_encoding . . . . \underline{2138}

\fakenarrow . . . . . . . . . . . . . . . . . \underline{2118} \fd_family . . . . . . . . . . . . . . . . . \underline{1437} \fd_shape . . . . . . . . . . . . . . . . . . \underline{1472} \fd_size . . . . . . . . . . . . . . . . . . . \underline{1479} \first_char . . . . . . . . . . . . . . . . . . \underline{163} \first_of_two . . . . . . . . . . . . . . . . \underline{141} \font_encoding . . . . . . . . . . . . . . \underline{2250} \font_family . . . . . . . . . . . . . . . . \underline{1714} \font_shape . . . . . . . . . . . . . . . . . \underline{1766} \font_variant . . . . . . . . . . . . . . . \underline{1714} \font_weight . . . . . . . . . . . . . . . . \underline{1756} \font_width . . . . . . . . . . . . . . . . . \underline{1761}

\fontinstversion . . . . . . . . . . . . . . \underline{7}

\fromafm . . . . . . . . . . . . . . . . 48, \underline{1577} \frommtx . . . . . . . . . . . . . . . . 48, \underline{1577} \frompl . . . . . . . . . . . . . . . . . 48, \underline{1577}

G

\g_eval_expr_to . . . . . . . . . . . . . . \underline{251} \g_let . . . . . . . . . . . . . . . . . . . . . . \underline{138} \glyph . . . . . . . . . . . . . . . . . \underline{864}, \underline{2551} \glyphpcc . . . . . . . . . . . . . . . . . . . \underline{919} \glyphrule . . . . . . . . . . . . . \underline{879}, \underline{2551} \glyphspecial . . . . . . . . . . . \underline{889}, \underline{2551} \glyphwarning . . . . . . . . . . . \underline{889}, \underline{2551} \gobble_one . . . . . . . . . . . . . . . . . . \underline{141} \gobble_three . . . . . . . . . . . . . . . . \underline{141} \gobble_two . . . . . . . . . . . . . . . . . . \underline{141}

H

\height . . . . . . . . . . . . . . . . \underline{744}, \underline{2467}

I

\identity_one . . . . . . . . . . . . . . . . \underline{141} \if_expert_. . . . . . . . . . . . . . . . . \underline{1754}

\if_fake_narrow_. . . . . . . . . . . . \underline{2116}

\if_false . . . . . . . . . . . . . . . . . . . \underline{180} \if_file_exists . . . . . . . . . . . . . . \underline{194} \if_oldstyle_. . . . . . . . . . . . . . . \underline{1754} \if_textcomp_. . . . . . . . . . . . . . . \underline{2372} \if_true . . . . . . . . . . . . . . . . . . . . \underline{180} \ifiscommand . . . . . . . . . . . . . . 12, \underline{239} \ifisdim . . . . . . . . . . . . 12, \underline{239}, \underline{2444} \ifisglyph . . . . . . . . . . . . . \underline{936}, \underline{2444} \ifisint . . . . . . . . . . . . 12, \underline{239}, \underline{2444} \ifisstr . . . . . . . . . . . . 12, \underline{239}, \underline{2444} \input_mtx_file . . . . . . . . . . . . . \underline{1409}

\input_mtx_files . . . . . . . . . . . . \underline{1399}

\inputetx . . . . . . . . . . . . . . . . 24, \underline{639} \inputmtx . . . . . . . . . . . . . . . . 25, \underline{673} \install_font . . . . . . . . . . . . . . . \underline{1366} \installfamily . . . . . . . . . . . 42, \underline{1356} \installfont . . . . . . . . . . . . . 42, \underline{1360} \installfonts . . . . . . . . . . . . 42, \underline{1350} \installrawfont . . . . . . . . . . 42, \underline{1360} \int . . . . . . . . . . . . . . . . 12, \underline{236}, \underline{2467} \italic . . . . . . . . . . . . . . . . \underline{744}, \underline{2467}

K

\kerning . . . . . . . . . . . . . . . \underline{735}, \underline{2467}

L

\latex_encoding . . . . . . . . . . . . . \underline{2250} \latex_mtx . . . . . . . . . . . . . . . . . \underline{2250} \latex_shape . . . . . . . . . . . . . . . . \underline{1766} \latex_variant . . . . . . . . . . . . . . \underline{1714} \latex_weight . . . . . . . . . . . . . . . \underline{1756} \latex_width . . . . . . . . . . . . . . . . \underline{1761} \latin_encoding . . . . . . . . . . . . . \underline{2250}

\latin_encodings . . . . . . . . . . . . \underline{2362}

\latin_shape . . . . . . . . . . . . . . . . \underline{1766} \latin_shapes . . . . . . . . . . . . . . . \underline{2356} \latin_weight . . . . . . . . . . . . . . . \underline{1756} \latin_weights . . . . . . . . . . . . . . \underline{2335} \latin_width . . . . . . . . . . . . . . . . \underline{1761} \latin_widths . . . . . . . . . . . . . . . \underline{2350} \latinfamily . . . . . . . . . . . . . . . . \underline{1698}

\left_brace_char . . . . . . . . . . . . . \underline{148}

\ligature . . . . . . . . . . . . . . \underline{658}, \underline{2511} \lose_measure . . . . . . . . . . . . . . . . \underline{158}

M

\max . . . . . . . . . . . . . . . . . . . \underline{255}, \underline{2473} \metrics . . . . . . . . . . . . . . . . . . . \underline{2535} \min . . . . . . . . . . . . . . . . . . . \underline{255}, \underline{2473} \movert . . . . . . . . . . . . . . . . \underline{895}, \underline{2556} \moveup . . . . . . . . . . . . . . . . \underline{895}, \underline{2556} \mtxtomtx . . . . . . . . . . . . . . . 49, \underline{1610} \mtxtopl . . . . . . . . . . . . . . . . 41, \underline{1311} \mul . . . . . . . . . . . . . . . . . . . \underline{255}, \underline{2473}

N

\needsfontinstversion . . . \underline{2379}, \underline{2483}

\neg . . . . . . . . . . . . . . . . . . . \underline{255}, \underline{2473} \never_do . . . . . . . . . . . . . . . . . . . \underline{171} \nextlarger . . . . . . . . . . . . . \underline{658}, \underline{2528} \nextslot . . . . . . . . . . . . . . \underline{655}, \underline{2486} \NOFILES . . . . . . . . . . . . . . . . . . . \underline{2392}

O

\oldstyle_shape . . . . . . . . . . . . . \underline{2376} \open_out . . . . . . . . . . . . . . . . . . . \underline{172} \out_file . . . . . . . . . . . . . . . . . . . \underline{132} \out_line . . . . . . . . . . . . . . . . . . . \underline{172} \out_lline . . . . . . . . . . . . . . . . . . \underline{172} \out_llline . . . . . . . . . . . . . . . . . . \underline{172}

P

\parse_family . . . . . . . . . . . . . . . \underline{1714} \percent_char . . . . . . . . . . . . . . . . \underline{148} \pltomtx . . . . . . . . . . . . . . . . . 21, \underline{500} \pop . . . . . . . . . . . . . . . . . . . \underline{909}, \underline{2558} \primitiveinput . . . . . . . . . . . . . . \underline{204} \push . . . . . . . . . . . . . . . . . . \underline{909}, \underline{2558}

R

\raw_encoding . . . . . . . . . . . . . . . \underline{2373} \raw_shape . . . . . . . . . . . . . . . . . \underline{1766} \raw_variant . . . . . . . . . . . . . . . . \underline{1714} \reencodefont . . . . . . . . . . . . 48, \underline{1589} \remove_shape . . . . . . . . . . . . . . . \underline{1486} \resetcommand . . . . . . . . 12, \underline{221}, \underline{2440} \resetdepth . . . . . . . . . . . . . \underline{915}, \underline{2560} \resetdim . . . . . . . . . . . 12, \underline{221}, \underline{2452} \resetglyph . . . . . . . . . . . . . \underline{788}, \underline{2547} \resetheight . . . . . . . . . . . . \underline{915}, \underline{2560} \resetint . . . . . . . . . . . 12, \underline{221}, \underline{2452} \resetitalic . . . . . . . . . . . . \underline{915}, \underline{2560}

\resetslotcomment . . . . . . . \underline{668}, \underline{2489}

\resetstr . . . . . . . . . . . 12, \underline{221}, \underline{2452} \resetwidth . . . . . . . . . . . . . \underline{915}, \underline{2560}

\right_brace_char . . . . . . . . . . . . \underline{148}

S

\samesize . . . . . . . . . . . . . . . . . . . \underline{926} \scale . . . . . . . . . . . . . . . . . \underline{255}, \underline{2473} \scalefont . . . . . . . . . . . . . . 48, \underline{1589} \second_of_two . . . . . . . . . . . . . . . \underline{141} \setcommand . . . . . . . . . . 12, \underline{209}, \underline{2440} \setdim . . . . . . . . . . . . . 12, \underline{209}, \underline{2449} \setglyph . . . . . . . . . . . . . . \underline{777}, \underline{2547} \setint . . . . . . . . . . . . . 12, \underline{209}, \underline{2449} \setkern . . . . . . . . . . . . . . . \underline{681}, \underline{2537} \setleftkerning . . . . . . . . . \underline{700}, \underline{2537}

\setleftrightkerning . . . . . \underline{700}, \underline{2537}

\setnotglyph . . . . . . . . . . . . . . . . . \underline{835} \setrawglyph . . . . . . . . . . . . \underline{805}, \underline{2545}

\setrightkerning . . . . . . . . \underline{700}, \underline{2537}

\setslot . . . . . . . . . . . . . . . \underline{650}, \underline{2506} \setslotcomment . . . . . . . . . \underline{668}, \underline{2489} \setstr . . . . . . . . . . . . . 12, \underline{209}, \underline{2449} \skipslots . . . . . . . . . . . . . \underline{655}, \underline{2486} \SlantAmount . . . . . . . . . . . . . . . . \underline{2378} \slantfont . . . . . . . . . . . . . . 48, \underline{1589} \slot@comment . . . . . . . . . . . . . . . \underline{2489} \slot@font . . . . . . . . . . . . . . . . . \underline{2489} \slot@name . . . . . . . . . . . . . . . . . \underline{2506} \slot@number . . . . . . . . . . . . . . . . \underline{2484} \slot_name . . . . . . . . . . . . . . . . . . \underline{650} \slot_number . . . . . . . . . . . . . . . . . \underline{655} \slotexample . . . . . . . . . . . . \underline{668}, \underline{2489} \str . . . . . . . . . . . . . . . . . . . . . 12, \underline{236} \sub . . . . . . . . . . . . . . . . . . . \underline{255}, \underline{2473}

\substitute_series . . . . . . . . . . . \underline{1505}
\substitute_shape . . . . . . . . . . . \underline{1489}
\substitutenoisy . . . . . . . . . . . . \underline{1520}
\substitutesilent . . . . . . . . . . . \underline{1520}

T

\then . . . . . . . . . . . . . . . . . . . . . . \underline{2444} \touch_file . . . . . . . . . . . . . . . . . \underline{2409} \transformfont . . . . . . . . . . . 48, \underline{1567}

U

\unsetcommand . . . . . . . . . . . . . 13, \underline{247} \unsetdim . . . . . . . . . . . . . . . . 13, \underline{247} \unsetglyph . . . . . . . . . . . . . . . . . . \underline{863} \unsetint . . . . . . . . . . . . . . . . 13, \underline{247}

                                       \unsetslotcomment . . . . . . . \underline{668}, \underline{2489}

\unsetstr . . . . . . . . . . . . . . . . 13, \underline{247} \useexamplefont . . . . . . . . . \underline{668}, \underline{2489}

V \varbot . . . . . . . . . . . . . . . . \underline{664}, \underline{2528} \varchar . . . . . . . . . . . . . . . \underline{658}, \underline{2528} \varmid . . . . . . . . . . . . . . . . \underline{664}, \underline{2528} \varrep . . . . . . . . . . . . . . . . \underline{664}, \underline{2528} \vartop . . . . . . . . . . . . . . . . \underline{664}, \underline{2528}

W \width . . . . . . . . . . . . . . . . . \underline{744}, \underline{2467}

X \x_cs . . . . . . . . . . . . . . . . . . . . . . . \underline{138} \x_relax . . . . . . . . . . . . . . . . . . . . \underline{138} \xscalefont . . . . . . . . . . . . . . 48, \underline{1589}

Y \yscalefont . . . . . . . . . . . . . . 48, \underline{1589}