The fontinst utility

Alan Jeffrey, Sebastian Rahtz, Ulrik Vieth, Lars Hellström

November 16, 1999

Contents

The fontinst documentation 4

1 Files 4 1.1 Source files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2 Generated files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.3 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 About previous fontinst releases 6 2.1 Pre-doc fontinst releases . . . . . . . . . . . . . . . . . . . . . . . . 6 2.2 About fontinst v 1.8 . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 About this fontinst release 7 3.1 Metric packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.2 Word boundary ligatures and kerns . . . . . . . . . . . . . . . . . . 9 3.3 Changing the names of glyphs . . . . . . . . . . . . . . . . . . . . . 10 3.4 Making map file fragments . . . . . . . . . . . . . . . . . . . . . . . 12 3.5 On monowidth and typewriter fonts . . . . . . . . . . . . . . . . . 14

4 Notes on using fontinst 15 4.1 General notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.2 Notes on small caps and olstyle fonts . . . . . . . . . . . . . . . . . 15

5 fontdoc package overview 16

a fibasics.dtx 18

6 The first and the last 18 6.1 Version numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 6.2 Special catcodes and configuration file . . . . . . . . . . . . . . . . 19 6.3 Plain TEX macros from fontinst.ini . . . . . . . . . . . . . . . . 20

7 Basic definitions 22 7.1 Declaring variables and constants . . . . . . . . . . . . . . . . . . . 22 7.2 Trigonometry macros . . . . . . . . . . . . . . . . . . . . . . . . . . 23 7.3 fontdoc-specific declarations . . . . . . . . . . . . . . . . . . . . . . 23 8 TEX hackery 23

8.1 Utiltiy macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 8.2 Writing to output files . . . . . . . . . . . . . . . . . . . . . . . . . 25 8.3 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 8.4 Real numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 8.5 Error, warning, and info messages . . . . . . . . . . . . . . . . . . 33

b fimain.dtx 38

9 General commands 38 9.1 Setting variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 9.2 For loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 9.3 Integer expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 9.4 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

10 Encoding files 48

11 Metric files 54 11.1 Kerning information . . . . . . . . . . . . . . . . . . . . . . . . . . 56 11.2 Glyph information . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 11.3 Glyph commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

12 Converting an ETX file to a (V)PL file 69 12.1 Lowest-level user interface . . . . . . . . . . . . . . . . . . . . . . . 69 12.2 Glyph to slot assignments . . . . . . . . . . . . . . . . . . . . . . . 71 12.3 The header, mapfonts, and fontdimens . . . . . . . . . . . . . . . . 74 12.4 The ligtable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 12.5 The characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 12.6 Slot commands that put things in a character property list …. 81 12.7 Saved map commands . . . . . . . . . . . . . . . . . . . . . . . . . 82 12.8 Tidying up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

13 Font installation commands and .fd files 84 13.1 Writing font definition files . . . . . . . . . . . . . . . . . . . . . . 86 13.2 Default encodings and font sizes . . . . . . . . . . . . . . . . . . . 88

14 Debugging 89

c ficonv.dtx 91

15 Basic file format conversions 91 15.1 Converting an ENC file to an ETX file . . . . . . . . . . . . . . . . 91 15.2 Converting an AFM file to an MTX file . . . . . . . . . . . . . . . 92 15.3 Converting a PL file to an MTX file . . . . . . . . . . . . . . . . . 98 15.4 Converting an MTX file to a PL file . . . . . . . . . . . . . . . . . 103 16 Font transformations 104

16.1 Transformable metric files . . . . . . . . . . . . . . . . . . . . . . . 104 16.2 Making font transformations . . . . . . . . . . . . . . . . . . . . . 104 16.3 Changing glyph names . . . . . . . . . . . . . . . . . . . . . . . . . 111

d filtfam.dtx 120

17 Installing Latin families 120 17.1 Processing a list of weights, widths and shapes . . . . . . . . . . . 121 17.2 Faking font shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 17.3 Faking font widths . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 17.4 Installing reencoded fonts . . . . . . . . . . . . . . . . . . . . . . . 133 17.5 Default weights, widths and shapes . . . . . . . . . . . . . . . . . . 135

e fimapgen.dtx 138

18 Generating map file fragments 138 18.1 Interface to main fontinst . . . . . . . . . . . . . . . . . . . . . . . 138 18.2 User interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 18.3 Deducing values for the map file entries . . . . . . . . . . . . . . . 145 18.4 Driver makers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

Internal notes 158

A Typographic treatment 158

B Planning topics 158 B.1 Reorganisation of the source . . . . . . . . . . . . . . . . . . . . . . 158 B.2 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

C Contributors 159

D To do 160 D.1 Things to do in the “near” future . . . . . . . . . . . . . . . . . . . 160 D.2 Things that probably won’t be done in the near future . . . . . . . 161 D.3 Things that have been done . . . . . . . . . . . . . . . . . . . . . . 161 D.4 Other notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

E Efficiency 163 E.1 Alan Jeffrey’s tests . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 E.2 Current tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

About the fontinst package

This document describes version 1.9 of fontinst. This is a prerelease, and in particular this document (the commented source) has much of an internal debate paper about it. The files generated from the source should however work (there may of course be various bugs in them).

1 Files

1.1 Source files

The source for fontinst is currently split on the five source files fibasics.dtx,

fimain.dtx, ficonv.dtx, filtfam.dtx, and fimapgen.dtx.

1.2 Generated files

By running the docstrip installation script fontinst.ins, the following files are generated:

fontinst.sty This is the executable file that contains all the commands that set up the fontinst utility for use.

xfntinst.sty This is a variant of fontinst.sty which behaves differently with respect to from which fonts the digits are picked (see below).

cfntinst.sty This is a variant of fontinst.sty which supports the old way of selecting boundarychar for fonts (i.e., by setting the integer boundarychar). It requires a bit more memory than fontinst.sty does.

fontinst.ini This file contains some very basic initialization code. It is used in case fontinst is used under iniTEX without a preloaded format.

finstmsc.sty This file contains the routines for automatic map file generation, which is still a part of the fontinst system that is under construction, but which does work as of v 1.904. This file also contains some seldom-used code (the ENC to ETX conversion) that has been broken off from the main fontinst utility, as it almost always just sat there and used up space for no good reason.

fontdoc.sty This file contains the fontdoc package, which can be used to typeset encoding and metric files.

csc2x.tex This file contains the reglyphing commands that set up the common caps-and-small-caps to expert names conversion. See Subsections 3.3 and 16.3 for details.

csckrn2x.tex This file is a variant of csc2x.tex, which doesn’t copy the commands that actually set glyphs.

1.3 Modules

The source is split up on the following docstrip modules: ⟨pkg⟩, all files Guards code that is to go into fontinst.sty (and its variants). ⟨doc⟩, fibasics and fimain Guards code that is to go into fontdoc.sty. ⟨driver⟩, all files Guards the driver code—the short piece of L^{A}TEX code in the

beginning of each file that makes it possible to typeset as a L^{A}TEX document. docstrip.ins doesn’t extract this code, but it is possible to write a script that makes docstrip extract this code if one wants to write a modified driver. It’s not usual, though.

⟨pkg2⟩, fibasics A special variant of ⟨pkg⟩ that is used for code that is to end

up at the very end of fontinst.sty. ⟨ini⟩, fibasics Guards the code for fontinst.ini. ⟨everyjob⟩, fibasics Guards the code setting \everyjob for fontinst formats (by

default not used). ⟨misc⟩, fibasics, fimain, and ficonv Guards code that is only to go into

     finstmsc.sty.

⟨!misc⟩, fibasics Guards code that is not to go into finstmsc.sty. ⟨oldTeX⟩, fibasics Guards code that copes with a bug in TEX versions before

3.141. ⟨!oldTeX⟩, fibasics Guards normal code that wouldn’t work satisfactory for TEX

versions before 3.141 due to a bug in those TEXs. ⟨boundaryCompability⟩, fimain Guards code that is needed for fontinst to be com-

patible with the old interface for boundary ligatures and kerns. ⟨!boundaryCompability⟩, fimain Guards code that is used when fontinst is not to

be compatible with the old interface for boundary ligatures and kerns. ⟨obsolete⟩, fimain Guards miscellaneous pieces of code that are considered obso-

lete. ⟨reglyph⟩, ficonv Guards code that is to go to the reglyphing setup files

     csc2x.tex and csckrn2x.tex.

⟨!glyphs⟩, ficonv Guards reglyphing setup code that is relevant when commands

that set glyphs are not to be copied. ⟨glyphs⟩, ficonv Guards reglyphing setup code that is relevant when commands

that set glyphs are to be copied. ⟨textcomp⟩, filtfam Guards code in the \latinfamily section that generates

text symbol (TS1/“text companion”) fonts. ⟨debug⟩, filtfam Guards code in the \latinfamily section that writes INFO>

messages.

⟨oldstyle⟩, filtfam Guards code in the \latinfamily section. The purpose of that code is described in more detail in Section 4.

⟨map⟩, fimapgen Guards the code for the automatic map file generation.

2 About previous fontinst releases

2.1 Pre-doc fontinst releases

The following is a choice of some fontinst versions and some comments about them. The complete list of versions in the range v 0.01–1.7 can be found in the

file CHANGES.

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. Until the summer of 1998 this was still the version to be found in the fonts/utilities/fontinst directory 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 fonts/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 fonts/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 exist.

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 fonts/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.

2.2 About fontinst v 1.8

Version 1.8 of the fontinst utility was the first to have been converted to docstrip format (this was made by Ulrik Vieth) and it was first released 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, version v 1.8 also incorporated 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.

Version 1.8 was agreed upon by the fontinst hacker community, as represented on the fontinst mailing list, as the new officially endorsed version, on which all further additions and enhancements can be based.

3 About this fontinst release

Several improvements, some of which fixes old bugs and some of which introduces new features, have been made to in particular the generation of fonts. The most important are:

• The old multiple \setkern bug, which resulted in pointless KRN instructions being written to (V)PL files have been fixed. In addition, it is now possible to reset kerns (using \resetkern) and unset kerns (using \unsetkerns,

\noleftkerning, \norightkerning, or \noleftrightkerning).

• A bug which resulted in too few kerns being written to a font if the same glyph is used in more than one slot (this occurs if you make an all-caps font from an encoding definition file which sets \lc, \lctop, and \lclig to the same to their \uc… counterparts) has been fixed. A consequence of this fix is that you cannot access the number of the slot that glyph ⟨glyph⟩ has been assigned to as \int{⟨glyph⟩} (unless you are using cfntinst.sty), but there really is no need for you to do so either.

• There is now a proper interface for using left and right boundaries which, in contrast to the old setting of the integer boundarychar, can make use of the full generality of the PL format. (The old interface is still available if you

use cfntinst.sty.)

• fontinst can now interpret AFM files which contain non-integer dimensions. There is also a user-level interface for changing the formula according to which the italic corrections of glyphs are computed.

• The PL to MTX converter can now cope with the VPL-unique property lists VTITLE, MAP, and MAPFONT, which means that it can now convert VPL files as well. In addition to this, there are a couple of minor bugfixes and improvements in the PL to MTX conversion.

• There is now a way of overriding the PL to MTX converter’s automatic choice of encoding definition file made based on the CODINGSCHEME property of a PL file. The command \generalpltomtx lets you select which encoding definition file you want to use, as does the new \fromplgivenetx transformed font command.

• Several fontinst commands that were previously missing have been added to the fontdoc package. The most significant are probably \inputmtx and

\inputetx.

• There is now a simple way of changing the names of glyphs in metric files generated from AFM files.

• The implementation of font metrics transformations, as done by \transformfont, has been rewritten. This can result in different font metrics, but we think only in that it comes out more like one would expect. The user interface is the same.

• There is now a new transformed font command \fromany which searches for a font metric file in any of the four formats MTX, PL, AFM, and VPL; converting it to MTX format and possibly generating a PL as well if required. This command is also used by \installfont, \installrawfont, and \reglyphfont to search for font metric files, so these can now take VPL files as a source for font metric data.

• The automatic map file generation is now working! It does not yet generate a map file that any known driver can read, however, but the interface to main fontinst has been established and there is a system for opening and closing output files, writing map files for multiple drivers simultaneously, and avoiding duplicate entries. What is missing is the routines for writing the actual entries; here we hope for contributions from other fontinst users.

3.1 Metric packages

The idea of the metric package commands is to make it easier to split all the commands normally kept in latin.mtx on several files, which is handy if one wants to make minor modifications to some of the commands or simply leave some of the parts in latin.mtx out to speed up the fontmaking.^{1} They are not of any use to those who use fontinst only at the \latinfamily level, but they should prove useful to those who are in the business of modifying latin.mtx or writing their own alternatives, as it simplifies modularisation.

1In my experience, the speedup can be considerable./LH

The main problem with splitting up latin.mtx (or some other metric file which fulfills an equivalent function) is that there are some commands which are defined at the top and which are then used in almost all sections of the file. One must make certain that these commands are always loaded, which makes the metric files somewhat harder to use (especially if the one who tries to use them is not the one who wrote them).

One strategy is to include all definitions needed for a metric file in it. This has the slight disadvantage that the commands will have to be definied several times. What is worse however, is that the command definitions will appear in several files, so if one finds a bug in one of them, one cannot simply correct this bug in one place. As the number of files can soon become quite large, correcting such bugs can become a boring procedure indeed.

Another strategy is to put all the command definitions in one file and then explicitly include it in the ⟨file-list⟩ argument of \installfont. This eliminates the repeated bug fixing problem, but requires the user to do something that the computer can actually do just as well.

A third strategy is to put the command definitions in one or several files and then in each metric file the user explicitly mensions load the command definitions needed for that particular file. Metric packages uses an improved version of this strategy, since they also make it possible for fontinst to remember which packages (i.e., sets of command definitions) that have already been loaded, so that they are not unnecessarily loaded again.

For information on syntax etcetera, see Section 11.

3.2 Word boundary ligatures and kerns

One of the new features added in TEX 3 was that of ligatures and kerns with word boundaries. fontinst has had an interface for making such ligatures and kerns, but it has been completely redesigned in v 1.9 and the old interface (setting the integer boundarychar) is no longer recognized by fontinst. Files which use the old interface can still be processed with cfntinst.sty, though.

Before considering the new commands, it is suitable to make a distinction between proper glyphs and pseudoglyphs. A proper glyph has been set using one

of the commands \setrawglyph, \setglyph, and \resetglyph. A pseudoglyph

is any name used in the context of a glyph name which does not denote a proper glyph. If a pseudoglyph g-not was set using the \setnotglyph command, the if \ifisglyph{g-not}\then will evaluate to true, but something can be a pseudoglyph even if an \ifisglyph test evaluates to false. The interesting point about pseudoglyphs when considering word boundaries however, is that a pseudoglyph can have ligatures and kerns.

Kerns and ligatures at the left word boundary (beginning of word) are specified

using the commands \setleftboundary and \endsetleftboundary, which are

syntactically identical to \setslot and \endsetslot respectively. One important difference is however that the argument to \setslot must be a proper glyph, while the argument to \setleftboundary may be any glyph, hence any pseudoglyph will do just fine.

   \ligature commands between \setleftboundary and \endsetleftboundary

will generate beginning of word ligatures. Kerns on the right of the glyph specified in \setleftboundary will become beginning of word kerns.

Kerns and ligatures at the right word boundary (end of word) are trickier, due to the asymmetrical nature of the ligkern table in a PL file. What a font can do is to specify that the right word boundary, for purposes of kerning and ligatures, should be interpreted as character n. By including a kern or ligature with character n on the right, that kern or ligature will be used at the end of a word, but it will also be used each time the next character is character n. Because of this, one usually wants the slot n, which the right word boundary is interpreted as being, to be empty whenever the encoding allows this.

The command

     \setrightboundary{⟨glyph⟩}

will mark the current slot as used to denote the right word boundary, and leave the slot empty, increasing the current slot number by one just like a \setslot … \endsetslot block does. Kerns on the left of ⟨glyph⟩ will be end of word kerns and \ligature commands with ⟨glyph⟩ as the second argument will be for the end of a word.

The command

     \makerightboundary{⟨glyph⟩}

is similar to \setrightboundary, but it is a slot command which may only be used

between a \setslot and the matching \endsetslot. Like \setrightboundary,

it marks the current slot as used to denote the right word boundary, but the glyph specified in the enclosing \setslot will be written to that slot. Ligatures for the glyph specified by the \setslot and ligatures for the glyph specified by the \makerightboundary will both be for this single slot. Kerns on the right of the \setslot glyph and the \makerightboundary glyph will similarly both be for this single slot. The idea is that the \setslot glyph should be used when making a kern or ligature for that glyph, while the \makerightboundary glyph should be used when making a kern or ligature for the end of a word. fontinst will warn you if these two uses of the slot directly contradict each other.

3.3 Changing the names of glyphs

Sometimes, primarily when making a virtual font from more than one raw font and two of the raw fonts contain different glyps with the same name, it becomes necessary to change the names of some glyphs to make some sense out of it. The main source of this kind of trouble is the “caps and small caps” (CSC) and “oldstyle figures” (OsF) fonts within many commercial font families. The typical problem is that what is typographically different glyphs—such as the lowercase ‘a’ (a, for fontinst) and the smallcaps ‘a’ (Asmall, for fontinst)—are given the same name by the foundry.

One way to get round this is to say for example

     \setglyph{Asmall} \glyph{a}{1000} \endsetglyph
     \setleftrightkerning{Asmall}{a}{1000}
     \unsetglyph{a}
     \noleftrightkerning{a}

and continuing like that for all the duplicate glyph names. This is however a rather prolix method and if the number of glyphs is large then it is usually simpler to use the \reglyphfont command.

To reglyph one or several fonts, one writes

     \reglyphfonts

⟨reglyphing commands⟩

     \endreglyphfonts

There are two types of reglyphing commands: the \reglyphfont command, and the commands that modify what \reglyphfont will do to the fonts it operates on. The syntax of \reglyphfont is

\reglyphfont{⟨destination font⟩}{⟨source font⟩}

The ⟨source font⟩ font here is the name (suffix not included, of course) of the font metric file one wants to change the glyph names in. This font metric file can be in any of the formats MTX, PL, AFM, and VPL, and it will be converted to MTX format if it isn’t already in that format (this happens just as for files listed in the second argument of \installfont). ⟨destination font⟩ (which must be different from ⟨source font⟩) will be taken as the name for a new .mtx file that will be generated. The destination font can differ from the source font only in two ways: the names of some glyphs in the source font might be changed, and some of the commands from the source font might not have been copied to the destination font. To what extent the fonts are different is determined by what modifying commands have been executed; when no modifying commands have been executed, the source and destination font are equal.

The modifying reglyphing commands are

     \renameglyph{⟨to⟩}{⟨from⟩}
     \renameglyphweighted{⟨to⟩}{⟨from⟩}{⟨weight⟩}
     \killglyph{⟨glyph⟩}
     \killglyphweighted{⟨glyph⟩}{⟨weight⟩}
     \offmtxcommand{⟨command⟩}
     \onmtxcommand{⟨command⟩}

\renameglyph simply declares that occurencies of the glyph name ⟨from⟩ should be replaced by the glyph name ⟨to⟩. To each glyph name is also assigned a weight, which is used by a mechanism which conditions copying of commands from the source font to the destination font by the set of glyphs that command mensions. The details of this mechanism are however somewhat tricky, so those interested in the full generality should go to Subsection 16.3. Here it needs only be noted that if one applies \killglyph to a glyph name, then (under most circumstances) commands that refer to that glyph name will not be copied to the destination font.

\offmtxcommand and \onmtxcommand also control whether commands are copied to the destination font, but they look at the actual command rather than the glyphs it refers to. For example, after the command

     \offmtxcommand{\setkern}

no \setkern commands will be copied. By using \offmtxcommand, it is possible to achieve effects similar to those of the files kernoff.mtx and glyphoff.mtx—the difference is that with \offmtxcommand, it happens at an earlier stage of the font generation. As expected, \onmtxcommand undoes the effect of \offmtxcommand.

The effects of modifying reglyphing commands are delimited by \reglyphfonts and \endreglyphfonts, which starts and ends a group respectively.

As we expect the most common reglyphing operation will be to go from CSC glyph names to expert glyph names, there is a file csc2x.tex in the fontinst distribution which contains the modifying reglyphing commands needed for setting up that conversion. Thus you can write for example

     \reglyphfonts
       \input csc2x
       \reglyphfont{padrcx8r}{padrc8r}
       \reglyphfont{padscx8r}{padsc8r}
     \endreglyphfonts

to alter the glyph names in the CSC fonts in the Adobe Garamond (pad) family. Note that the names of the destination fonts here really are rather arbitrary, since they will only exist as .mtx files, and thus only need to work within your local file system. In particular, all the \setrawglyph commands in the destination font files still refer to the source font, so it is that font which the drivers need to know about.

3.4 Making map file fragments

The mechanism that lets fontinst write the fragments of a DVI driver map file the driver would need to handle a set of fonts generated by fontinst is still under construction, but it has now reached the level where it can be helpful. The goal is that the map file fragment writer should be able to write the lines^{2} of a map file that the driver would need for handling the raw fonts fontinst has (i) installed directly (using \installrawfont) or (ii) used as a base font for some installed virtual font (generated by \installfont). There is still some work to do before that goal is met, however.

What the map file fragment writer can do today is that it can tell you

• which fonts there need to be entries in the map file for,

• for each font what metric transformations (scaling, slanting, etc.) need to be applied,

• for each font whether it must be reencoded and in that case to what encoding,

• for most fonts what the postscript name for this font is (you’ll probably need this if the driver is to generate postscript or PDF output).

You still have to edit it all into some format that your driver will understand, but at least you will be spared the work of collecting the information.

Now what does one have to do to use this map file fragment writer, then? First you need to tell fontinst to record the information the map file fragment writer needs. You do this by giving the command

     \recordtransforms{whatever.tex}

at the beginning of the run. Here whatever.tex is the name of a file that will be created, so you can use some other name if you like. After that you do all the

calls to \transformfont, \installfont, \installrawfont, \latinfamily, etc.

you need to make the fonts you want. When you’re done, you give the command

2Not in general an entire map file, hence the word fragment.

     \endrecordtransforms

and end the run (say \bye). The file whatever.tex will now contain the information about which fonts were used and what needs to be done with them.

The second step is to actually run the map file fragment writer. Observe that it is located in the file finstmsc.sty, not fontinst.sty! The commands you need to give it can be so few that you can type them in at TEX’s * prompt, but if you are writing a command file then it should typically have the following structure (comments not necessary, of course):

\input finstmsc.sty              % Input command definitions
⟨general settings⟩  % See below

      \adddriver{debug}{whatever.map}  % Open output file
      \input whatever.tex              % Write to output file

\donedrivers                     % Close output file(s), tidy up

      \bye                             % Quit

The \adddriver command gives the order “write map file entries for the ⟨first argument⟩ DVI driver to the file ⟨second argument⟩.” The plan is that it should be possible to use the name of just about any major driver (dvips, xdvi,^{3} pdftex, OzTeX, etc.) here and get suitable map file entries for that driver as output, but for the moment the only acceptable value for the first argument is debug. The entries in the file that is written for the debug “DVI driver” simply contain all the available information about each font (hence it should come handy for debugging code writing entries for real drivers) in a format that should be easy to interpret for a human.

The file whatever.tex in the above example contains the commands (\makemapentry commands) that actually cause entries to be written to the output file. It also contains a number of \storemapdata commands—these describe how some given font was made. One problem with the current setup is that if the MTX file for some font was made before the \recordtransforms command was given, perhaps on an earlier fontinst run, then the file whatever.tex above will not contain a \storemapdata for that font, and in this case subsequent \makemapentrys won’t know what to make of it, so you’ll get an error message. There are two ways to avoid this: (i) include a \storemapdata for each font made before \recordtransforms in the command file, for example in the ⟨general settings⟩ part, or (ii) see to that you only use fonts that have their MTX files generated after the \recordtransforms command. fontinst makes it a little tricky to use (ii), since MTX files usually won’t be generated if one with the right name already exists. To be on the safe side here, you’ll have to delete all MTX files generated from AFM, PL, VPL, or other MTX files between each fontinst run. We plan to have that annoying detail fixed by the time the next fontinst release is made, however.

Another class of things that will typically appear in the ⟨general settings⟩ part above is commands that will inform the routines actually writing output about characteristics of your TEX system, of the set of fonts you are using on this run, or of something else that might be useful. For the moment, there are three commands of this type, all of which has to do with what should be used for the postscript font name of a font whose metrics are taken from a PL file.

\AssumeMetafont Assume all fonts with PL metrics are bitmaps generated by Metafont, and therefore make no entries for them.

3Or does that use the same map file as dvips? I heard somewhere that it did. /LH

\AssumeAMSBSYY Assume all fonts with PL metrics have their TEX names in all upper case as postscript names—just like the Computer Modern fonts in the AMS/Blue Sky/Y&Y distribution.

\AssumeBaKoMa Assume all fonts with PL metrics have their TEX names in all lower case as postscript names—just like the Computer Modern fonts in the BaKoMa distribution.

Otherwise the default action is that the routine for finding out this simply observes that it hasn’t got a clue about what the right value is when the metrics were taken from a PL file, and therefore this field comes out as ‘??????’ in those cases.

3.5 On monowidth and typewriter fonts

Traditionally, the monowidth integer has controlled the aspects of the behaviour of fontinst’s standard metric and encoding files that have to do with monowidth and typewriter fonts. Unlike all the other integers, the value of this integer did not matter, only whether the integer was set or not. The user typically set this integer outside an \installfonts … \endinstallfonts block (if it was to be set during all font installations in that block), or in the first file in the file-list argument of \installfont or \installrawfont (if it should only be set for a few files installed in that block).

The effects of setting this integer has been rather diverse and the only way to find out exactly which they are for any given setup is to read the metric and encoding files in question. The general idea is however that everything in a monowidth font should have width a multiple of the width of an ordinary letter, so that characters on different rows will always align horizontally. This means for example that spaces of such fonts will get zero stretch and shrink, since that would otherwise completely mess up the alignment.

However, some of the things monowidth has used to control really was not about the font being a monowidth font, but rather about the font being a typewriter font. There is a large covariance between these two concepts, but they are not equivalent, and hence code that is conditioned by these two attributes should not be controlled through a single switch. Therefore a second variable typewriter has been introduced to control the typewriter aspects of what metric and encoding files do.

To get the old effect of setting monowidth, one should now set both monowidth and typewriter. To give some support to old code, there is also code which will set typewriter if it isn’t set and monowidth is set to anything but 9876. The code that does this will however disappear eventually, and it always prints a warning message on the terminal.

The above may give the impression that the change to typewriter taking over some of the functions of monowidth has completely taken place, but this is not the case. To date, only the files ot1.etx, 8r.etx, and 8y.etx have been updated this way, and even though all encoding and metrics files that are affected by typewriter/monowidth characteristics should eventually be updated, the change will probably be slow and for a few files at a time. The process of introducing this distinction also poses some questions which seem suited for a public debate. One of these which are espectially noteworthy is which effects typewriter should have in t1.etx, since this file has previously ignored typewriter aspects of fonts.

4 Notes on using fontinst

The primary purpose of fontinst is to simplify the installation of PostScript or TrueType text fonts.

4.1 General notes

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.

4.2 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. The current version of \latinfamily does not implement this, but it would be a worthwile approach, and advanced fontinst users are encouraged to attempt it. The file csckrn2x.tex (a variant of csc2x.tex, which is mensioned in Subsection 3.3) should come in handy for this.

5 fontdoc package 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:

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

L^{A}TEX commands

\encoding or \metrics

fontinst commands

\endencoding or \endmetrics

L^{A}TEX commands

\end{document}

To make it work, fontdoc has to define all the user-level fontinst commands in terms of typesetting instructions. This goal is currently only partially achieved, but the percentage of fontinst commands covered by fontdoc is still fairly large, so it is our impression that problems with commands not covered occur only very rarely.

File a

fibasics.dtx

6 The first and the last

6.1 Version numbers

We start by making 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.910}
 9 \def\filedate{1999/11/04}

10 ⟨/pkg | doc⟩

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

specific \ProvidesPackage stuff.

11 ⟨∗pkg | doc⟩

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

16 ⟨/pkg | doc⟩

Now we can identify ourselves as usual.

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

“Can’t say I’ve ever been too fond of beginnings, myself. Messy little things. Give me a good ending any time. You know where you are with an ending.”

— from The kindly ones by Neil Gaiman et al.

While we’re at version numbers anyway, we might as well define the command for testing them. Note however that the module name is not ⟨pkg⟩ as above, but ⟨pkg2⟩. Code in the latter module ends up at the very end of fontinst.sty!

\needsfontinstversion The macro:
     \needsfontinstversion{⟨number⟩}

checks the version number.

22 ⟨∗pkg2⟩

23 \def\needsfontinstversion#1{{
24 \a_dimen=#1pt
25 \b_dimen=\fontinstversion~pt\x_relax
26 \ifnum\a_dimen>\b_dimen
27  \immediate\write16{}
28  \immediate\write16{Warning:~This~file~needs~fontinst~version~#1.}
29  \immediate\write16{Warning:~You~are~using~version~
30  \fontinstversion.}
31  \immediate\write16{Warning:~This~may~cause~errors.}
32  \immediate\write16{}
33 \fi
34 }}

35 ⟨/pkg2⟩

In fontdoc, \needsfontinstversion is printed out as a comment.

36 ⟨∗doc⟩

37 \def\needsfontinstversion#1{\Bheading{Needs fontinst v\thinspace#1}}

38 ⟨/doc⟩

6.2 Special catcodes and configuration file

fontinst uses some unusual, but convenient, settings of \catcode. @ and _are made letters, ~ is made a space, and space and newline are ignored. Before setting those however, we save the current values of the catcodes, so that they can be restored at the end of fontinst.sty.

39 ⟨∗pkg⟩

40 \edef\spacecatcode{\the\catcode`\ }
41 \edef\nlcatcode{\the\catcode`\^^M}
42 \edef\atcatcode{\the\catcode`\@}
43 \edef\underscorecatcode{\the\catcode`\_}
44 \edef\tildecatcode{\the\catcode`\~}
45 \catcode`\ =9
46 \catcode`\^^M=9
47 \catcode`\@=11
48 \catcode`\_=11
49 \catcode`\~=10

50 ⟨/pkg⟩

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

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.

51 ⟨∗pkg2⟩ 52 ⟨∗!misc⟩

53 \if_file_exists{fontinst.rc}\then
54 \primitiveinput fontinst.rc
55 \else
56 \immediate\write16{No~file~fontinst.rc.}
57 \fi

58 ⟨/!misc⟩

Use a different configuration file for finstmsc.sty.

59 ⟨∗misc⟩

60 \if_file_exists{finstmsc.rc}\then
61 \primitiveinput finstmsc.rc
62 \else
63 \immediate\write16{No~file~finstmsc.rc.}
64 \fi

65 ⟨/misc⟩

At the end of fontinst.sty, we restore the catcodes we changed.

66 \catcode`\@=\atcatcode
67 \catcode`\^^M=\nlcatcode
68 \catcode`\ =\spacecatcode
69 \catcode`\~=\tildecatcode
70 \catcode`\_=\underscorecatcode

71 ⟨/pkg2⟩

6.3 Plain TEX macros from fontinst.ini

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

72 ⟨∗pkg⟩

73 \ifx\@ne\undefined_command
74 \input fontinst.ini\relax
75 \fi

76 ⟨/pkg⟩

77 ⟨∗ini⟩

78 \chardef\active=13

79

80 \chardef\@ne=1
81 \chardef\tw@=2
82 \chardef\thr@@=3
83 \chardef\sixt@@n=16
84 \chardef\@cclv=255
85 \mathchardef\@cclvi=256
86 \mathchardef\@m=1000
87 \mathchardef\@M=10000
88 \mathchardef\@MM=20000

89

90 \count10=22 % allocates \count registers 23, 24, ...
91 \count11=9 % allocates \dimen registers 10, 11, ...
92 \count15=9 % allocates \toks registers 10, 11, ...
93 \count16=-1 % allocates input streams 0, 1, ...
94 \count17=-1 % allocates output streams 0, 1, ...
95 \count20=255 % allocates insertions 254, 253, ...
96 \countdef\insc@unt=20 % the insertion counter
97 \countdef\allocationnumber=21 % the most recent allocation
98 \countdef\m@ne=22 \m@ne=-1 % a handy constant
99 \def\wlog{\immediate\write\m@ne} % write on log file (only)

100

101 \countdef\count@=255
102 \dimendef\dimen@=0

103

104 \outer\def\newcount{\alloc@0\count\countdef\insc@unt}

105 \outer\def\newdimen{\alloc@1\dimen\dimendef\insc@unt}
106 \outer\def\newtoks{\alloc@5\toks\toksdef\@cclvi}
107 \outer\def\newread{\alloc@6\read\chardef\sixt@@n}
108 \outer\def\newwrite{\alloc@7\write\chardef\sixt@@n}

109

110 \def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
111 \ch@ck#1#4#2% make sure there's still room
112 \allocationnumber=\count1#1%
113 \global#3#5=\allocationnumber
114 \wlog{\string#5=\string#2\the\allocationnumber}}
115 \outer\def\newinsert#1{\global\advance\insc@unt by\m@ne
116 \ch@ck0\insc@unt\count
117 \ch@ck1\insc@unt\dimen
118 \ch@ck2\insc@unt\skip
119 \ch@ck4\insc@unt\box
120 \allocationnumber=\insc@unt
121 \global\chardef#1=\allocationnumber
122 \wlog{\string#1=\string\insert\the\allocationnumber}}
123 \def\ch@ck#1#2#3{\ifnum\count1#1<#2%
124 \else\errmessage{No~room~for~a~new~#3}\fi}

125

126 \outer\def\newif#1{\count@\escapechar \escapechar\m@ne
127 \expandafter\expandafter\expandafter
128 \edef\@if#1{true}{\let\noexpand#1=\noexpand\iftrue}%
129 \expandafter\expandafter\expandafter
130 \edef\@if#1{false}{\let\noexpand#1=\noexpand\iffalse}%
131 \@if#1{false}\escapechar\count@} % the condition starts out false
132 \def\@if#1#2{\csname\expandafter\if@\string#1#2\endcsname}
133 {\uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}} % `if' is required

134

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

137

138 \def\space{~}
139 \let\bgroup={
140 \let\egroup=}

141

142 \def\loop#1\repeat{\def\body{#1}\iterate}
143 \def\iterate{\body \let\next\iterate \else\let\next\relax\fi \next}
144 \let\repeat=\fi % this makes \loop...\if...\repeat skippable

145

146 \def\supereject{\par\penalty-\@MM}
147 \outer\def\bye{\par\vfill\supereject\end}

148 ⟨/ini⟩

The two last commands above also need to be defined if we’re running under L^{A}TEX. In that case we need to be careful with \bye however, as no \if… can skip over code that explicitly contains that control sequence, if it has been defined as above.

149 ⟨∗pkg⟩

150 \ifx\bye\undefined_command
151 \def\supereject{\par\penalty-\@MM}
152 \outer\expandafter\def \csname bye\endcsname
153  {\par\vfill\supereject\@@end}

154 \fi

155 ⟨/pkg⟩

156 ⟨∗ini & everyjob⟩

157 \everyjob{%
158 \if_file_exists{fontinst.rc}\then
159  \primitiveinput~fontinst.rc
160 \else
161  \immediate\write16{No~file~fontinst.rc.}
162 \fi

163 } 164 ⟨/ini & everyjob⟩

7 Basic definitions

7.1 Declaring variables and constants

Some temporary variables:

165 ⟨∗pkg⟩

166 \newcount\a_count
167 \newcount\b_count
168 \newcount\c_count
169 \newcount\d_count
170 \newcount\e_count
171 \newcount\f_count
172 \newcount\g_count
173 \newdimen\a_dimen
174 \newdimen\b_dimen
175 \newdimen\c_dimen
176 \newdimen\d_dimen
177 \newtoks\a_toks
178 \newtoks\b_toks
179 \newtoks\c_toks
180 \newif\if_a_

Besides these temporary variables that have to be declared, the family of control sequences with names of the form \⟨letter⟩_macro, such as \a_macro, \b_macro, etc., should be used as “macro valued” temporary variables.

\out_file Some global variables:

181 \newwrite\out_file

Some constants:

182 \mathchardef\one_thousand=1000
183 \mathchardef\five_hundred=500
184 \mathchardef\one_hundred=100
185 \mathchardef\max_mathchardef="7FFF

7.2 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 v 1.8 these hacks been moved to an earlier place since we put in \ProvidesPackage ourselves.

186 \let\@tempdima\a_dimen
187 \let\@tempdimb\b_dimen
188 \input trig.sty

189 ⟨/pkg⟩

7.3 fontdoc-specific declarations

Two global variables:

190 ⟨∗doc⟩

191 \newdimen\a@dimen
192 \newcount\a@count

Some useful macros and constrol structures:

193 \def\x@cs#1#2{\expandafter#1\csname#2\endcsname}
\Aheading \Bheading  \Aheading and \Bheading are used to typeset various headings.
194 \def\Aheading#1{%
195 \par\addvspace\medskipamount
196 \noindent\textbf{#1}\vadjust{\penalty200}\par

197 }

198 \def\Bheading#1{\par\noindent{\bf#1}}

Some formating commands and a macro that comes in handy:

199 \raggedright
200 \raggedbottom
201 \def\plain{{\tt plain}}
\plainint \plaindiv fontdoc saves away Plain TEX’s \int and \div as \plainint and \plaindiv,

since we are going to use the control sequences for other purposes.

202 \let\plainint=\int
203 \let\plaindiv=\div

204 ⟨/doc⟩

8 TEX hackery

8.1 Utiltiy macros

\x_cs \x_relax \g_let

205 ⟨∗pkg⟩

206 \def\x_cs#1#2{\expandafter#1\csname#2\endcsname}
207 \let\x_relax=\relax
208 \def\g_let{\global\let}

209 ⟨/pkg⟩

\x@relax
210 ⟨doc⟩\let\x@relax=\relax

\empty_command
\gobble_one
\gobble_two
\gobble_three
\identity_one
\first_of_two
\second_of_two

211 ⟨∗pkg⟩

212 \def\empty_command{}
213 \def\gobble_one#1{}
214 \def\gobble_two#1#2{}
215 \def\gobble_three#1#2#3{}
216 \def\identity_one#1{#1}
217 \def\first_of_two#1#2{#1}
218 \def\second_of_two#1#2{#2}
\hash_char
\percent_char
\left_brace_char
\right_brace_char

219 \bgroup
220 \catcode`\[=1
221 \catcode`\]=2
222 \catcode`\#=12
223 \catcode`\%=12
224 \catcode`\{=12
225 \catcode`\}=12
226 \gdef\hash_char[#]
227 \gdef\percent_char[%]
228 \gdef\left_brace_char[{]
229 \gdef\right_brace_char[}]
230 \egroup

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

231 {

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

235 }

\first_char Return the first character of a string.

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

\add_to Append one or more tokens to the replacement text of a parameterless macro.

237 \def\add_to#1#2{
238 \ifx#1\x_relax
239  \def#1{#2}
240 \else
241  \expandafter\def\expandafter#1\expandafter{#1#2}
242 \fi

243 }

\prep_to Prepend one or more tokens to the replacement text of a parameterless macro. Note that if more than one token is added then the second parameter must contain an \expandafter between every pair of tokens you actually mean to contribute. Thus if you want to prepend abc to \next, you must write

      \prep_to\next{a\expandafter b\expandafter c}

Also note that the second argument must not be empty.

244 \def\prep_to#1#2{
245 \ifx#1\x_relax

246  \expandafter\def\expandafter#1\expandafter{\expandafter#2}
247 \else
248  \expandafter\def\expandafter#1\expandafter{\expandafter#2#1}
249 \fi

250 }

\never_do The command \do, protected from expansion.

251 \def\never_do{\noexpand\do}

8.2 Writing to output files

LH 1999/03/04: As of v 1.901, there are two different output file models in fontinst. One has been along “forever” and is for writing output to files which are only open for a short period of time—every fontinst file command that opens a file in this model must also close it—and it can only be used for one file at at time. The other model offers pooled allocation of output files—as long as there is an unused TEX output stream to open, you may open a new file, and it does not matter if files are not closed in the revese order of that in which they were opened.

\open_out \close_out \out_line \out_lline \out_llline These macros implement the classical output file commands.

252 \def\open_out#1{
253 \immediate\openout\out_file=#1 \xdef\out_filename{#1}}
254 \def\close_out#1{
255 \immediate\write16{#1~written~on~\out_filename.}
256 \immediate\closeout\out_file}
257 \def\out_line#1{\immediate\write\out_file{#1}}
258 \edef\out_lline#1{\noexpand\out_line{\space\space\space#1}}
259 \edef\out_llline#1{
260 \noexpand\out_line{\space\space\space\space\space\space#1}

261 }

\pout_line In the new model, the basic writing command \pout_line takes two arguments: a file identifier control sequence and the token sequence to write. Thus its call looks like

\pout_line⟨identifier⟩{⟨text⟩}

The ⟨identifier⟩ is usually a chardef token whose number tells which input stream is used, but if TEX runs out of output streams then it might be defined as a parameterless macro which expands to \m@ne. This has the effect of making all output to that “file” go to the log file, from which the data might be salvaged.

\out_filename-STREAM The new model operates using the control sequence family \out_filename-⟨stream⟩ both for storing the name of the output file and for handling allocation of output streams.

\TeX_terminal \closed_stream \out_filename-99 \out_filename--1 Output streams 16 and above always write to TEX’s terminal, and any output file that gets closed gets its identifier set to 99 so that any attempts to write to a closed file can be easily spotted. (99 is the character code for c.) Output stream –1 is the log file, and if another output stream cannot be allocated then attempts to write to the output file will be redirected to the log file.

262 \def\TeX_terminal{\string\TeX\space terminal}
263 \chardef\closed_stream=99
264 \x_cs\let{out_filename-99}=\TeX_terminal
265 \x_cs\def{out_filename--1}{\jobname.log}

\allocate_stream
\ch@ck
266 \def\allocate_stream{
267 \a_count=\m@ne
268 \b_count=\m@ne
269 \loop \ifnum \count17>\a_count

While \a_count < the number of the last allocated output stream …

270  \advance \a_count \@ne
271  \x_cs\ifx{out_filename-\the\a_count}\TeX_terminal

If \out_filename-⟨stream⟩, where ⟨stream⟩ is the value of \a_count, is equal to \TeX_terminal, then output stream \a_count is allocated to the pool but is not used for any currently open file. Thus we’ve found a stream that can be used.

272  \b_count=\a_count
273  \a_count=\count17
274  \fi
275 \repeat
276 \ifnum \b_count=\m@ne

In this case all streams allocated to the pool are currently in use, so try to allocate a new one.

277  \global\advance\count17by\@ne
278  \ifnum \count17<\sixt@@n

Then case: There was another output stream.

279  \b_count=\count17
280  \global\x_cs\let{out_filename-\the\b_count}\TeX_terminal
281  \wlog{\string\write\the\b_count\space allocated~to~the~pool.}
282  \else

Else case: See to that the output stream allocation register holds at 16.

283  \global\count17=\sixt@@n
284  \fi
285 \fi

286 }

By now, if a new stream could be allocated then the number of that stream is in \b_count, and if it couldn’t then \b_count is –1.

All output streams up to and including that whose number is in \count17 is checked to see if it is available. Many unsuccessful \newwrites could therefore mean we have to do quite a lot of checking. What’s more, output stream 99 would incorrectly be interpreted as being in the pool but not used. To guard against these (improbable) errors, \ch@ck is redefined to stop allocation \count registers at their limit value.

287 \def\ch@ck#1#2#3{
288 \ifnum \count1#1<#2 \else
289  \errmessage{No~room~for~a~new~#3}
290  \global\count1#1=#2
291 \fi

292 }

\open_pout \close_pout The syntax for \open_pout is

\open_pout⟨identifier⟩{⟨name⟩} ⟨name⟩ is the name of the output file one wishes to open. ⟨identifier⟩ is a control sequence which will be redefined (globally) to act as an identifier of the file.

293 \def\open_pout#1#2{
294 \allocate_stream
295 \ifnum \b_count=\m@ne
296  \immediate\write\sixt@@n{fontinst~is~out~of~output~streams.^^J
297  Output~file~#2~cannot~be~opened.^^J
298  Writes~will~be~redirected~to~the~log~file.

299 }

300  \gdef#1{\m@ne}
301 \else
302  \immediate\openout\b_count=#2\x_relax
303  \x_cs\xdef{out_filename-\the\b_count}{#2}
304  \global\chardef#1=\b_count
305 \fi

306 }

The syntax for \close_pout is

\close_pout⟨identifier⟩{⟨what⟩}

⟨identifier⟩ is the output stream identifier which should have been defined in an earlier call of \open_pout. ⟨what⟩ is a string which describes what has been written to the output file, e.g. Metrics or Raw~font. It will be used to write a message on the terminal.

307 \def\close_pout#1#2{
308 \ifnum #1=\closed_stream
309  \errmessage{Output~file~\string#1~(#2)~not~closed,^^J
310  since~it~was~not~open}
311 \else
312  \immediate\write\sixt@@n{#2~written~on~
313  \csname out_filename-\the#1\endcsname.}
314  \ifnum #1=\m@ne \else
315  \immediate\closeout#1
316  \global\x_cs\let{out_filename-\the#1}=\TeX_terminal
317  \fi
318  \global\chardef#1=\closed_stream
319 \fi

320 }

\pout_line The syntax for \pout_line is

\pout_line⟨identifier⟩{⟨text⟩}

⟨identifier⟩ is the output stream identifier which should have been defined in an earlier call to \open_pout. ⟨text⟩ is what will be written to the file.

321 \def\pout_line#1#2{\immediate\write#1{#2}}
\pout_lline \pout_llline There relate to \pout_line as \out_lline and \out_llline to \out_line.
322 \edef\pout_lline#1#2{\noexpand\pout_line#1{\space\space\space#2}}
323 \edef\pout_llline#1#2{
324 \noexpand\pout_line#1{\space\space\space\space\space\space#2}

325 }

\tempfileprefix \temp_prefix Selecting the directory for temporary files.

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

328 ⟨/pkg⟩

8.3 Conditionals

8.3.1 The needs of fontinst

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

329 ⟨pkg | doc⟩\let\then=\iffalse

330 ⟨∗pkg⟩

331 \def\if_false{\iffalse}
332 \def\if_true{\iftrue}

\gobble_if It is sometimes best to skip both the then-part and the else-part of a conditional. \gobble_if does this by temporarily making \else mean \relax, thus preventing the expansion of \iffalse from removing anything less than all tokens up to and including the matching \fi.

333 \def\gobble_if{
334 \begingroup
335  \let\else=\x_relax
336 \expandafter\endgroup
337 \iffalse

338 }

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

339 \def\if_or#1\or_else#2\then{
340 #1\then
341  \expandafter\if_true
342 \else
343  #2\then
344  \expandafter\expandafter\expandafter\if_true
345  \else
346  \expandafter\expandafter\expandafter\if_false
347  \fi
348 \fi

349 }

\if_file_exists  \if_file_exists checks to see if a file exits, using \openin.
350 \def\if_file_exists#1\then{
351 \immediate\openin1=#1\x_relax
352 \ifeof1\x_relax
353  \immediate\closein1
354  \expandafter\if_false
355 \else
356  \immediate\closein1
357  \expandafter\if_true
358 \fi

359 } 360 ⟨/pkg⟩

8.3.2 The needs of fontdoc

In order to get a reasonable documentation of branches in an ETX or MTX file, the code in both branches must be typeset and the positions of the if, the else, and the fi must be clearly marked. There seems to be no reasonable way to achieve this if the standard names for the else and fi are used. Therefore the alternative names \Else and \Fi for \else and \fi have been introduced, to be used as in for example

     \ifisint{monowidth}\then

⟨then-part⟩

     \Else

⟨else-part⟩

     \Fi

{\Else \atop \Fi} By default, these are identical to their lowercase counterparts.

361 ⟨∗pkg | doc⟩

362 \let\Else=\else
363 \let\Fi=\fi

364 ⟨/pkg | doc⟩

The interesting part begins if the ETX or MTX file gives the command \showbranches, since this means (i) that it wants the branches to be shown and (ii) that it complies to a simple rule about where to use \Else and \Fi. The rule is as follows: If an if statement is of fontinst form (it uses \then), then it must be terminated by \Fi, and a possible else in the statement must be an \Else. If an if statement is not of fontinst form (it has no \then), then it must be terminated by \fi, and a possible else in the statement must be an \else. Only the fontinst form if statements are affected by \showbranches.

\showbranches \generic@if The \showbranches command changes the definitions of \generic@if, \then,

\Else, and \Fi so that the branches of if statements will be made visible. \generic@if is used to implement all the fontinst form if statements in fontdoc. It is called as

     \generic@if{⟨description⟩}

and this will by default expand to \iftrue, but after executing \showbranches it will instead typeset

If ⟨description⟩ then

and do a bit of additional housekeeping.

365 ⟨∗doc⟩

366 \def\generic@if#1{\iftrue}
367 \newcommand\showbranches{%
368 \let\generic@if=\branches@if
369 \let\then=\x@relax
370 \let\Else=\branches@else
371 \let\Fi=\branches@fi

372 }

\saved@slot@number The \saved@slot@number is used for storing the value of \slot@number at the if

until the \Else. Unlike \slot@number, it is always set locally.

373 \newcount\saved@slot@number
\branches@if \branches@else \branches@fi \branches@type \branches@par The macros \branches@if, \branches@else, and \branches@fi contain the def-

initions of \generic@if, \Else, and \Fi respectively that are used when branches are to be shown. Their basic task is to typeset the texts If #1 then, Else, and Fi in an appropriate style and with appropriate spacing around. A complicating matter is however that \slot@number must have the same value at the beginning of the else part as at the beginning of the then part. To achieve this, the value of \slot@numer is saved in \saved@slot@number at the if and copied back at the else. To make this work even with nested if s, both the then branch and the else branch are enclosed in groups and \saved@slot@number is assigned locally.

There are still some formating issues to solve, however. In some cases it works best to put the text of adjacent if, else, or fi in the same paragraph, and it must be possible to recognize those cases. This is done by looking at the macro \branches@type, which should expand to

0 if the preceeding item was an if,

1 if the preceeding item was an else preceeded by an if,

2 if the preceeding item was an else not preceeded by an if,

3 if the preceeding item was a fi,

4 if it was anything else.

\branches@par is used for resetting \branches@type to 3. It is an auto-resetting definition of \par.

374 \def\branches@if#1{%
375 \ifnum \branches@type=\tw@
376  \textit{ if #1 then}%
377 \else
378  \par\addvspace\medskipamount
379  \noindent\textit{If #1 then}%
380 \fi
381 \saved@slot@number=\slot@number
382 \begingroup
383 \gdef\branches@type{0}%
384 \let\par=\branches@par

385 }

386 \def\branches@else{%
387 \endgroup
388 \ifnum \branches@type=\z@
389  \textit{ relax else}%
390  \gdef\branches@type{1}%
391 \else
392  \par\addvspace\medskipamount
393  \noindent\textit{Else}%
394  \gdef\branches@type{2}%
395 \fi
396 \global\slot@number=\saved@slot@number

397 \begingroup
398 \let\par=\branches@par

399 }

400 \def\branches@fi{%
401 \endgroup
402 \ifnum \branches@type=\thr@@
403  \textit{ fi}%
404 \else
405  \par\addvspace\medskipamount
406  \noindent\textit{Fi}%
407 \fi
408 \gdef\branches@type{3}%
409 \let\par=\branches@par

410 }

411 \gdef\branches@type{4}
412 \def\branches@par{%
413 \@restorepar\par\gdef\branches@type{4}%
414 \addvspace\medskipamount

415 } 416 ⟨/doc⟩

8.3.3 Miscellanea

\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\foo\primitiveinput, which doesn’t work with the L^{A}TEX version of \input.

417 ⟨∗pkg⟩

418 \x_cs\ifx{@@input}\x_relax
419 \let\primitiveinput=\input
420 \else
421 \let\primitiveinput=\@@input
422 \fi
\process_csep_list  The macro
      \process_csep_list{⟨pretext⟩}⟨comma-sep list⟩,\process_csep_list,

executes ⟨pretext⟩{⟨item⟩} for every item in the ⟨comma-sep list⟩.

\process_csep_list
423 \def\process_csep_list#1#2,{
424 \ifx\process_csep_list#2
425  \expandafter\gobble_one
426 \else
427  \expandafter\identity_one
428 \fi{
429  #1{#2}
430  \process_csep_list{#1}

431 } 432 } 433 ⟨/pkg⟩

\print@csep@list The macro call

     \print@csep@list{⟨format⟩}{⟨list⟩}

prints the comma-separated list ⟨list⟩ in math mode. ⟨format⟩ can be used to set the style in which the list is printed, since it is executed in the beginning of the same group as in which the list is printed.

The formating is based on changing the \mathcode of comma to "8000 so that the comma can be used as if it was an active character without actually having to be one.

434 ⟨∗doc⟩

435 \begingroup
436 \catcode`\,=13
437 \gdef\print@csep@list#1#2{%

438 $%

439  \ifnum "8000=\mathcode`\,\else
440  \mathchardef\private@comma=\mathcode`\,%
441  \mathcode`\,="8000\x@relax
442  \fi
443  #1%
444  \let,=\active@comma
445  #2%

446 $% 447 }

448 \endgroup
449 \def\active@comma{\private@comma \penalty\binoppenalty}

450 ⟨/doc⟩

8.4 Real numbers

TEX’s ⟨number⟩s are merely integers, but fontinst needs to store and calculate with numerical entities (most of which are lengths) that are intrinsically real numbers. Most of the time, fontinst does this by using a representation of real numbers by integers in which a real number x is represented by the integer that 1000x gets rounded to. This representation has proved sufficiently precise for most purposes.

There are however a few cases in which real numbers must be delt with in a more general fashion. Generic routines for this appear in this subsection.

\make_factor The \make_factor macro is meant to be used in the context

     \make_factor{⟨number⟩}

where ⟨number⟩ can be any legal TEX number. It expands to the same number divided by 1000, with decimals, so that what it expands to matches the regular expression

     -?[0-9]+\.[0-9][0-9][0-9]

More specifically, \make_factor has two tasks to perform: it takes care of the sign, so that its subsidary macros need only work with unsigned numbers, and it converts the ⟨number⟩ (which could well be a countdef or mathchardef token) to a sequence of digits.

451 ⟨∗pkg⟩

452 \def\make_factor#1{
453 \ifnum #1<\z@

454  -\expandafter\make_factor_i\expandafter{\number-#1}
455 \else
456  \expandafter\make_factor_i\expandafter{\number#1}
457 \fi

458 }

\make_factor_i \make_factor_i distinguishes between the two main cases of numbers that in absolute value are less than 1000 and numbers that in absolute value are greater than or equal to 1000. In the former case, zeros need to be inserted. In the latter case, some number of digits need to be stepped over before the decimal point can be inserted.

459 \def\make_factor_i#1{
460 \ifnum #1<\one_thousand
461  \make_factor_ii{#1}
462 \else
463  \make_factor_iii #1
464 \fi

465 #1 466 }

\make_factor_ii \make_factor_ii inserts extra zeros, in the extent it is needed.

467 \def\make_factor_ii#1{

468 0.

469 \ifnum #1<\one_hundred

470 0

471  \ifnum #1<10~ 0\fi
472 \fi

473 }

\make_factor_iii \make_factor_iii steps over one digit and checks if this is the correct position for the decimal point. Note that #2#3 is exactly the digits in the number that has not been stepped over. Also note that comparision with #2#3 would not work, since #2 can be 0.

474 \def\make_factor_iii#1#2#3\fi#4{
475 \fi

476 #4

477 \ifnum 1#3<\one_thousand

478 .

479 \else
480  \make_factor_iii#2#3
481 \fi

482 } 483 ⟨/pkg⟩

8.5 Error, warning, and info messages

The code in this subsection is an adaptation of code from the L^{A}TEX kernel—more precisely from the source file lterror.dtx—and the same is true for some of the comments. As authors of that code are listed Johannes Braams, David Carlisle, Alan Jeffrey, Leslie Lamport, Frank Mittelbach, Chris Rowley, and Rainer Schöpf. The original source can be found in the file lterror.dtx in the macros/latex/ base directory in any of the Comprehensive TEX Archive Network FTP sites.^{4}

4As if anyone didn’t already know that!

That should have fulfilled the conditions in the LPPL.

8.5.1 General commands

\messagebreak This command prints a new-line inside a message, followed by a continuation whose exact appearence may depend on the context. Normally this command is defined to be \relax, but inside messages it gets redefined to a linebreak (^^J) followed by the appropriate continuation.

484 ⟨pkg⟩\let\messagebreak\x_relax
485 ⟨doc⟩\let\messagebreak\space

\generic_info This takes two arguments: a continuation and a message, and sends the result to the log file.

486 ⟨∗pkg⟩

487 \def\generic_info#1#2{
488 \begingroup
489  \def\messagebreak{^^J#1}
490  \immediate\write\m@ne{#2\on_line.}
491 \endgroup

492 }

\generic_warning This takes two arguments: a continuation and a message, and sends the result to the screen.

493 \def\generic_warning#1#2{
494 \begingroup
495  \def\messagebreak{^^J#1}
496  \immediate\write\closed_stream{^^J#2\on_line.^^J}
497 \endgroup

498 }

\generic_error “This macro takes four arguments: a continuation, an error message, where to go for further information, and the help information. It displays the error message, and sets the error help (the result of typing h to the prompt), and does a horrible hack to turn the last context line (which by default is the only context line) into just three dots. This could be made more efficient.”

Thus far the L^{A}TEX comments, but the horrible hack it mensions has been removed since it just makes things look strange when \errorcontextlines is larger than one. The “where to go for further information” message is currently not used (it is commented out in \fontinsterror below), since there is no good place to refer to anyway. If the documentation is ever improved in this respect, it would of course be best to reinsert this message. Note however that unlike the case in L^{A}TEX, this message should end with a ^^J.

A complication is that TEX versions older than 3.141 have a bug which causes ^^J to not force a linebreak in \message and \errmessage commands. So for these old TEX’s we use a \write to produce the message, and then have an empty \errmessage command. This causes an extra line of the form

! .

to appear on the terminal, but if you do not like it, you can always upgrade your TEX!

Since I don’t think many fontinst users use such old TEXs, I removed L^{A}TEX’s test for TEX version at this point. The code for old TEXs is still there, but it lies in a docstrip module of its own.

First the ‘standard case’.

499 ⟨∗!oldTeX⟩

500 \def\generic_error#1#2#3#4{
501 \begingroup
502  \immediate\write\closed_stream{}
503  \def\messagebreak{^^J}
504  \edef\a_macro{{#4}}
505  \errhelp\a_macro
506  \def\messagebreak{^^J#1}
507  \errmessage{#2.^^J^^J#3
508  Type~\space H~<return>~\space for~immediate~help

509 }

510 \endgroup

511 } 512 ⟨/!oldTeX⟩

Secondly the version for old TEX’s.

513 ⟨∗oldTeX⟩

514 \def\generic_error#1#2#3#4{%
515 \begingroup
516  \immediate\write\closed_stream{}
517  \def\messagebreak{^^J}
518  \edef\a_macro{{#4}}
519  \errhelp\a_macro
520  \def\messagebreak{^^J#1}
521  \immediate\write\closed_stream{!~#2.^^J^^J#3^^J
522  Type~\space H~<return>~\space for~immediate~help.

523 }

524  \errmessage{}
525 \endgroup

526 } 527 ⟨/oldTeX⟩

\fontinsterror \fontinstwarning \fontinstwarningnoline \fontinstinfo These commands are intended for giving a uniformed, and for the programmers

hopefully simplified, form of error, warning, and info messages. The syntax is:

\fontinsterror{⟨subsystem⟩}{⟨error⟩}{⟨help⟩}

     \fontinstwarning{⟨subsystem⟩}{⟨warning⟩}
     \fontinstwarningnoline{⟨subsystem⟩}{⟨warning⟩}
     \fontinstinfo{⟨subsystem⟩}{⟨info⟩}

A ⟨subsystem⟩ in this context is intended to be some piece of text which identifies some functionally clearly defined part of fontinst. Examples of ⟨subsystem⟩s could

be PL to MTX converter, Ligful (V)PL writer, and Latin family.

The \fontinsterror command prints the ⟨error⟩ message, and presents the interactive prompt; if the user types h, then the ⟨help⟩ information is displayed. The \fontinstwarning command produces a warning but does not present the interactive prompt. The \fontinstwarningnoline command does the same, but doesn’t print the input line number. The \fontinstinfo command writes the message to the log file. Within the messages, the command \messagebreak can be used to break a line and \space is a space, for example:

     \def\foo{FOO}
     \fontinstwarning{Hungarian}{
        Your~hovercraft~is~full~of~eels,\messagebreak
        and~\string\foo\space is~\foo}

produces:

     Hungarian warning:
             Your hovercraft is full of eels,
             and \foo is FOO on input line 54.

528 \def\fontinsterror#1#2#3{
529 \generic_error{
530  \four_spaces\four_spaces

531 }{

532  #1~error:\messagebreak #2

533 }{

534 %       See~the~#1~package~documentation~for~explanation.^^J
535 }{#3}

536 }

537 \def\fontinstwarning#1#2{
538 \generic_warning{
539  \four_spaces\four_spaces

540 }{

541  #1~warning:\messagebreak #2

542 } 543 }

544 \def\fontinstwarningnoline#1#2{
545 \fontinstwarning{#1}{#2\gobble_one}

546 }

547 \def\fontinstinfo#1#2{
548 \generic_info{
549  \four_spaces\four_spaces

550 }{

551  #1~info:\messagebreak #2

552 } 553 } 554 ⟨/pkg⟩

555 ⟨∗doc⟩

556 \def\fontinsterror#1#2#3{%
557 \Bheading{Error} observed by #1:%
558 \begin{quote}#2.\end{quote}%

559 }

560 \def\fontinstwarning#1#2{
561 \Bheading{Warning} from #1:%
562 \begin{quote}#2.\end{quote}%

563 }

564 \let\fontinstwarningnoline=\fontinstwarning
565 \def\fontinstinfo#1#2{
566 \Bheading{Info} from #1:%

567 \begin{quote}#2.\end{quote}%

568 } 569 ⟨/doc⟩

\on_line The message ‘ on input line n’. L^{A}TEX has special code for TEX 2, but since fontinst has assumed the existence of the \errorcontextlines parameter since v 1.500, the removal of that code shouldn’t cause problems for anyone who wasn’t already having related problems.

570 ⟨∗pkg⟩

571 \def\on_line{~on~input~line~\the\inputlineno}

\four_spaces Four spaces. Using \edef (rather than \def as in L^{A}TEX) to save some macro expansions.

572 \edef\four_spaces{\space\space\space\space}

8.5.2 Specific errors

\error_help_a \error_help_c \error_help_d The more common error help messages. They are called \@eha, \@ehc, and \@ehd

in L^{A}TEX. \@ehb is of no use for fontinst, so it has been omitted.

573 \gdef\error_help_a{
574 Your~command~was~ignored.\messagebreak
575 Type~\space I~<command>~<return>~\space to~replace~it~
576 with~another~command,\messagebreak
577 or~\space <return>~\space to~continue~without~it.}
578 \gdef\error_help_c{
579 Try~typing~\space <return>~
580 \space to~proceed.\messagebreak
581 If~that~doesn't~work,~type~\space X~<return>~\space to~quit.}
582 \gdef\error_help_d{
583 You're~in~trouble~here.~\space\error_help_c}

584 ⟨/pkg⟩

File b

fimain.dtx

9 General commands

9.1 Setting variables

⟨int⟩, ⟨str⟩, and ⟨dim⟩ below can be any strings. ⟨command⟩ can be any control sequence.

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

\strint The macro

\strint{⟨int⟩}

returns the value of \i-⟨int⟩ as a string.

\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⟩, \d-⟨dim⟩, or ⟨command⟩ 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⟩.

\x_setint  The macros \x_setint, \x_resetint, and \x_setstr are “private” versions
\x_resetint
\x_setstr

of \setint, \resetint, and \setstr respectively. They have been included to reduce the problems in case a user turns off one of these commands and forgets to turn it on again.

Integers are kept as \mathchardefs if possible; a comparision of doing this versus not doing this appears in Subsection E.1.

\x_setint
\setint
\x_setstr
\setstr
\setdim
\setcommand

1 ⟨∗pkg | misc⟩

 2 \def\x_setint#1#2{
 3 \x_cs\ifx{i-#1}\x_relax
 4  \x_resetint{#1}{#2}
 5 \fi
 6 }
 7 \let\setint=\x_setint
 8 \def\x_setstr#1#2{\x_cs\ifx{s-#1}\x_relax
 9 \x_cs\edef{s-#1}{#2}\fi}
10 \let\setstr=\x_setstr
11 \def\setdim#1#2{\x_cs\ifx{d-#1}\x_relax
12 \a_dimen=#2\x_relax\x_cs\edef{d-#1}{\the\a_dimen}\fi}
13 \def\setcommand#1{\ifx#1\undefined_command
14 \expandafter\def\expandafter#1\else
15 \expandafter\def\expandafter\a_command\fi}

16 ⟨/pkg | misc⟩

In fontdoc, \setint, \setstr, and \setdim print headings. There is no need for the private forms \x_setint and \x_setstr. \setcommand, finally, does the same thing as in fontinst.

17 ⟨∗doc⟩

18 \def\setint#1#2{\Bheading{Default} #1 = $\expression0{#2}$}
19 \def\setstr#1#2{\Bheading{Default} #1 = #2}
20 \def\setdim#1#2{\a@dimen=#2\relax\Bheading{Default} #1 = \the\a@dimen}
21 \def\setcommand#1{\ifx#1\undefined@command
22 \expandafter\gdef\expandafter#1\else
23 \expandafter\gdef\expandafter\a@command\fi}

24 ⟨/doc⟩

\x_resetint
\resetint
\resetstr
\resetdim
\resetcommand

25 ⟨∗pkg | misc⟩

26 \def\x_resetint#1#2{
27 \eval_expr{#2}
28 \ifnum\result<\max_mathchardef
29  \ifnum 0>\result
30  \x_cs\edef{i-#1}{\the\result}
31  \else
32  \x_cs\mathchardef{i-#1}=\result
33  \fi
34 \else
35  \x_cs\edef{i-#1}{\the\result}
36 \fi

37 }

38 \let\resetint=\x_resetint
39 \def\resetstr#1#2{\x_cs\edef{s-#1}{#2}}

40 \def\resetdim#1#2{\a_dimen=#2\x_cs\edef{d-#1}{\the\a_dimen}}
41 \def\resetcommand#1{\def#1}

42 ⟨/pkg | misc⟩

In fontdoc, \resetint, \resetstr, and \resetdim print headings. There is no need for the private form \x_resetint. \resetcommand, finally, does the same thing as in fontinst.

43 ⟨∗doc⟩

44 \def\resetint#1#2{\Bheading{Value} #1 = $\expression0{#2}$}
45 \def\resetstr#1#2{\Bheading{Value} #1 = #2}
46 \def\resetdim#1#2{\a@dimen=#2\relax\Bheading{Value} #1 = \the\a@dimen}
47 \def\resetcommand#1{\gdef#1}

48 ⟨/doc⟩

\int \str \dim \strint

49 ⟨∗pkg | misc⟩

50 \def\int#1{\csname~i-#1\endcsname}
51 \def\str#1{\csname~s-#1\endcsname}
52 \def\dim#1{\csname~d-#1\endcsname}
53 \def\strint#1{\expandafter\identity_one\expandafter{\number\int{#1}}}

54 ⟨/pkg | misc⟩

Not in doc: \str
Not in doc: \dim
Not in doc: \strint

55 ⟨∗doc⟩

56 \def\int#1{\typeset@integer{#1}}

\typeset@integer \typeset@string \typeset@dimen These macros take the name of an integer/string/dimen as argument and typesets that name with the correct formating. They should work equally well in horizontal, math, and vertical mode.

57 \def\typeset@integer#1{\x@relax \ifmmode {\fam0 #1}\else $\fam0 #1$\fi}
58 \def\typeset@string#1{\x@relax
59 \ifmmode \hbox{\normalfont#1}\else \textnormal{#1}\fi

60 }

61 \let\typeset@dimen=\typeset@string

62 ⟨/doc⟩

\ifisint
\ifisstr
\ifisdim
\ifiscommand

63 ⟨∗pkg | misc⟩

64 \def\ifisint#1\then{\x_cs\ifx{i-#1}\x_relax\expandafter\if_false
65 \else\expandafter\if_true\fi}
66 \def\ifisstr#1\then{\x_cs\ifx{s-#1}\x_relax\expandafter\if_false
67 \else\expandafter\if_true\fi}
68 \def\ifisdim#1\then{\x_cs\ifx{d-#1}\x_relax\expandafter\if_false
69 \else\expandafter\if_true\fi}
70 \def\ifiscommand#1\then{\ifx#1\undefined_command\expandafter\if_false
71 \else\expandafter\if_true\fi}

72 ⟨/pkg | misc⟩

In fontdoc, all conditionals are handled through \generic@if, which by default expands to \iftrue.

73 ⟨∗doc⟩

74 \def\ifisint#1\then{\generic@if{integer \typeset@integer{#1} set}}
75 \def\ifisstr#1\then{\generic@if{string \typeset@string{#1} set}}
76 \def\ifisdim#1\then{\generic@if{dimension \typeset@dimen{#1} set}}
77 \def\ifiscommand#1\then{%

78 \generic@if{command \normalfont{\ttfamily\string#1} set}%

79 } 80 ⟨/doc⟩

\unsetint
\unsetstr
\unsetdim
\unsetcommand

81 ⟨∗pkg | misc⟩

82 \def\unsetint#1{\x_cs\let{i-#1}\x_relax}
83 \def\unsetstr#1{\x_cs\let{s-#1}\x_relax}
84 \def\unsetdim#1{\x_cs\let{d-#1}\x_relax}
85 \def\unsetcommand#1{\let#1=\undefined_command}

86 ⟨/pkg | misc⟩

Not in doc: \unsetint
Not in doc: \unsetstr
Not in doc: \unsetdim
Not in doc: \unsetcommand

87 ⟨∗doc⟩ 88 ⟨/doc⟩

\offcommand \oncommand LH 1999/02: The calls
     \offcommand⟨command⟩
     \oncommand⟨command⟩

can be used to turn a command off (make it simply absorb its arguments but expand to nothing) or on (return it to normal) respectively. Their primary use is for ignoring some of the commands in .mtx files that fontinst generates from .afm, .pl, or other .mtx files.

\saved-COMMAND The normal definition of a command that have been turned off is saved as the control sequence \saved-⟨command⟩. If the syntax of a command is tricky—not all arguments are read by the base command or its parameter text contains tokens that are not parameters—or if simply making it do nothing is not the expected ‘off’ behaviour, then the automatic off-turning may not work. In such cases a handtooled off definition of the command ⟨command⟩ may be provided as the

\off-COMMAND control sequence \off-⟨command⟩.

Nothing happens if \offcommand is called for a command that is not on. Nothing happens if \oncommand is called for a command that is not off.

89 ⟨∗pkg | misc⟩

90 \def\offcommand#1{
91 \x_cs\ifx{saved-\string#1}\x_relax
92  \x_cs\let{saved-\string#1}#1
93  \x_cs\ifx{off-\string#1}\x_relax
94  \generate_off_command{#1}
95  \else
96  \expandafter\let \expandafter#1
97  \csname off-\string#1\endcsname
98  \fi
99 \fi

100 }

101 \def\oncommand#1{
102 \x_cs\ifx{saved-\string#1}\x_relax \else
103  \expandafter\let \expandafter#1
104  \csname saved-\string#1\endcsname
105  \x_cs\let{saved-\string#1}\x_relax
106 \fi

107 }

\generate_off_command \count_hashes \gobble_to_xrelax  \generate_off_command⟨command⟩ converts ⟨command⟩ to an “off” version of

itself by counting the number of arguments and defining it to gobble that many arguments. It cannot cope with commands whose parameter texts are not simply of the type

     #1#2. . . #n

108 \def\generate_off_command#1{
109 \a_count=0
110 \let\next=\count_hashes
111 \expandafter\next\meaning#1~->\x_relax
112 \b_count=0
113 \a_toks={}
114 \loop \ifnum \b_count<\a_count
115  \advance \b_count 1
116  \a_toks=\expandafter{\the\expandafter\a_toks \expandafter####
117  \the\b_count}
118 \repeat
119 \expandafter\def \expandafter#1 \the\a_toks {}

120 }

121 \def\count_hashes#1#2{
122 \if \hash_char#1
123  \advance \a_count 1
124 \else
125  \if -#1
126  \if >#2
127  \let\next=\gobble_to_xrelax
128  \fi\fi
129 \fi
130 \next#2

131 }

132 \def\gobble_to_xrelax#1\x_relax{}

133 ⟨/pkg | misc⟩

Not in doc: \offcommand
Not in doc: \oncommand

134 ⟨∗doc⟩ 135 ⟨/doc⟩

9.2 For loops

\for \endfor LH 1999/02: The command sequence

\for(⟨name⟩){⟨start⟩}{⟨stop⟩}{⟨step⟩}

⟨body code⟩

     \endfor(⟨name⟩)

will cause the ⟨body code⟩ to be repeated some number of times. How many depends on the values of ⟨start⟩, ⟨stop⟩, and ⟨step⟩, which are integer expressions.

As a precaution, the ⟨body code⟩ is not allowed to contain any empty lines (\par tokens). If you want to have the visual separation (for sakes of legibility or otherwise), put a % somewhere on the line—that makes it nonempty.

⟨name⟩ is used as the name of an integer variable. This variable gets reset to the value of ⟨start⟩ before the first repetition of ⟨body code⟩. After each repetition but the last, it is incremented by ⟨step⟩. ⟨body code⟩ gets repeated if the value of ⟨name⟩ has not gotten past that of ⟨stop⟩. To get past means to be bigger if ⟨step⟩ is positive and to be smaller if ⟨step⟩ is negative. In the case that ⟨step⟩ is zero, the entire construction above will be equivalent to

     \resetint{⟨name⟩}{⟨start⟩}

⟨body code⟩

\for … \endfor constructions can be nested. ⟨name⟩ is used by \for to identify its matching \endfor, so they need to be identical in \for and \endfor.

136 ⟨∗pkg | misc⟩

137 \def\for(#1)#2#3#4{
138 \eval_expr_to\a_count{#2}
139 \x_resetint{#1}{\a_count}
140 \eval_expr{#4}
141 \ifnum 0=\result \else
142  \c_count=\result
143  \eval_expr_to\b_count{#3}
144  \x_cs\edef{for-#1}{
145  \the\c_count \x_relax
146  \noexpand\ifnum \gobble_one\fi
147  \the\b_count \ifnum 0>\c_count > \else < \fi

148 }

149  \def\next##1##2##3\endfor(#1){##2\for_i{##1}{##3}}
150  \next{#1}
151 \fi

152 }

\for-NAME The macro \for-⟨name⟩ will contain

⟨step⟩\x_relax\ifnum⟨stop⟩⟨rel⟩

⟨step⟩ is the value of the ⟨step⟩ parameter of \for, computed when the loop was entered and now expressed in digits. ⟨stop⟩ is likewise for the ⟨stop⟩ parameter. ⟨rel⟩ is > or <, depending on whether ⟨step⟩ is positive or negative respectively. The reason for this curious definition will be appearent in the light of the definition

of \for_ii.

\for_i is expanded in the context

\for_i{⟨name⟩}{⟨body code⟩}

Also remember, when reading the definition below, that \ifnum keeps on expanding tokens until it has found a

⟨number⟩⟨relation⟩⟨number⟩

structure. It is therefore possible to nest \ifnums like this!

153 \def\for_i#1#2{
154 \x_cs\def{body-#1}{#2}
155 \ifnum \b_count \ifnum0>\c_count >\else<\fi \a_count
156  \expandafter\gobble_two
157 \else
158  \csname body-#1 \expandafter\endcsname
159 \fi
160 \for_ii{#1}

161 }

\body-NAME The macro \body-⟨name⟩ expands to the ⟨body code⟩. \for_ii executes the following code:

     \a_count=\int{⟨name⟩}
     \advance \a_count ⟨step⟩\x_relax
     \ifnum ⟨stop⟩⟨rel⟩\a_count
        \expandafter\gobble_two
     \else
        \resetint{⟨name⟩}\a_count
        \csname body-⟨name⟩ \expandafter\endcsname
     \fi
     \for_ii{⟨name⟩}

⟨step⟩, ⟨stop⟩, and ⟨rel⟩ are in \for-⟨name⟩, and since there only are two other tokens between ⟨step⟩ and ⟨rel⟩ in the above, one might as well include them in \for-⟨name⟩ as well. Doing that requires that a matching hole—that will be filled in by \for-⟨name⟩—is made in the definition of \for_ii and that is the reason for its somewhat curious definition.

162 \def\for_ii#1{
163 \a_count=\int{#1}
164 \advance \a_count \csname for-#1\endcsname \a_count
165  \expandafter\gobble_two
166 \else
167  \x_resetint{#1}\a_count
168  \csname body-#1 \expandafter\endcsname
169 \fi
170 \for_ii{#1}

171 }

\endfor just gobbles its argument, so that the ⟨step⟩ = 0 case will work right.

172 \def\endfor(#1){}

173 ⟨/pkg | misc⟩

Not in doc: \for
Not in doc: \endfor

174 ⟨∗doc⟩ 175 ⟨/doc⟩

\foreach \foreach_i The command sequence

\foreach(⟨name⟩){⟨csep-list⟩}

⟨body code⟩

     \endfor(⟨name⟩)

will cause the ⟨body code⟩ to be repeated one time for each item in the ⟨csep-list⟩. ⟨csep-list⟩ is a comma-separated list of strings.

As a precaution, the ⟨body code⟩ is not allowed to contain any empty lines (\par tokens). If you want to have the visual separation (for sakes of legibility or otherwise), put a % somewhere on the line—that makes it nonempty.

⟨name⟩ is used as the name of a string variable. Before each repetition of the ⟨body code⟩, this variable will get reset to the next item in the ⟨csep-list⟩.

\for… \endfor constructions can be nested. ⟨name⟩ is used by \foreach to identify its matching \endfor, so they need to be identical in \foreach and

Not in doc: \foreach  \endfor.

176 ⟨∗pkg | misc⟩

177 \def\foreach(#1)#2{
178 \def\next##1\endfor(#1){
179  \x_cs\def{body-#1}{##1}
180  \process_csep_list{\foreach_i{#1}}#2,\process_csep_list,

181 }

182 \next

183 }

184 \def\foreach_i#1#2{
185 \resetstr{#1}{#2}
186 \csname body-#1\endcsname

187 } 188 ⟨/pkg | misc⟩

9.3 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{⟨integer variable⟩}{⟨integer expression⟩}

locally assigns the value of ⟨integer expression⟩ to ⟨integer variable⟩ (which is an integer variable as defined in [1]). \g_eval_expr_to does the same globally.

189 ⟨∗pkg | misc⟩

190 \newcount\result
191 \def\eval_expr#1{\global\result=#1\x_relax}
192 \def\eval_expr_to#1#2{\eval_expr{#2}#1=\result}
193 \def\g_eval_expr_to#1#2{\eval_expr{#2}\global#1=\result}
\rounded_thousandths LH 1999/03/06: The \rounded_thousandths macro divides \result by 1000 and

rounds the result to the nearest integer. This is different from

     \global\divide \result \one_thousand

since the latter always rounds positive numbers downwards and negative numbers upwards.

194 \def\rounded_thousandths{
195 \global\divide \result \five_hundred
196 \ifodd \result
197  \global\advance \result by \ifnum 0>\result - \fi 1
198 \fi
199 \global\divide \result \tw@

200 }

\neg \add \sub \mul \div \max \min 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⟩}

201 \def\neg#1{#1\global\result=-\result}
202 \def\add#1#2{#1{\a_count=\result\eval_expr{#2}
203 \global\advance\result by \a_count}}
204 \def\sub#1#2{#1{\a_count=\result\eval_expr{#2}
205 \advance\a_count by -\result
206 \global\result=\a_count}}
207 \def\mul#1#2{#1{\a_count=\result\eval_expr{#2}
208 \global\multiply\result by \a_count}}
209 \def\div#1#2{#1{\a_count=\result\eval_expr{#2}
210 \divide\a_count by \result
211 \global\result=\a_count}}
212 \def\max#1#2{#1{\a_count=\result\eval_expr{#2}
213 \ifnum\a_count>\result \global\result=\a_count \fi}}
214 \def\min#1#2{#1{\a_count=\result\eval_expr{#2}
215 \ifnum\a_count<\result \global\result=\a_count \fi}}

216 ⟨/pkg | misc⟩

217 ⟨∗doc⟩

218 \def\neg#1{\priority8{-\expression6{#1}}}
219 \def\add#1#2{\priority2{\expression2{#1}+\expression2{#2}}}
220 \def\sub#1#2{\priority2{\expression2{#1}-\expression3{#2}}}
221 \def\mul#1#2{\priority4{\expression4{#1}\times\expression4{#2}}}
222 \def\div#1#2{\priority4{\expression4{#1}/\expression5{#2}}}
223 \def\max#1#2{\priority6{\expression6{#1}\sqcup\expression6{#2}}}
224 \def\min#1#2{\priority7{\expression7{#1}\sqcap\expression7{#2}}}

225 ⟨/doc⟩

\scale \grabchars@ \grabchars@i \grabchars@ii \grabchars@iii \scale-500X The \scale macro performs the operation of multiplying the operands and divid-

ing that result by one thousand.

226 ⟨∗pkg | misc⟩

227 \def\scale#1#2{#1{\a_count=\result\eval_expr{#2}
228 \global\multiply\result by \a_count
229 \rounded_thousandths}}

230 ⟨/pkg | misc⟩

\scale is often used with a fixed scaling factor, such as for example 500, as the second argument. In those cases it often makes more sense to typeset the expression as for example a fraction times the first argument than to typeset it as \div{\mul{#1}{#2}}{1000} would. Such special cases can be specified by defin-

\scale-FACTOR ing a control sequence \scale-⟨factor⟩, where ⟨factor⟩ is the first four characters of the #2 integer expression (all control sequences are \stringed), with Xs added at the end if the expression is shorter than four characters.

For the moment, the only scaling factor with such a special definition is 500. This scaling factor gets typeset as \frac{1}{2}.

231 ⟨∗doc⟩

232 \def\scale#1#2{%
233 \x@cs\ifx{scale-\grabchars@#2XXXX\@nil}\x@relax
234  \div{\mul{#1}{#2}}{1000}%

235 \else
236  \csname scale-\grabchars@#2XXXX\@nil\endcsname{#1}{#2}%
237 \fi

238 }

239 \def\grabchars@{\expandafter\grabchars@i\string}
240 \def\grabchars@i#1{#1\expandafter\grabchars@ii\string}
241 \def\grabchars@ii#1{#1\expandafter\grabchars@iii\string}
242 \def\grabchars@iii#1{#1\expandafter\@car\string}
243 \x@cs\def{scale-500X}#1#2{\priority4{\frac{1}{2}\expression4{#1}}}

244 ⟨/doc⟩

\expression \priority \identity \bracket fontdoc uses \expression and \priority for typsetting nested arithmetic expres-

sions. \expression is called as

\expression{⟨priority⟩}{⟨expression⟩}

where ⟨priority⟩ is the minimum priority the outermost operation in ⟨expression⟩ must have if ⟨expression⟩ is to be read correctly without bracketing. \priority is called as

\priority{⟨priority⟩}{⟨expression⟩}

where ⟨priority⟩ is the priority the outermost operation in ⟨expression⟩. Its object is to bracket ⟨expression⟩ if that is necessary.

245 ⟨∗doc⟩

246 \def\expression#1#2{\a@count=#1\relax#2}
247 \def\priority#1#2{%
248 \ifnum #1<\a@count
249  \let\next=\bracket
250 \else
251  \let\next=\identity
252 \fi
253 \next{#2}}
254 \def\identity#1{#1}
255 \def\bracket#1{(#1)}

256 ⟨/doc⟩

\ifnumber LH 1999/02: The call

\ifnumber{⟨integer expression⟩}⟨rel⟩{⟨integer expression⟩}\then

can be used to compare the two integer expressions. ⟨rel⟩ may be <, =, or >.

257 ⟨∗pkg | misc⟩

258 \def\ifnumber#1#2#3\then{
259 \eval_expr_to\a_count{#1}
260 \eval_expr{#3}
261 \ifnum \a_count#2\result
262  \expandafter\if_true
263 \else
264  \expandafter\if_false
265 \fi

266 } 267 ⟨/pkg | misc⟩

Like the other conditionals, \ifnumber is treated as being true by fontdoc.

268 ⟨∗doc⟩

269 \def\ifnumber#1#2#3\then{%
270 \generic@if{$ \expression0{#1} #2 \expression0{#3} $}%

271 } 272 ⟨/doc⟩

9.4 Comments

\comment In fontinst, \comment simply gobbles its argument.

273 ⟨∗pkg⟩

274 \let\comment=\gobble_one

275 ⟨/pkg⟩

In fontdoc, \comment starts a new text paragraph and leaves the argument to be typeset.

276 ⟨∗doc⟩

277 \def\comment{\par\noindent}

278 ⟨/doc⟩

\begincomment \endcomment LH 1999/02: Since \comment cannot be used for a comment longer than one paragraph, we also provide the means of introducing longer comments, by writing

     \begincomment ⟨any amount of text⟩ \endcomment

The names are admittedly not nice from a L^{A}TEX point of view, but it is hardly worth the cost to implement some kind of environment processing in fontinst, just for the sake of this command.

279 ⟨pkg⟩\let\begincomment=\iffalse
280 ⟨doc⟩\let\begincomment=\iftrue
281 ⟨pkg | doc⟩\let\endcomment=\fi

10 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
\encoding
\endencoding

282 ⟨∗pkg⟩

283 \def\inputetx#1{
284 \edef\lowercase_file{\lowercase{
285  \edef\noexpand\lowercase_file{#1}}}
286 \lowercase_file
287 \slot_number=0
288 \def\relax{\let\relax=\x_relax\iffalse}
289 \let\encoding=\fi
290 \primitiveinput \lowercase_file.etx\x_relax
291 \let\relax=\x_relax

293 \let\encoding=\relax
294 \outer\def\endencoding{\endinput}

295 ⟨/pkg⟩

Things are a bit more complicated in fontdoc, since the \relax … \encoding … \endencoding markup must be able to work in two different ways. In the main file only \encoding actually does anything—it sets \slot@number to zero. In a file that is being \inputetxed, they must work as with fontinst: Everything between \relax and \encoding, and everything after \endencoding must be ignored.

296 ⟨∗doc⟩

297 \def\inputetx#1{%
298 \begingroup
299  \edef\lowercase@file{\lowercase{%
300  \edef\noexpand\lowercase@file{#1}%
301  }}%
302  \lowercase@file
303  \global\slot@number=0%
304  \def\relax{\let\relax=\x@relax\iffalse}%
305  \let\encoding=\fi
306  \outer \expandafter\def \csname endencoding\endcsname
307  {\endinput}%
308  \expandafter\input \lowercase@file.etx\x@relax
309  \let\relax=\x@relax
310 \endgroup

311 }

312 \def\encoding{\begingroup\global\slot@number=0}
313 \outer\def\endencoding{\endgroup}

314 ⟨/doc⟩

\setslot \endsetslot \slot_name \slot@name  \setslot{⟨name⟩} ⟨slot commands⟩ \endsetslot

In fontinst, this sets \slot_name to ⟨name⟩ and calls \do_slot at the beginning of the slot and it calls \end_do_slot and increments \slot_number by one at the end. By default, \do_slot and \end_do_slot do nothing, but this is over-ridden later.

315 ⟨∗pkg⟩

316 \def\setslot#1{\edef\slot_name{#1}\do_slot}
317 \def\endsetslot{\end_do_slot\advance\slot_number by 1\x_relax}

318 ⟨/pkg⟩

In fontdoc, the same code sets \slot@name to ⟨name⟩, prints an \Aheading heading for the slot which show the name and number of the slot, and prints the current automatic slot comment (if one has been set) at the beginning of the slot. At the end of the slot, it simply increments \slot@number by one.

319 ⟨∗doc⟩

320 \def\setslot#1{\def\slot@name{#1}%
321 \Aheading{Slot \the\slot@number\space `#1'}%
322 \ifslot@comment@ \comment{\slot@comment}\fi}
323 \def\endsetslot{\global\advance\slot@number by 1\relax}

324 ⟨/doc⟩

\do_slot
\end_do_slot

325 ⟨∗pkg⟩

326 \let\do_slot\empty_command
327 \let\do_new_slot\empty_command
328 \let\end_do_slot\empty_command
\nextslot \skipslots \slot_number \slot@number  \nextslot{⟨integer expression⟩}

\skipslots{⟨integer expression⟩}

In fontinst, \nextslot sets the \slot_number and \skipslots addvances the

\slot_number.
329 \newcount\slot_number
330 \def\nextslot#1{\eval_expr_to\slot_number{#1}}
331 \def\skipslots#1{\eval_expr{#1} \advance\slot_number by \result}

332 ⟨/pkg⟩

The commands do the same in fontdoc as in fontinst, although they do it to

\slot@number instead of \slot_number.

333 ⟨∗doc⟩

334 \newcount\slot@number
335 \def\nextslot#1{\global\slot@number=#1\relax}
336 \def\skipslots#1{\global\advance\slot@number by #1\relax}

337 ⟨/doc⟩

A What should the arguments to \nextslot and \skipslots be? At least since v 1.335 the comments in the source has said it was an integer expression, but the implementation was for a TEX number. Alan’s v 1.5 manual and Rowland’s v 1.8 manual both say the arguments must be numbers. Allowing arbitrary integer expressions with fontinst is trivial, the above implementation copes with that, but fontdoc gets in trouble, so what should we do about it? /LH

AFAIK, all instances of \nextslot or \skipslots appearing in present *.etx files are explicit numbers, no fancy constructs. /UV

\setleftboundary \endsetleftboundary \do_boundary  \setleftboundary{⟨glyph⟩} ⟨slot commands⟩ \endsetleftboundary

These macros are like \setslot and \endsetslot, but they merely set the left boundary ligkern program, they do not cause any CHARACTER property list to be written. Thus the only metric information connected to the ⟨glyph⟩ argument that is ever used is the kerns with this glyph on the left.

   \do_boundary and \endsetleftboundary are initally \relax, but are later

redefined.

338 ⟨∗pkg⟩

339 \def\setleftboundary#1{\edef\slot_name{#1}\do_boundary}
340 \let\endsetleftboundary\x_relax
341 \let\do_boundary\x_relax

342 ⟨/pkg⟩ 343 ⟨∗doc⟩

344 \def\setleftboundary#1{\def\slot@name{#1}%
345 \Aheading{Left boundary `#1'}%

346 }

347 \let\endsetleftboundary=\x@relax

348 ⟨/doc⟩

\setrightboundary  \setrightboundary{⟨glyph⟩}

The \setrightboundary macro should be used to set which slot in the font is used as right boundary marker if that slot is empty. It advances \slot_number just like a \setslot … \endsetslot pair, but since the slot will be left empty, there is no need for any ⟨slot commands⟩, and hence there is no need for a closing \endset… command either.

If the right boundary marker slot is not to be left empty (often unavoidable), then one should use the slot command \makerightboundary instead.

349 ⟨∗pkg⟩

350 \def\setrightboundary#1{
351 \makerightboundary{#1}
352 \advance \slot_number 1\x_relax

353 } 354 ⟨/pkg⟩ 355 ⟨∗doc⟩

356 \def\setrightboundary#1{%
357 \Aheading{Right boundary slot \the\slot@number\space `#1'}%
358 \global\advance\slot@number by 1\relax

359 } 360 ⟨/doc⟩

\ligature The ⟨slot commands⟩ are:

\nextlarger
\varchar
\endvarchar
\usedas
\makerightboundary

\ligature{⟨lig⟩}{⟨glyph⟩}{⟨glyph⟩}

      \nextlarger{⟨glyph⟩}
      \varchar ⟨varchar commands⟩ \endvarchar

\usedas{⟨command⟩}{⟨type⟩}

      \makerightboundary{⟨glyph⟩}

By default, these do nothing in fontinst, but those defaults are overridden later.^{5} In fontdoc, they generate descriptive headings.

\ligature
361 ⟨pkg⟩\let\ligature=\gobble_three

362 ⟨∗doc⟩

363 \def\ligature#1{\Bheading{Ligature} \csname doc-#1\endcsname}

Symbolic typesetting of \ligature programs requires special processing.

364 \x@cs\def{doc-LIG}#1#2{%
365 $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
366 \typeset@glyph{#2}$}
367 \x@cs\def{doc-/LIG}#1#2{%
368 $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
369 \typeset@glyph{\slot@name} * \typeset@glyph{#2}$}
370 \x@cs\def{doc-LIG/}#1#2{%
371 $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
372 \typeset@glyph{#2} * \typeset@glyph{#1}$}
373 \x@cs\def{doc-/LIG/}#1#2{%
374 $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
375 \typeset@glyph{\slot@name} * \typeset@glyph{#2} * \typeset@glyph{#1}$}
376 \x@cs\def{doc-/LIG>}#1#2{%
377 $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
378 \typeset@glyph{\slot@name} + \typeset@glyph{#2}$}
379 \x@cs\def{doc-LIG/>}#1#2{%

5With the exception of \usedas, which is never used at all AFAIK. It was intended to be used for math font encodings, but that is still on the TODO list. /LH

380 $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
381 \typeset@glyph{#2} + \typeset@glyph{#1}$}
382 \x@cs\def{doc-/LIG/>}#1#2{%
383 $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
384 \typeset@glyph{\slot@name} + \typeset@glyph{#2} * \typeset@glyph{#1}$}
385 \x@cs\def{doc-/LIG/>>}#1#2{%
386 $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
387 \typeset@glyph{\slot@name} + \typeset@glyph{#2} + \typeset@glyph{#1}$}

388 ⟨/doc⟩

\nextlarger
\usedas
\makerightboundary

389 ⟨∗pkg⟩

390 \let\nextlarger=\gobble_one
391 \let\usedas=\gobble_two
392 \let\makerightboundary=\gobble_one

393 ⟨/pkg⟩

394 ⟨∗doc⟩

395 \def\nextlarger#1{\Bheading{Next larger} \typeset@glyph{#1}}
396 \def\makerightboundary#1{%
397 \Bheading{Right boundary marker slot} designation \typeset@glyph{#1}%

398 } 399 ⟨/doc⟩

Not in doc: \usedas

\vartop The ⟨varchar commands⟩ are:

\varmid
\varbot
\varrep

      \vartop{⟨glyph⟩}
      \varmid{⟨glyph⟩}
      \varbot{⟨glyph⟩}
      \varrep{⟨glyph⟩}

These too do by default, which is overridden later, nothing in fontinst but typeset descriptive headings in fontdoc.

\varchar
\vartop
\varmid
\varbot
\varrep
\endvarchar

400 ⟨∗pkg⟩

401 \let\varchar=\empty_command
402 \let\vartop=\gobble_one
403 \let\varmid=\gobble_one
404 \let\varbot=\gobble_one
405 \let\varrep=\gobble_one
406 \let\endvarchar=\empty_command

407 ⟨/pkg⟩

408 ⟨∗doc⟩

409 \def\varchar{\Bheading{Extensible glyph:}}
410 \def\vartop#1{\Bheading{Top} \typeset@glyph{#1}}
411 \def\varmid#1{\Bheading{Middle} \typeset@glyph{#1}}
412 \def\varbot#1{\Bheading{Bottom} \typeset@glyph{#1}}
413 \def\varrep#1{\Bheading{Repeated} \typeset@glyph{#1}}
414 \let\endvarchar\relax

415 ⟨/doc⟩

\useexamplefont \slotexample \setslotcomment \resetslotcomment \unsetslotcomment \slot@comment \slot@font As of v 1.8 of fontinst, we have added an interface for automatic documentation of

encoding files, which has been developed by Matthias Clasen as part of his work on math fonts. The implementation was slightly modified and integrated into this version by Ulrik Vieth.

\setslotcomment defines a default slot comment, stored in the variable \slot@comment, which is subsequently used to annotate all \setslot commands. The slot comment can be changed by \resetslotcomment or turned off by

\unsetslotcomment.

\useexamplefont defines a default font, \slot@font, which may be referenced by calling \slotexample in slot comments to display the character or symbol allocated to the current slot.

Taking advantage of this mechanism, it is possible to write:

\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

These macros never do anything in fontinst, they just gobble their arguments.

416 ⟨∗pkg⟩

417 \let\useexamplefont=\gobble_one
418 \let\slotexample=\empty_command
419 \let\setslotcomment=\gobble_one
420 \let\resetslotcomment=\gobble_one
421 \let\unsetslotcomment=\empty_command

422 ⟨/pkg⟩

423 ⟨∗doc⟩

424 \newif\ifslot@comment@
425 \slot@comment@false
426 \def\slot@comment{}
427 \def\setslotcomment#1{%
428 \slot@comment@true
429 \gdef\slot@comment{#1}}
430 \def\resetslotcomment#1{%
431 \gdef\slot@comment{#1}}
432 \def\unsetslotcomment{%
433 \slot@comment@false
434 \gdef\slot@comment{}}
435 \let\slot@font=\nullfont
436 \def\useexamplefont#1{\font\slot@font=#1 }
437 \def\slotexample{{\slot@font\char\the\slot@number}}

438 ⟨/doc⟩

11 Metric files

\inputmtx The macro
      \inputmtx{⟨filename⟩}

inputs ⟨filename⟩.mtx, ignoring anything between \relax and \metrics, and any-

 thing after \endmetrics.
\inputmtx \metrics \endmetrics \endmetrics_text The \endmetrics_text macro expands to \endmetrics (eleven ‘other’ tokens,

not one control sequence token). It is used instead of \string\endmetrics, which does not work since \endmetrics is outer.

439 ⟨∗pkg⟩

440 \def\inputmtx#1{
441 \def\relax{\let\relax=\x_relax\iffalse}
442 \let\metrics=\fi
443 \primitiveinput #1.mtx\x_relax
444 \let\relax=\x_relax

445 }

446 \let\metrics=\x@relax
447 \edef\endmetrics_text{\string\endmetrics}
448 \outer\def\endmetrics{\endinput}

449 ⟨/pkg⟩

\inputmtx used to set \a_count, but we haven’t been able to find a reason for this, so we removed it.

In fontdoc, the \metrics and \endmetrics macros initially just define a group. \inputmtx redefines them to work like in fontinst however.

450 ⟨∗doc⟩

451 \def\inputmtx#1{%
452 \begingroup
453  \edef\lowercase@file{\lowercase{%
454  \edef\noexpand\lowercase@file{#1}%
455  }}%
456  \lowercase@file
457  \def\relax{\let\relax=\x@relax\iffalse}
458  \let\metrics=\fi
459  \outer \expandafter\def \csname endmetrics\endcsname{\endinput}%
460  \expandafter\input \lowercase@file.etx\x@relax
461  \let\relax=\x@relax
462 \endgroup

463 }

464 \def\metrics{\begingroup}
465 \outer\def\endmetrics{\endgroup}

466 ⟨/doc⟩

\ProvidesMtxPackage The call
      \ProvidesMtxPackage{⟨package name⟩}

signals to the package managing system that there is no need to load this package again.

467 ⟨pkg⟩\def\ProvidesMtxPackage#1{\x_cs\let{pack-#1}P}

468 ⟨∗doc⟩

469 \def\ProvidesMtxPackage#1{%
470 \Aheading{Metric package} \textsf{#1} provided.%

471 } 472 ⟨/doc⟩

\usemtxpackage The call
      \usemtxpackage{⟨package list⟩}

inputs those of the packages in the list that have not been loaded yet (i.e., those for which no \ProvidesMtxPackage has been made). Each package is assumed to reside in the metric file that \inputmtx loads when given the name of the package as argument.

The call

\usemtxpackage[⟨filename⟩]{⟨package list⟩}

inputs the packages in the list if at least one of them has not been loaded yet. In this case, all the packages are assumed to reside in the single metric file that \inputmtx loads when given ⟨filename⟩ as argument.

473 ⟨∗pkg⟩

474 \def\usemtxpackage{\futurelet\next_token\test_UseMtxPkg_arguments}
475 \def\test_UseMtxPkg_arguments{\ifx\next_token[
476  \expandafter\mtx_package_given_file
477 \else
478  \expandafter\mtx_package_separate_files
479 \fi

480 }

481 \newif\if_load_mtx_package_
482 \def\mtx_package_given_file[#1]#2{
483 \_load_mtx_package_false
484 \process_csep_list\load_true_unless_loaded #2,\process_csep_list,
485 \if_load_mtx_package_\inputmtx{#1} \fi

486 }

487 \def\load_true_unless_loaded#1{
488 \x_cs\ifx{pack-#1}P\else\_load_mtx_package_true\fi

489 }

490 \def\mtx_package_separate_files#1{
491 \process_csep_list\load_file_unless_loaded #1,\process_csep_list,

492 }

493 \def\load_file_unless_loaded#1{
494 \x_cs\ifx{pack-#1}P\else \inputmtx{#1} \fi

495 } 496 ⟨/pkg⟩

497 ⟨∗doc⟩

498 \newcommand\usemtxpackage[2][\x@relax]{%
499 \ifx \x@relax#1%
500  \Aheading{Require} all metric packages in
501  \print@csep@list{\fam0}{\{#2\}} that has not been previously
502  loaded. Expect to find them in the metric files whose names can
503  be formed from the names of the packages.
504 \else
505  \Aheading{Require} metric packages from the file \texttt{#1.mtx}

506  if some of the packages in \print@csep@list{\fam0}{\{#2\}} has not
507  been loaded previously.
508 \fi

509 } 510 ⟨/doc⟩

11.1 Kerning information

\l-NAME The kerning information is kept in the macros \l-⟨name⟩ and \r-⟨name⟩, contain-

\r-NAME
\k
\AMOUNT

ing 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⟩

control sequences, and vice versa. Examples of \⟨amount⟩ control sequences are: \0, \1, \1000, \-50, \33; these corresponds to the kern amounts 0, 1, 1000 (which would be grotesquely large), −50, and 33 respectively.

\setkern \setkern{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨integer expression⟩}

Sets a kern pair between ⟨glyph1 ⟩ and ⟨glyph2 ⟩ to the specified value, which is typically a value returned by \kerning{⟨glyph3 ⟩}{⟨glyph4 ⟩}. If there already is a kern set between ⟨glyph1 ⟩ and ⟨glyph2 ⟩ then this will not affect the output, but it will use up another 3 units of token memory.

511 ⟨∗pkg⟩

512 \def\setkern#1#2#3{
513 \x_cs\ifx{i-rawscale}\x_relax
514  \expandafter\set_kern
515  \csname~r-#1\expandafter\endcsname
516  \csname~l-#2\endcsname{#3}
517 \else
518  \expandafter\set_kern
519  \csname~r-#1\expandafter\endcsname
520  \csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}}
521 \fi

522 }

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

526 }

527 \def\set_kern_cs#1#2#3{
528 \add_to#2{\k#3#1}
529 \add_to#3{\k#2#1}

530 } 531 ⟨/pkg⟩

532 ⟨∗doc⟩

533 \def\setkern#1#2#3{%
534 \Bheading{Kern} ${\typeset@glyph{#1} + \typeset@glyph{#2}}
535 \rightarrow \expression0{#3}$}

536 ⟨/doc⟩

\resetkern \resetkern{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨integer expression⟩}

Resets the kern pair between ⟨glyph1 ⟩ and ⟨glyph2 ⟩ to the specified value. Note however that this does not relieve TEX of the burden to remember the previous kerning pair between these two glyphs (if there was one).

537 ⟨∗pkg⟩

538 \def\resetkern#1#2#3{
539 \x_cs\ifx{i-rawscale}\x_relax
540  \expandafter\reset_kern
541  \csname~r-#1\expandafter\endcsname
542  \csname~l-#2\endcsname{#3}
543 \else
544  \expandafter\reset_kern
545  \csname~r-#1\expandafter\endcsname
546  \csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}}
547 \fi

548 }

549 \def\reset_kern#1#2#3{
550 \eval_expr{#3}
551 \expandafter\reset_kern_cs\csname\the\result\endcsname#1#2

552 }

553 \def\reset_kern_cs#1#2#3{
554 \prep_to#2{\k\expandafter#3\expandafter#1}
555 \prep_to#3{\k\expandafter#2\expandafter#1}

556 } 557 ⟨/pkg⟩

558 ⟨∗doc⟩

559 \def\resetkern#1#2#3{%
560 \Bheading{Override kern} ${\typeset@glyph{#1} + \typeset@glyph{#2}}
561  \rightarrow \expression0{#3}$}

562 ⟨/doc⟩

\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⟩ (which is an integer expression). \setleftrightkerning does both.

563 ⟨∗pkg⟩

564 \def\setleftkerning#1#2#3{
565 \eval_expr_to\b_count{#3}
566 \expandafter\set_kerning
567  \csname~l-#1\expandafter\endcsname
568  \csname~l-#2\endcsname

569 }

570 \def\setrightkerning#1#2#3{
571 \eval_expr_to\b_count{#3}
572 \expandafter\set_kerning
573  \csname~r-#1\expandafter\endcsname
574  \csname~r-#2\endcsname

575 }

576 \def\setleftrightkerning#1#2#3{
577 \eval_expr_to\b_count{#3}
578 \expandafter\set_kerning
579  \csname~l-#1\expandafter\endcsname
580  \csname~l-#2\endcsname

581 \expandafter\set_kerning
582  \csname~r-#1\expandafter\endcsname
583  \csname~r-#2\endcsname

584 }

585 \def\set_kerning#1#2{
586 \if\b_count=\one_thousand
587  \def\k##1##2{
588  \set_kern_cs##2##1#1

589 }

590 \else
591  \def\k##1##2{
592  \set_kern##1#1{
593  \scale\b_count{\expandafter\gobble_one\string##2}

594 } 595 }

596 \fi

597 #2 598 } 599 ⟨/pkg⟩

600 ⟨∗doc⟩

601 \def\setleftkerning#1#2#3{%
602 \Bheading{Kern} \typeset@glyph{#1} on the left like
603 \typeset@glyph{#2} scaled $\expression0{#3}$}
604 \def\setrightkerning#1#2#3{%
605 \Bheading{Kern} \typeset@glyph{#1} on the right like
606 \typeset@glyph{#2} scaled $\expression0{#3}$}
607 \def\setleftrightkerning#1#2#3{%
608 \Bheading{Kern} \typeset@glyph{#1} on the left and right like
609 \typeset@glyph{#2} scaled $\expression0{#3}$}

610 ⟨/doc⟩

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

611 ⟨∗pkg⟩

612 \def\kerning#1#2{0\x_relax
613 \def\k##1{\csname~set-\string##1\endcsname\gobble_one}
614 \bgroup
615 \x_cs\def{set-\string\l-#2}##1##2{
616  \global\result=\expandafter\gobble_one\string##2\egroup

617 }

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

620 } 621 ⟨/pkg⟩

622 ⟨doc⟩\def\kerning#1#2{k(\typeset@glyph{#1})(\typeset@glyph{#2})}
\ifiskern  \ifiskern{⟨glyph1 ⟩}{⟨glyph2 ⟩}\then

This command tests if there is a kern pair between ⟨glyph1 ⟩ and ⟨glyph2 ⟩. It’s hard to say if there is a use for it, but it is included for symmetry.

623 ⟨∗pkg⟩

624 \def\ifiskern#1#2\then{

625 \def\k##1##2{\ifx T##1 \let\k\gobble_two \fi}
626 \bgroup
627  \x_cs\let{l-#2}T
628  \csname r-#1\endcsname
629 \expandafter\egroup \ifx\k\gobble_two

630 } 631 ⟨/pkg⟩

632 ⟨∗doc⟩

633 \def\ifiskern#1#2\then{%
634 \generic@if{kern \typeset@glyph{#1}${}+{}$\typeset@glyph{#2} set}}

635 ⟨/doc⟩

\unsetkerns \unsetkerns{⟨left glyph list⟩}{⟨right glyph list⟩}

This command unsets all kerns with a glyph in the ⟨left glyph list⟩ on the left and a glyph in the ⟨right glyph list⟩ on the right. The lists themselves are ordinary comma-separated lists. Unlike \setkern and \resetkern, \unsetkerns actually removes the kerning pairs from TEX’s memory.

The implementation itself simply goes through \r-⟨left glyph⟩ for each element ⟨left glyph⟩ in ⟨left glyph list⟩ and \l-⟨right glyph⟩ for each element ⟨right glyph⟩ in ⟨right glyph list⟩, removing each \k⟨token⟩⟨token⟩ tripple that refers to a glyph from the opposite list as it goes along. To make this test reasonably fast, the routine first “marks” the glyphs in the other list by setting the control sequences \slots-⟨glyph⟩ to U (the letter token U). This mark is later removed when the \r-⟨glyph⟩ or \l-⟨glyph⟩ respectively control sequences have been gone through; the \slots-⟨glyph⟩ control sequences are then set to \relax.

636 ⟨∗pkg⟩

637 \def\unsetkerns#1#2{
638 \let\k\k_unless_to_U
639 \process_csep_list\make_slots_U#1,\process_csep_list,
640 \def\do##1{\x_cs\main_remove_Us{l-##1}}
641 \process_csep_list\do#2,\process_csep_list,
642 \process_csep_list\make_slots_relax#1,\process_csep_list,
643 \process_csep_list\make_slots_U#2,\process_csep_list,
644 \def\do##1{\x_cs\main_remove_Us{r-##1}}
645 \process_csep_list\do#1,\process_csep_list,
646 \process_csep_list\make_slots_relax#2,\process_csep_list,

647 }

648 \def\make_slots_U#1{\x_cs\let{slots-#1}U}
649 \def\make_slots_relax#1{\x_cs\let{slots-#1}\x_relax}
650 \def\k_unless_to_U#1#2{
651 \x_cs\ifx{slots-\expandafter\gobble_three\string#1}U \else
652  \noexpand\k\noexpand#1\noexpand#2
653 \fi

654 }

655 \def\main_remove_Us#1{
656 \ifx#1\x_relax \else
657  \edef#1{#1}
658  \ifx#1\empty_command \let#1\x_relax \fi
659 \fi

660 } 661 ⟨/pkg⟩

662 ⟨∗doc⟩

663 \def\unsetkerns#1#2{%
664 \Bheading{Remove} all kerning pairs in
665 \print@csep@list{\fam0}{\{#1\}\times\{#2\}}.%

666 } 667 ⟨/doc⟩

\noleftkerning \norightkerning \noleftrightkerning The argument of these commands is the name of a glyph. The commands removes all kerns on the left, on the right, and on both sides respectively, of this glyph.

668 ⟨∗pkg⟩

669 \def\noleftkerning#1{\no_kerning{l}{#1}}
670 \def\norightkerning#1{\no_kerning{r}{#1}}
671 \def\noleftrightkerning#1{\no_kerning{l}{#1}\no_kerning{r}{#1}}

672 ⟨/pkg⟩

673 ⟨∗doc⟩

674 \def\noleftkerning#1{%
675 \Bheading{Remove kerns} on the left of glyphs in
676 \print@csep@list{\fam0}{\{#1\}}.}
677 \def\norightkerning#1{%
678 \Bheading{Remove kerns} on the right of glyphs in
679 \print@csep@list{\fam0}{\{#1\}}.}
680 \def\noleftrightkerning#1{%
681 \Bheading{Remove kerns} on any side of glyphs in
682 \print@csep@list{\fam0}{\{#1\}}.}

683 ⟨/doc⟩

\no_kerning This macro is called as

\no_kerning{⟨side⟩}{⟨glyph list⟩}

where ⟨side⟩ is l or r, and ⟨glyph list⟩ is a comma-separated list of glyph names. The macro unsets all kerns on the ⟨side⟩ side of the glyphs in the ⟨glyph list⟩.

684 ⟨∗pkg⟩

685 \def\no_kerning#1#2{
686 \let\k\no_kerning_i
687 \def\do##1{\csname #1-##1\endcsname}
688 \bgroup
689  \aftergroup\def \aftergroup\a_macro \aftergroup{
690  \process_csep_list\do #2,\process_csep_list,
691  \aftergroup}
692 \egroup
693 \def\do##1{\expandafter\let \csname #1-##1\endcsname \x_relax}
694 \process_csep_list\do #2,\process_csep_list,
695 \let\k\no_kerning_ii
696 \def\do##1{\edef##1{##1}}
697 \a_macro

698 }

\no_kerning_i The \no_kerning_i macro is used by \no_kerning in constructing a list of all glyphs that a glyph in the ⟨glyph list⟩ has a ⟨side⟩ kern to, while avoiding repetitions.

699 \def\no_kerning_i#1#2{
700 \ifx #1\x_relax \else
701  \aftergroup\do \aftergroup#1

702  \let #1\x_relax
703 \fi

704 }

\no_kerning_ii The \no_kerning_ii macro is similar to the \k_unless_to_U macro.
705 \def\no_kerning_ii#1#2{
706 \ifx #1\x_relax \else \noexpand\k \noexpand#1 \noexpand#2 \fi

707 } 708 ⟨/pkg⟩

11.2 Glyph information

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

\typeset@glyph The \typeset@glyph macro is analogous to \typeset@string and friends.
709 ⟨doc⟩\let\typeset@glyph=\typeset@string
\width \height \depth \italic  \width{⟨glyph⟩}
\height{⟨glyph⟩}
\depth{⟨glyph⟩}
\italic{⟨glyph⟩}

In fontinst, these macros return the width, height, depth, and italic correction of ⟨glyph⟩ as an integer.

710 ⟨∗pkg⟩

711 \def\width{\glyph_parameter\first_of_six}
712 \def\height{\glyph_parameter\second_of_six}
713 \def\depth{\glyph_parameter\third_of_six}
714 \def\italic{\glyph_parameter\fourth_of_six}

715 ⟨/pkg⟩

In fontdoc, they print symbolic representations for the corresponding integer expressions.

716 ⟨∗doc⟩

717 \def\width#1{w(\typeset@glyph{#1})}
718 \def\height#1{h(\typeset@glyph{#1})}
719 \def\depth#1{d(\typeset@glyph{#1})}
720 \def\italic#1{i(\typeset@glyph{#1})}

721 ⟨/doc⟩

\mapcommands \mapfonts These are similar to \width and its companions, but they are not user level commands.

722 ⟨∗pkg⟩

723 \def\mapcommands{\glyph_parameter\fifth_of_six}
724 \def\mapfonts{\glyph_parameter\sixth_of_six}

725 ⟨/pkg⟩

\glyph_parameter
\first_of_six
\second_of_six
\third_of_six
\fourth_of_six
\fifth_of_six
\sixth_of_six

726 ⟨∗pkg⟩

File b: fimain.dtx  61

727 \def\glyph_parameter#1#2{
728 \expandafter\expandafter\expandafter
729  #1\csname~g-#2\endcsname

730 }

731 \def\first_of_six#1#2#3#4#5#6{#1}
732 \def\second_of_six#1#2#3#4#5#6{#2}
733 \def\third_of_six#1#2#3#4#5#6{#3}
734 \def\fourth_of_six#1#2#3#4#5#6{#4}
735 \def\fifth_of_six#1#2#3#4#5#6{#5}
736 \def\sixth_of_six#1#2#3#4#5#6{#6}
\saved_scale \saved_mapfont \saved_raw \saved_rule \saved_special \saved_warning \saved_movert \saved_moveup \saved_push \saved_pop These are the commands allowed inside a glyph. They are initally set to \relax,

so we can \edef with them safely.

737 \let\saved_scale\x_relax
738 \let\saved_mapfont\x_relax
739 \let\saved_raw\x_relax
740 \let\saved_rule\x_relax
741 \let\saved_special\x_relax
742 \let\saved_warning\x_relax
743 \let\saved_movert\x_relax
744 \let\saved_moveup\x_relax
745 \let\saved_push\x_relax
746 \let\saved_pop\x_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. The \glyph_maxhpos variable globally keeps track of the largest horizontal offset position reached so far (with the possible exception of the current position, i.e. width, which may well be larger).

\glyph_width
\glyph_height
\glyph_depth
\glyph_italic
\glyph_map_commands
\glyph_map_fonts
\glyph_voffset
\glyph_maxhpos

747 \newcount\glyph_width
748 \newcount\glyph_height
749 \newcount\glyph_depth
750 \newcount\glyph_italic
751 \newtoks\glyph_map_commands
752 \newtoks\glyph_map_fonts
753 \newcount\glyph_voffset
754 \newcount\glyph_maxhpos

\setglyph \gobble_glyph The \setglyph{⟨name⟩} command defines \g-⟨name⟩, unless \g-⟨name⟩ has al-

ready been defined.

The reason \g-⟨name⟩ is defined before calling \resetglyph is to make it possible to refer to “the glyph constructed so far” using \width{⟨name⟩}, \height{⟨name⟩}, etc.

755 \def\setglyph#1{
756 \ifisglyph{#1}\then
757  \expandafter\gobble_glyph

758 \else
759  \x_cs\def{g-#1}{{\the\glyph_width}{\the
760  \glyph_height}{\the\glyph_depth}{\the\glyph_italic}{\the
761  \glyph_map_commands}{\the\glyph_map_fonts}}
762  \resetglyph{#1}
763 \fi

764 }

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

766 ⟨/pkg⟩

767 ⟨doc⟩\def\setglyph#1{\Aheading{Glyph `#1'}}

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

768 ⟨∗pkg⟩

769 \def\resetglyph#1{
770 \def\glyphname{#1}
771 \glyph_width=0
772 \global\glyph_height=0
773 \global\glyph_depth=0
774 \global\glyph_italic=0
775 \glyph_voffset=0
776 \global\glyph_maxhpos=0
777 \global\glyph_map_commands={}
778 \global\glyph_map_fonts={}

779 } 780 ⟨/pkg⟩

781 ⟨doc⟩\def\resetglyph#1{\Aheading{Reset glyph `#1'}}
\endsetglyph
\endresetglyph

782 ⟨∗pkg⟩

783 \def\endsetglyph{
784 \x_cs\edef{g-\glyphname}
785  {{\the\glyph_width}{\the\glyph_height}
786  {\the\glyph_depth}{\the\glyph_italic}
787  {\the\glyph_map_commands}{\the\glyph_map_fonts}}

788 }

789 \let\endresetglyph=\endsetglyph

790 ⟨/pkg⟩

791 ⟨∗doc⟩

792 \def\endsetglyph{}
793 \def\endresetglyph{}

794 ⟨/doc⟩

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

795 ⟨∗pkg⟩

796 \def\setrawglyph#1#2#3#4#5#6#7#8{
797 \x_cs\ifx{g-#1}\x_relax
798  \x_cs\ifx{i-rawscale}\x_relax
799  \x_cs\def{g-#1}{
800  {#5}

801  {#6}
802  {#7}
803  {#8}
804  {\saved_raw{#2}{#4}{#1}}
805  {\saved_mapfont{#2}{#3}}

806 }

807  \else
808  \eval_expr_to\e_count{\int{rawscale}}
809  \eval_expr_to\a_count{\scale{#5}\e_count}
810  \eval_expr_to\b_count{\scale{#6}\e_count}
811  \eval_expr_to\c_count{\scale{#7}\e_count}
812  \eval_expr_to\d_count{\scale{#8}\e_count}
813  \x_cs\edef{g-#1}{
814  {\the\a_count}
815  {\the\b_count}
816  {\the\c_count}
817  {\the\d_count}
818  {\saved_scale{\the\e_count}
819  {\saved_raw{#2}{#4}{#1}}}
820  {\saved_scale{\the\e_count}
821  {\saved_mapfont{#2}{#3}}}

822 }

823  \fi
824 \fi

825 } 826 ⟨/pkg⟩

827 ⟨∗doc⟩

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

830 ⟨/doc⟩

\setnotglyph

831 ⟨∗pkg⟩

832 \def\setnotglyph#1#2#3#4#5#6#7#8{
833 \x_cs\ifx{g-#1-not}\x_relax
834  \x_cs\ifx{i-rawscale}\x_relax
835  \x_cs\def{g-#1-not}{
836  {#5}
837  {#6}
838  {#7}
839  {#8}

840 {} 841 {} 842 }

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

853  {\the\d_count}

854 {} 855 {} 856 }

857  \fi
858 \fi

859 } 860 ⟨/pkg⟩

861 ⟨doc⟩\def\setnotglyph#1#2#3#4#5#6#7#8{\Aheading{Pseudoglyph `#1-not'}}

\unsetglyph The \unsetglyph{⟨name⟩} command makes \g-⟨name⟩ undefined.

862 ⟨pkg⟩\def\unsetglyph#1{\x_cs\let{g-#1}\x_relax}
Not in doc: \unsetglyph

11.3 Glyph commands

The ⟨glyph commands⟩ are:

\glyph  \glyph{⟨glyph⟩}{⟨scale⟩}

863 ⟨∗pkg⟩

864 \def\glyph#1#2{
865 \eval_expr_to\b_count{#2}
866 \ifnum \b_count=\one_thousand
867  \eval_expr_to\glyph_width{\add\glyph_width{\width{#1}}}
868  \g_eval_expr_to\glyph_height{\max\glyph_height
869  {\add{\height{#1}}\glyph_voffset}}
870  \g_eval_expr_to\glyph_depth{\max\glyph_depth
871  {\sub{\depth{#1}}\glyph_voffset}}
872  \g_eval_expr_to\glyph_italic{\italic{#1}}
873  \edef\a_macro{\mapcommands{#1}}
874  \global\glyph_map_commands\expandafter{
875  \the\expandafter\glyph_map_commands \a_macro

876 }

877  \edef\a_macro{\mapfonts{#1}}
878 \else
879  \eval_expr_to\glyph_width{
880  \add\glyph_width{\scale\b_count{\width{#1}}}

881 }

882  \g_eval_expr_to\glyph_height{\max\glyph_height
883  {\add{\scale\b_count{\height{#1}}}\glyph_voffset}}
884  \g_eval_expr_to\glyph_depth{\max\glyph_depth
885  {\sub{\scale\b_count{\depth{#1}}}\glyph_voffset}}
886  \g_eval_expr_to\glyph_italic{\scale\b_count{\italic{#1}}}
887  \edef\a_macro{\saved_scale{\the\b_count}{\mapcommands{#1}}}
888  \global\glyph_map_commands\expandafter{
889  \the\expandafter\glyph_map_commands \a_macro

890 }

891  \edef\a_macro{\saved_scale{\the\b_count}{\mapfonts{#1}}}
892 \fi
893 \global\glyph_map_fonts\expandafter{
894  \the\expandafter\glyph_map_fonts \a_macro

895 } 896 } 897 ⟨/pkg⟩

898 ⟨doc⟩\def\glyph#1#2{\Bheading{Glyph} `#1' scaled $\expression0{#2}$}
\glyphrule  \glyphrule{⟨width⟩}{⟨height⟩}

899 ⟨∗pkg⟩

900 \def\glyphrule#1#2{
901 \eval_expr_to\b_count{#1} \eval_expr_to\c_count{#2}
902 \advance\glyph_width by \b_count
903 \g_eval_expr_to\glyph_depth{\max\glyph_depth{-\glyph_voffset}}
904 \g_eval_expr_to\glyph_height{
905  \max\glyph_height{\add\glyph_voffset\c_count}

906 }

907 \global\glyph_italic=0
908 \edef\a_macro{\saved_rule{\the\b_count}{\the\c_count}}
909 \global\glyph_map_commands\expandafter{
910  \the\expandafter\glyph_map_commands \a_macro

911 } 912 } 913 ⟨/pkg⟩

914 ⟨∗doc⟩

915 \def\glyphrule#1#2{%
916 \Bheading{Rule} $\expression0{#1}$ by $\expression0{#2}$}

917 ⟨/doc⟩

\glyphspecial \glyphwarning  \glyphspecial{⟨string⟩}
 \glyphwarning{⟨string⟩}

918 ⟨∗pkg⟩

919 \def\glyphspecial#1{
920 \edef\a_macro{\saved_special{#1}}
921 \global\glyph_map_commands\expandafter{
922  \the\expandafter\glyph_map_commands \a_macro

923 } 924 }

925 \def\glyphwarning#1{
926 \edef\a_macro{\saved_warning{#1}}
927 \global\glyph_map_commands\expandafter{
928  \the\expandafter\glyph_map_commands \a_macro

929 } 930 } 931 ⟨/pkg⟩

932 ⟨∗doc⟩

933 \def\glyphspecial#1{\Bheading{Special} `#1'}
934 \def\glyphwarning#1{\Bheading{Warning} `#1'}

935 ⟨/doc⟩

\movert \moveup  \movert{⟨xoffset⟩}
 \moveup{⟨yoffset⟩}

936 ⟨∗pkg⟩

937 \def\movert#1{
938 \eval_expr{#1}
939 \ifnum \glyph_maxhpos<\glyph_width
940  \global\glyph_maxhpos\glyph_width
941 \fi

942 \ifnum 0=\result \else
943  \advance\glyph_width by \result
944  \edef\a_macro{\saved_movert{\the\result}}
945  \global\glyph_map_commands\expandafter{
946  \the\expandafter\glyph_map_commands \a_macro

947 }

948 \fi

949 }

950 \def\moveup#1{
951 \eval_expr{#1}
952 \ifnum\result=0\else
953  \advance\glyph_voffset by \result
954  \edef\a_macro{\saved_moveup{\the\result}}
955  \global\glyph_map_commands\expandafter{
956  \the\expandafter\glyph_map_commands \a_macro

957 }

958 \fi

959 } 960 ⟨/pkg⟩

961 ⟨∗doc⟩

962 \def\movert#1{\Bheading{Rt}~$\expression0{#1}$}
963 \def\moveup#1{\Bheading{Up}~$\expression0{#1}$}

964 ⟨/doc⟩

{\push \atop \pop}

965 ⟨∗pkg⟩

966 \def\push{
967 \bgroup
968 \global\glyph_map_commands\expandafter{
969  \the\glyph_map_commands \saved_push

970 } 971 }

972 \def\pop{
973 \ifnum \glyph_maxhpos<\glyph_width
974  \global\glyph_maxhpos\glyph_width
975 \fi
976 \egroup
977 \global\glyph_map_commands\expandafter{
978  \the\glyph_map_commands \saved_pop

979 } 980 } 981 ⟨/pkg⟩

982 ⟨∗doc⟩

983 \def\push{\Bheading{Push}}
984 \def\pop{\Bheading{Pop}}

985 ⟨/doc⟩

\resetwidth \resetheight \resetdepth \resetitalic  \resetwidth{⟨width⟩}
 \resetheight{⟨height⟩}
 \resetdepth{⟨depth⟩}
 \resetitalic{⟨italic⟩}

986 ⟨∗pkg⟩

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

991 ⟨/pkg⟩

992 ⟨∗doc⟩

 993 \def\resetwidth#1{\Bheading{Reset width to $\expression0{#1}$}}
 994 \def\resetheight#1{\Bheading{Reset height to $\expression0{#1}$}}
 995 \def\resetdepth#1{\Bheading{Reset depth to $\expression0{#1}$}}
 996 \def\resetitalic#1{\Bheading{Reset italic to $\expression0{#1}$}}

997 ⟨/doc⟩

\glyphpcc Some syntactic sugar: \glyphpcc could do with optimization. \glyphpcc{⟨glyph⟩}{⟨xoffset⟩}{⟨yoffset⟩}

998 ⟨∗pkg⟩

 999 \def\glyphpcc#1#2#3{
1000 \push
1001  \movert{#2}
1002  \moveup{#3}
1003  \glyph{#1}{\one_thousand}
1004 \pop

1005 } 1006 ⟨/pkg⟩

1007 ⟨∗doc⟩

1008 \def\glyphpcc#1#2#3{
1009 \push
1010  \movert{#2}
1011  \moveup{#3}
1012  \glyph{#1}{1000}
1013 \pop

1014 } 1015 ⟨/doc⟩

\glyphbboxright The \glyphbboxright command is a valid integer expression, but its value

  is only meaningful inside a \setglyph . . . \endsetglyph or \resetglyph . . .

\endresetglyph structure. There its value is almost the horizontal position of the right edge of the bounding box for the glyph constructed so far—in reality it is the greatest horizontal offset reached so far.

1016 ⟨pkg⟩\def\glyphbboxright{\max\glyph_width\glyph_maxhpos}
1017 ⟨doc⟩\def\glyphbboxright{\hbox{glyphbboxright}}
\samesize  \samesize{⟨glyph⟩}

1018 ⟨∗pkg⟩

1019 \def\samesize#1{
1020 \x_cs\ifx{g-#1}\x_relax
1021  \resetwidth{\glyphbboxright}
1022 \else
1023  \expandafter\expandafter\expandafter
1024  \same_size\csname g-#1\endcsname

1025 \fi 1026 }

1027 \def\same_size#1#2#3#4#5#6{

1028 \movert{\sub{#1}\glyph_width}
1029 \global\glyph_height=#2
1030 \global\glyph_depth=#3
1031 \global\glyph_italic=#4

1032 } 1033 ⟨/pkg⟩

1034 ⟨doc⟩\def\samesize#1{\Bheading{Reset dimensions to those of `#1'.}}

\ifisglyph The control flow command:

1035 ⟨∗pkg⟩

1036 \def\ifisglyph#1\then{
1037 \x_cs\ifx{g-#1}\x_relax
1038  \expandafter\if_false
1039 \else
1040  \expandafter\if_true

1041 \fi 1042 } 1043 ⟨/pkg⟩

1044 ⟨doc⟩\def\ifisglyph#1\then{\generic@if{glyph \typeset@glyph{#1} set}}

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

12.1 Lowest-level user interface

\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

1045 ⟨∗pkg⟩

1046 \def\etxtovpl#1#2{{
1047 \def\vpl_extension{vpl}
1048 \def\vpl_title{COMMENT}
1049 \def\vpl_font{virtual~font}
1050 \def\vpl_Font{Virtual~font}
1051 \def\vpl_caller{\string\etxtovpl}
1052 \def\vpl_to_vf##1{vpltovf~##1.vpl~##1.vf~##1.tfm}
1053 \etx_to_font{#1}{#2}

1054 }}

1055 \def\etxtopl#1#2{{
1056 \def\vpl_extension{pl}
1057 \def\vpl_title{COMMENT}
1058 \def\vpl_font{font}
1059 \def\vpl_Font{Font}

1060 \def\vpl_caller{\string\etxtopl}
1061 \def\vpl_to_vf##1{pltotfm~##1.pl~##1.tfm}
1062 \_including_map_false
1063 \etx_to_font{#1}{#2}

1064 }}

\if_including_map_LH 1998/10/02: The v 1.5 method of controlling whether MAP and MAPFONT property lists should be written requires that some code is put in an awkward place (in \make_mapfonts rather than \make_characters). As I am reorganising the code anyway, I saw it best to let a switch control this instead. If \if_including_map_ is true, MAP and MAPFONT property lists are written to the file (which should be a VPL), if it is false then they are not written to the file (which is then a normal PL).

1065 \newif\if_including_map_
1066 \_including_map_true
\etx_to_font  \etx_to_font{⟨encoding⟩}{⟨fontfile⟩} makes a .vpl file.
1067 \def\etx_to_font#1#2{
1068 \make_assignments{#1}
1069 \open_out{#2.\vpl_extension}
1070 \out_line{(\vpl_title\space\vpl_font\space
1071  #2~created~by~fontinst~v\fontinstversion)}
1072 \out_line{}
1073 \out_line{(COMMENT~Filename:~#2.\vpl_extension)}
1074 \out_line{(COMMENT~Created~by:~tex~\jobname)}
1075 \out_line{(COMMENT~Created~using:~\vpl_caller{#1}{#2})}
1076 \out_line{}
1077 \out_line{(COMMENT~This~file~can~be~turned~into~a~\vpl_font\space
1078  with)}
1079 \out_line{(COMMENT~\vpl_to_vf{#2})}
1080 \out_line{}
1081 \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
1082 \out_line{}
1083 \make_header{#1}
1084 \if_including_map_\make_mapfonts{#1} \fi
1085 \make_fontdimens{#1}
1086 \make_ligtable{#1}
1087 \make_characters{#1}
1088 \make_tidy{#1}
1089 \out_line{}
1090 \out_line{(COMMENT~END~OF~FILE~#2.\vpl_extension)}
1091 \close_out{\vpl_Font}

1092 }

\pre_first_etx_pass_hook \pre_second_etx_pass_hook \pre_third_etx_pass_hook \pre_fourth_etx_pass_hook \post_first_etx_pass_hook \post_second_etx_pass_hook \post_third_etx_pass_hook \post_fourth_etx_pass_hook \tidying_up_hook LH 1998/09/30: As the \etxtovpl and \etxtopl macros are the lowest-level

interfaces to what they do that are available in fontinst and as the amount of code they execute is really quite large, I feel there is a need for some robust mechanism for adding code to this, in case the need should arise. Such a mechanism is provided by the following hooks:

1093 \let\pre_first_etx_pass_hook\x_relax
1094 \let\pre_second_etx_pass_hook\x_relax
1095 \let\pre_third_etx_pass_hook\x_relax
1096 \let\pre_fourth_etx_pass_hook\x_relax

1097 \let\post_first_etx_pass_hook\x_relax
1098 \let\post_second_etx_pass_hook\x_relax
1099 \let\post_third_etx_pass_hook\x_relax
1100 \let\post_fourth_etx_pass_hook\x_relax
1101 \let\tidying_up_hook\x_relax

To include code in one of them, one should write things like

     \add_to\pre_first_etx_pass_hook{⟨extra code⟩}

12.2 Glyph to slot assignments

The way fontinst has traditionally kept track of which glyph goes to which slot—information which is needed when writing the LIGTABLE in a (V)PL, for \nextlarger, and for the varchar commands—is by storing the slot number in the integer whose name is the name of the glyph. There are two main problems with this implementation: (i) If a user sets an integer which happens to have the same name as a glyph that is not assigned to any slot, then kerns for that unused glyph might be written to the file, accidentally creating a kerning pair where there should be none. (ii) It is only possible to store one slot number per glyph, so if one uses the same glyph for several slots then fontinst can only write kerns (and ligatures) for one of the occurences, despite the fact that all occurences have the same typographical need for them. These problems do only occur for glyphs on the right side of a ligature/kerning pair, but they are still serious enough. This part of fontinst has therefore been reimplemented.

The new implementation does not use integers, instead it uses a new family

\slots-GLYPH of macros with names on the form \slots-⟨glyph⟩. These macros expand to sequences of \do ⟨character⟩, where ⟨character⟩ is a category 12 (other) token whose character code equals the slot number.

In the entire space of such names, each slot sould be mensioned at most once, with one exception, namely the slot which serves as right boundary marker, which may occur twice (once for the glyph which actually is assigned to the slot and once for the right boundary marker glyph). To detect whether there is a collision between these two uses of the slot, the right boundary marker glyph uses \rboundary_do instead of \do and the glyph whose slot serves as boundarychar uses \rbserver_do instead of \do. By redefining these two control sequences to generate a warning message when appropriate, the occurence of such a collision can be brought to the user’s attention.

As it turned out to not be such a big deal, some extra code (protected by a docstrip switch called ⟨boundaryCompability⟩) that makes fontinst compatible with the previous syntax for boundary handling has been included. I don’t recommend using it though, since it makes fontinst store almost all slot numbers in two places.

\make_assignments
1102 \def\make_assignments#1{
1103 \let\do_slot=\assign_slot
1104 \let\end_do_slot=\end_assign_slot
1105 \def\do_boundary{\bgroup
1106  \let\makerightboundary=\bad_makerightboundary

1107 }

1108 \let\endsetleftboundary=\egroup
1109 \let\makerightboundary=\assign_rboundary

1110 \pre_first_etx_pass_hook
1111 \inputetx{#1}
1112 \post_first_etx_pass_hook
1113 \let\end_do_slot=\empty_command
1114 \let\do_boundary=\x_relax
1115 \let\endsetleftboundary=\x_relax
1116 \let\makerightboundary=\gobble_one

1117 }

\assign_slot \end_assign_slot  \assign_slot begins the assignment of a slot to a glyph. \end_assign_slot com-

pletes it. In the time between these two, some information is stored in \a_toks, so that it can be modified by an intervening \makerightboundary (which is then

  \assign_rboundary).

Note that the code below will not reset \lccode0. The value of this register should be considered uncertain while a ligful PL or VPL file is written.

1118 \def\assign_slot{\a_toks={\do}}
1119 \begingroup
1120 \catcode0=12
1121 \gdef\end_assign_slot{
1122  \ifisglyph\slot_name\then
1123  \lccode0=\slot_number
1124  \lowercase{
1125  \expandafter\add_to
1126  \csname slots-\slot_name\expandafter\endcsname
1127  \expandafter{\the\a_toks^^@}

1128 }

1129 ⟨boundaryCompability⟩  \x_resetint\slot_name\slot_number

1130 \fi 1131 }

\assign_rboundary \bad_makerightboundary  \assign_rboundary is what \makerightboundary is when it is assigning a slot

to act as right boundary marker.

    \bad_makerightboundary is what \makerightboundary temporarily gets set
  to between \setleftboundary and \endsetleftboundary.
1132 \gdef\assign_rboundary#1{
1133  \lccode0=\slot_number
1134  \lowercase{\x_cs\add_to{slots-#1}{\rboundary_do^^@}}
1135  \x_setint{\percent_char boundarychar}\slot_number
1136  \a_toks={\rbserver_do}

1137 }

1138 \endgroup
1139 \def\bad_makerightboundary#1{
1140 \errhelp={The~left~boundary~is~not~a~slot,~so~it~cannot~serve~
1141  as~right~boundary.}
1142 \errmessage{Incorrect~use~of~\string\makerightboundary}

1143 }

\get_slot_num It is sometimes necessary to get the number of an arbitrary slot given only the name of the glyph which has been assigned to the slot. In such situations, the call

      \get_slot_num{⟨glyph⟩}

will set \result to the number of one such slot if the glyph has been assigned to some slot, or set \result to minus one if the glyph has not been assigned to a slot.

1144 \def\get_slot_num#1{

1145 ⟨∗!boundaryCompability⟩

1146 \global\result=-1
1147 \bgroup
1148  \def\do{\global\result=`}
1149  \let\rbserver_do=\do
1150  \let\rboundary_do=\gobble_one
1151  \csname slots-#1\endcsname
1152 \egroup

1153 ⟨/!boundaryCompability⟩ 1154 ⟨∗boundaryCompability⟩

1155 \ifisint{#1}\then
1156  \global\result=\int{#1}
1157 \else
1158  \global\result=-1

1159 \fi

1160 \x_relax

1161 ⟨/boundaryCompability⟩ 1162 }

\ifisinslot The call \ifisinslot{⟨glyph⟩}{⟨slot⟩}\then can be used to test whether glyph ⟨glyph⟩ has been assigned to slot ⟨slot⟩. Both then-part and else-part of the conditional will however be ignored when the ETX file is read the first time, since the assignment of glyph to slots need not have been completed yet.

1163 \def\ifisinslot#1#2\then{
1164 \ifx \makerightboundary\gobble_one

This is used to test if the ETX file is being read in for the first time. It is a bit hacky, but it is efficient.

1165  \eval_expr{#2}
1166  \begingroup
1167  \def\do##1{\ifnum `##1=\result \let\do=\gobble_one \fi}
1168  \def\rbserver_do{\do}
1169  \let\rboundary_do=\gobble_one
1170  \csname slots-#1\endcsname
1171  \expandafter\endgroup
1172  \ifx \do\gobble_one
1173  \expandafter\expandafter \expandafter\if_true
1174  \else
1175  \expandafter\expandafter \expandafter\if_false

1176 \fi

1177 \else
1178  \expandafter\gobble_if

1179 \fi 1180 } 1181 ⟨/pkg⟩

1182 ⟨∗doc⟩

1183 \def\ifisinslot#1#2\then{%
1184 \generic@if{glyph \typeset@glyph{#1} assigned to slot
1185 $\expression0{#2}$}%

1186 } 1187 ⟨/doc⟩

12.3 The header, mapfonts, and fontdimens

\scaled_design_size \afmconvert The call

\afmconvert⟨dimen⟩=⟨integer expression⟩;

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

1188 ⟨∗pkg⟩

1189 \newdimen\scaled_design_size
1190 \def\afm_convert#1=#2;{
1191 \eval_expr{#2}
1192 #1=\scaled_design_size
1193 \divide#1 by 8
1194 \multiply #1 by \result
1195 \divide #1 by \one_thousand
1196 \multiply#1 by 8

1197 }

\vpl_real \vpl_int The commands \vpl_real⟨dimen⟩ and \vpl_int⟨count⟩ print a dimension and integer respectively in (V)PL syntax.

1198 \def\vpl_real#1{R~\expandafter\lose_measure\the#1}
1199 \def\vpl_int#1{D~\the#1}

LH 1998/12/04: I have removed the count register \boundary_char as the reimplementation of the left and right boundaries have drastically decreased the need to check which slot serves as the right boundary. Instead the integer %boundarychar (whose name cannot normally be typed) is used to store the number of this slot, but the user need never (and should not) access this integer directly. If the integer is not set then no slot serves as boundarychar.

\side_bearings \curr_bearings These two dimens are used by the letterspacing mechanism.

1200 \newdimen\side_bearings
1201 \newdimen\curr_bearings
\make_header
1202 \def\make_header#1{
1203 \global\font_count=0
1204 \setdim{designsize}{10pt}
1205 \scaled_design_size=\dim{designsize}
1206 \out_line{(DESIGNSIZE~\vpl_real\scaled_design_size)}
1207 \out_line{(DESIGNUNITS~\vpl_real\scaled_design_size)}
1208 \x_setstr{codingscheme}{UNKNOWN}
1209 \out_line{(CODINGSCHEME~\str{codingscheme})}

1210 ⟨∗boundaryCompability⟩

1211 \ifisint{boundarychar}\then
1212  \x_setint{\percent_char boundarychar}{\int{boundarychar}}
1213  \immediate\write16{Please~use~\string\setleftboundary\space
1214  and/or~\string\makerightboundary^^J
1215  instead~of~setting~the~boundarychar~integer.}

1216 \fi 1217 ⟨/boundaryCompability⟩

1218 \ifisint{\percent_char boundarychar}\then
1219  \a_count=\int{\percent_char boundarychar}
1220  \out_line{(BOUNDARYCHAR~\vpl_int\a_count)}

1221 \fi

1222 \x_setint{letterspacing}{0}
1223 \afm_convert\side_bearings=\int{letterspacing};
1224 \divide \side_bearings 2
1225 \x_setint{minimumkern}{0}
1226 \minimum_kern=\int{minimumkern}
1227 \out_line{}

1228 }

\make_mapfonts
1229 \def\make_mapfonts#1{
1230 \let\saved_scale\vpl_scale
1231 \let\saved_mapfont\vpl_mapfont
1232 \let\do_slot=\do_mapfont
1233 \pre_second_etx_pass_hook
1234 \inputetx{#1}
1235 \post_second_etx_pass_hook
1236 \out_line{}

1237 }

\do_mapfont  \do_mapfont produces a MAPFONT entry for each font used by glyph \slot_name.
1238 \def\do_mapfont{
1239 \ifisglyph\slot_name\then
1240  \mapfonts\slot_name

1241 \fi 1242 }

The following commands can be used in the ⟨mapfonts⟩ glyph parameter.

\vpl_scale
1243 \def\vpl_scale#1#2{{
1244 \divide \scaled_design_size by 8
1245 \multiply \scaled_design_size by #1
1246 \divide \scaled_design_size by \one_thousand
1247 \multiply \scaled_design_size by 8

1248 #2 1249 }}

\vpl_mapfont
1250 \def\vpl_mapfont#1#2{
1251 \a_dimen=#2
1252 \x_cs\ifx{#1-\the\scaled_design_size}\x_relax
1253  \x_cs\xdef{#1-\the\scaled_design_size}{\the\font_count}
1254  \x_cs\xdef{f-\the\font_count}{#1-\the\scaled_design_size}
1255  \out_line{(MAPFONT~\vpl_int\font_count\space
1256  (FONTNAME~#1)~
1257  (FONTDSIZE~\vpl_real\a_dimen)~
1258  (FONTAT~\vpl_real\scaled_design_size))}
1259  \record_usage{#1}
1260  \global\advance\font_count by 1

1261 \fi 1262 }

\font_count
\next_mapfont
\prev_mapfont

1263 \newcount\font_count
1264 \newcount\next_mapfont
1265 \newcount\prev_mapfont
\make_fontdimens
1266 \def\make_fontdimens#1{
1267 \out_line{(FONTDIMEN}
1268  \ifisint{fontdimen(1)}\then
1269  \a_dimen=\int{fontdimen(1)}pt
1270  \divide\a_dimen by \one_thousand
1271  \out_lline{(PARAMETER~D~1~\vpl_real\a_dimen)}

1272 \fi

1273  \a_count=2
1274  \loop\ifnum\a_count<256
1275  {\ifisint{fontdimen(\the\a_count)}\then
1276  \afm_convert\a_dimen=\int{fontdimen(\the\a_count)};
1277  \out_lline{(PARAMETER~\vpl_int\a_count\space
1278  \vpl_real\a_dimen)}
1279  \fi}
1280  \advance\a_count by 1 \repeat
1281 \out_lline{)}
1282 \out_line{}

1283 }

12.4 The ligtable

\make_ligtable
1284 \def\make_ligtable#1{
1285 \bgroup
1286  \out_line{(LIGTABLE}

1287 ⟨!boundaryCompability⟩ \let\do_slot=\bgroup 1288 ⟨∗boundaryCompability⟩

1289  \def\do_slot{\bgroup
1290  \ifisint{boundarychar}\then
1291  \ifnum \int{boundarychar}=\slot_number
1292  \def\vpl_liglabel{\out_liglabel\boundary_liglabel}

1293 \fi 1294 \fi 1295 } 1296 ⟨/boundaryCompability⟩

1297  \let\end_do_slot=\vpl_kerning
1298  \def\do_boundary{\bgroup \let\vpl_liglabel=\boundary_liglabel}
1299  \let\endsetleftboundary=\vpl_kerning
1300  \let\ligature=\vpl_ligature
1301  \let\k=\vpl_kern
1302  \let\rbserver_do=\vpl_rbserver_do
1303  \let\rboundary_do=\vpl_rboundary_do
1304  \pre_third_etx_pass_hook
1305  \inputetx{#1}
1306  \post_third_etx_pass_hook
1307  \out_lline{)}
1308 \egroup

1309 \out_line{}

1310 }

\vpl_rbserver_do \vpl_rboundary_do \wrn_rboundary_do  \vpl_rbserver_do and \vpl_rboundary_do are what \rbserver_do and \rboundary_do

respectively are when a ligkern program is being written and no entry has yet been written for the boundarychar slot. \wrn_rboundary_do is what one of them will get set to afterwards, so that warnings are written when collisions between using the slot as a right boundary marker and using the slot for the actual glyph occur.

1311 \def\vpl_rbserver_do#1{
1312 \do{#1}
1313 \let\rboundary_do=\wrn_rboundary_do

1314 }

1315 \def\vpl_rboundary_do#1{
1316 \do{#1}
1317 \let\rbserver_do=\wrn_rboundary_do

1318 }

1319 \def\wrn_rboundary_do#1{
1320 \do{#1}
1321 \immediate\write16{Boundarychar~slot~usage~collision~in~
1322  `\slot_name'~ligkern~program.}

1323 }

\vpl_ligature \vpl_ligature{⟨type⟩}{⟨glyph⟩}{⟨glyph⟩} produces a ligtable entry for glyph

  \slot_name.

The double spaces in the \out_lline statement below might look strange, but \number will always gobble the first one.

1324 \def\vpl_ligature#1#2#3{
1325 \get_slot_num{#3}
1326 \ifnum -1=\result
1327  \immediate\write16{Warning:~\string\ligature\space
1328  for~unknown~slot~`#3'.}
1329 \else
1330  \x_cs\ifx{slots-#2}\x_relax
1331  \immediate\write16{Warning:~\string\ligature\space
1332  for~unknown~slot~`#2'.}
1333  \else
1334  \def\do##1{
1335  \vpl_liglabel
1336  \out_lline{(#1~D~\number`##1~\space\vpl_int\result)~
1337  (COMMENT~#2~#3)}

1338 }

1339  \csname slots-#2\endcsname

1340 \fi 1341 \fi 1342 }

\vpl_kerning \vpl_kerning writes out kerning instructions.

1343 \def\vpl_kerning{
1344 \let\do=\vpl_kern_do
1345 \csname~r-\slot_name\endcsname
1346 \vpl_ligstop
1347 \egroup

1348 }

\vpl_kern \vpl_kern\l-⟨name⟩ \⟨amount⟩ writes out a KRN instruction.

\vpl_kern has been modified so that at most one KRN instruction is written for each (ordered) pair of characters. The idea is basically to make fontinst forget, until the end of \vpl_kerning, that the glyph for which \vpl_kern is being called has been assigned a slot, as this stops any more KRN instructions for that particular glyph from being written. \vpl_kern has also been modified so that it will not write out any KRN instructions for kerns whose absolute value is less than or equal to \minimum_kern. \minimum_kern gets set to the value of the integer

minimumkern in \make_header. If the user has not set minimumkern, a default

value of 0 will be supplied by fontinst.

1349 \def\vpl_kern#1#2{
1350 \edef\a_macro{\expandafter\gobble_three\string#1}
1351 \a_count=\expandafter\gobble_one\string#2\x_relax
1352 \ifnum -\a_count>\a_count
1353  \a_count=-\a_count

1354 \fi

1355 \ifnum \a_count>\minimum_kern
1356  \afm_convert\a_dimen=\expandafter\gobble_one\string#2;
1357  \csname slots-\a_macro\endcsname

1358 \fi

1359 \x_cs\let{slots-\a_macro}=\x_relax

1360 }

Observation (LH 1999/03/16): The above construction has the side-effect that a direct contradiction between a right boundary glyph and a glyph in the %boundarychar slot won’t be detected if one of the items in contradiction is a kern less than or equal to \minimum_kern. Perhaps this should be changed (letting \do equal to \gobble_one would let the dectection mechanism work, but \do would have to be restored afterwards and it is doubtful if it is worth it).

\vpl_kern_do \vpl_kern_do is what \do is defined to be when kerns are written.

1361 \def\vpl_kern_do#1{
1362 \vpl_liglabel
1363 \out_lline{
1364  (KRN~D~\number`#1~\space\vpl_real\a_dimen)~
1365  (COMMENT~\a_macro)

1366 } 1367 }

\out_liglabel \boundary_liglabel \vpl_liglabel  \out_liglabel writes out a LIGLABEL instruction for a slot. \boundary_liglabel

writes out a LIGLABEL instruction for the BOUNDARYCHAR ligkern program. \vpl_liglabel writes out the correct LIGLABEL instruction for the current ligkern program, if it is approriate.

1368 \def\out_liglabel{
1369 \out_lline{(LABEL~\vpl_int\slot_number)~(COMMENT~\slot_name)}
1370 \let\vpl_liglabel=\x_relax
1371 \let\vpl_ligstop=\out_ligstop

1372 }

1373 \def\boundary_liglabel{
1374 \out_lline{(LABEL~BOUNDARYCHAR)~(COMMENT~\slot_name)}
1375 \let\vpl_liglabel=\x_relax
1376 \let\vpl_ligstop=\out_ligstop

1378 \let\vpl_liglabel=\out_liglabel
\out_ligstop \vpl_ligstop  \vpl_ligstop writes out a LIGSTOP instruction if appropriate.
1379 \def\out_ligstop{\out_lline{(STOP)}
1380 \let\vpl_liglabel=\out_liglabel
1381 \let\vpl_ligstop=\x_relax}
1382 \let\vpl_ligstop=\x_relax

12.5 The characters

\make_characters
1383 \def\make_characters#1{
1384 \bgroup
1385  \let\do_slot=\do_character
1386  \let\end_do_slot=\end_do_character
1387  \let\nextlarger=\vpl_nextlarger
1388  \let\varchar=\vpl_varchar
1389  \let\endvarchar=\end_vpl_varchar
1390  \let\vartop=\vpl_vartop
1391  \let\varmid=\vpl_varmid
1392  \let\varbot=\vpl_varbot
1393  \let\varrep=\vpl_varrep
1394  \if_including_map_
1395  \let\saved_raw\vpl_raw
1396  \let\saved_rule\vpl_rule
1397  \let\saved_special\vpl_special
1398  \let\saved_warning\vpl_warning
1399  \let\saved_movert\vpl_movert
1400  \let\saved_moveup\vpl_moveup
1401  \let\saved_push\vpl_push
1402  \let\saved_pop\vpl_pop
1403  \else
1404  \let\do_character_map\x_relax

1405 \fi

1406  \pre_fourth_etx_pass_hook
1407  \inputetx{#1}
1408  \post_fourth_etx_pass_hook
1409 \egroup

1410 }

\do_character  \do_character produces a character entry for glyph \slot_name in slot \slot_number.
1411 \def\do_character{
1412 \x_cs\ifx{g-\slot_name}\x_relax
1413  \expandafter\gobble_setslot
1414 \else
1415  \ifx\slot_name\notdef_name\else
1416  \out_line{(CHARACTER~\vpl_int\slot_number\space
1417  (COMMENT~\slot_name)}
1418  \afm_convert\a_dimen=\width\slot_name;
1419  \do_character_sidebearings
1420  \out_lline{(CHARWD~\vpl_real\a_dimen)}
1421  \afm_convert\a_dimen=\height\slot_name;

1422  \out_lline{(CHARHT~\vpl_real\a_dimen)}
1423  \afm_convert\a_dimen=\depth\slot_name;
1424  \out_lline{(CHARDP~\vpl_real\a_dimen)}
1425  \afm_convert\a_dimen=\italic\slot_name;
1426  \ifnum\a_dimen>0
1427  \out_lline{(CHARIC~\vpl_real\a_dimen)}

1428 \fi

1429  \do_character_map

1430 \fi 1431 \fi 1432 }

\do_character_sidebearings
1433 \def\do_character_sidebearings{
1434 \ifisint{\slot_name-spacing}\then
1435  \afm_convert\curr_bearings=\int{\slot_name-spacing};
1436  \divide\curr_bearings by 2
1437 \else
1438  \curr_bearings=\side_bearings

1439 \fi

1440 \afm_convert\a_dimen=\width\slot_name;
1441 \advance\a_dimen by 2\curr_bearings

1442 }

\do_character_map
1443 \def\do_character_map{
1444 \global\prev_mapfont=0 \out_lline{(MAP}
1445  \ifdim 0pt=\curr_bearings
1446  \mapcommands\slot_name
1447  \else
1448  \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
1449  \mapcommands\slot_name
1450  \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}

1451 \fi

1452 \out_llline{)}

1453 }

\do_character_no_letterspacing LH 1999/03/27: This is an alternative version of \do_character which I think is now antiquated. It used to have an advantage over \do_character in that it did not do any letterspacing (in v 1.5, that was good since \do_character used to write code for letterspacing to the VPL regardless of whether is was needed or not), but that advantage is gone now since \do_character_map is a bit less stupid now than it used to be.

For the record, I don’t think there ever was a user interface for using this macro instead of \do_character, but I suspect there are plenty of people around who have hacked it into being used.

1454 ⟨∗obsolete⟩

1455 \def\do_character_no_letterspacing{
1456 \x_cs\ifx{g-\slot_name}\x_relax
1457  \expandafter\gobble_setslot
1458 \else
1459  \ifx\slot_name\notdef_name\else
1460  \out_line{(CHARACTER~\vpl_int\slot_number\space

1461  (COMMENT~\slot_name)}
1462  \afm_convert\a_dimen=\width\slot_name;
1463  \out_lline{(CHARWD~\vpl_real\a_dimen)}
1464  \afm_convert\a_dimen=\height\slot_name;
1465  \out_lline{(CHARHT~\vpl_real\a_dimen)}
1466  \afm_convert\a_dimen=\depth\slot_name;
1467  \out_lline{(CHARDP~\vpl_real\a_dimen)}
1468  \afm_convert\a_dimen=\italic\slot_name;
1469  \ifnum\a_dimen>0 \out_lline{(CHARIC~\vpl_real\a_dimen)} \fi
1470  \global\prev_mapfont=0 \out_lline{(MAP}
1471  \mapcommands\slot_name
1472  \out_llline{)}

1473 \fi 1474 \fi 1475 } 1476 ⟨/obsolete⟩

\gobble_setslot
1477 \long\def\gobble_setslot#1\endsetslot{\endsetslot}
\end_do_character
1478 \def\end_do_character{
1479 \ifisglyph\slot_name\then
1480  \out_lline{)}

1481 \fi 1482 }

\notdef_name
1483 \def\notdef_name{.notdef}

12.6 Slot commands that put things in a character property list

Here follows the active definitions for those slot commands that causes things to be put in CHARACTER property lists.

\vpl_nextlarger  \vpl_nextlarger{⟨name⟩} produces a NEXTLARGER entry.
1484 \def\vpl_nextlarger#1{
1485 \get_slot_num{#1}
1486 \ifnum -1<\result
1487  \out_lline{(NEXTLARGER~D~\the\result)~(COMMENT~#1)}
1488 \else
1489  \immediate\write16{Warning:~\string\nextlarger\space
1490  for~unknown~slot~`#1'}

1491 \fi 1492 }

\vpl_varchar \end_vpl_varchar  \vpl_varchar ⟨varchar commands⟩ \end_vpl_varchar produces a VARCHAR entry.
1493 \def\vpl_varchar{\out_lline{(VARCHAR}}
1494 \def\end_vpl_varchar{\out_llline{)}}

\vpl_vartop
1495 \def\vpl_vartop#1{
1496 \get_slot_num{#1}
1497 \ifnum -1<\result
1498  \out_llline{(TOP~D~\the\result)~(COMMENT~#1)}
1499 \else
1500  \immediate\write16{Warning:~\string\vartop\space
1501  for~unknown~slot~`#1'}

1502 \fi 1503 }

\vpl_varmid
1504 \def\vpl_varmid#1{
1505 \get_slot_num{#1}
1506 \ifnum -1<\result
1507  \out_llline{(MID~D~\the\result)~(COMMENT~#1)}
1508 \else
1509  \immediate\write16{Warning:~\string\varmid\space
1510  for~unknown~slot~`#1'}

1511 \fi 1512 }

\vpl_varbot
1513 \def\vpl_varbot#1{
1514 \get_slot_num{#1}
1515 \ifnum -1<\result
1516  \out_llline{(BOT~D~\the\result)~(COMMENT~#1)}
1517 \else
1518  \immediate\write16{Warning:~\string\varbot\space
1519  for~unknown~slot~`#1'}

1520 \fi 1521 }

\vpl_varrep
1522 \def\vpl_varrep#1{
1523 \get_slot_num{#1}
1524 \ifnum -1<\result
1525  \out_llline{(REP~D~\the\result)~(COMMENT~#1)}
1526 \else
1527  \immediate\write16{Warning:~\string\varrep\space
1528  for~unknown~slot~`#1'}

1529 \fi 1530 }

12.7 Saved map commands

The following commands (and \vpl_scale, which is defined above) can be used in the ⟨mapcommands⟩ glyph parameter.

\vpl_raw
1531 \def\vpl_raw#1#2#3{
1532 \global\next_mapfont=\csname#1-\the\scaled_design_size\endcsname
1533 \x_relax

1534 \ifnum\next_mapfont=\prev_mapfont\else
1535  \out_llline{(SELECTFONT~\vpl_int\next_mapfont)~
1536  (COMMENT~#1~at~\the\scaled_design_size)}

1537 \fi

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

1540 }

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

1545 }

\vpl_special
\vpl_warning
1546 \def\vpl_special#1{
1547 \out_llline{(SPECIAL~#1)}}
1548 \def\vpl_warning#1{
1549 \out_llline{(SPECIAL~Warning:~#1)}
1550 \immediate\write16{Warning:~#1.}

1551 }

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

1555 }

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

1559 }

\vpl_push \vpl_pop
1560 \def\vpl_push{\out_llline{(PUSH)}}
1561 \def\vpl_pop{\out_llline{(POP)}}

12.8 Tidying up

\make_tidy The only tidying up (currently) needed is to clear the list of mapfont numbers, since that is stored globally.

1562 \def\make_tidy#1{
1563 \tidying_up_hook
1564 \if_including_map_
1565  \a_count=0\loop\ifnum\a_count<\font_count
1566  \edef\a_macro{\csname~f-\the\a_count\endcsname}
1567  \global\x_cs\let\a_macro\x_relax
1568  \advance\a_count by 1
1569  \repeat
1570  \global\font_count=0

1571 \fi 1572 }

13 Font installation commands and .fd files

\installfonts The call
\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-commmands⟩} \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.

1573 \newtoks\family_toks
1574 \def\installfonts{
1575 \bgroup
1576 \global\family_toks={}
1577 \gdef\prev_file_list{}

1578 }

\installfamily  \installfamily{⟨encoding⟩}{⟨family⟩}{⟨FD-commmands⟩}

Adds the command

\fd_family{⟨encoding⟩}{⟨family⟩}{⟨FD-commmands⟩}

\ENCODING-FAMILY to the token list \family_toks and defines a macro \⟨encoding⟩-⟨family⟩.

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

1583 }

\installfont \installrawfont  \installfont{⟨font-name⟩}{⟨file-list⟩}{⟨etx⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩} \installrawfont{⟨font-name⟩}{⟨file-list⟩}{⟨etx⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩}

1584 \def\installfont#1#2#3#4#5#6#7#8{
1585 \install_font{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{\etxtovpl}

1586 }

1587 \def\installrawfont#1#2#3#4#5#6#7#8{
1588 \record_usage{#1}
1589 \install_font{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{\etxtopl}

1590 }

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

1591 \def\install_font#1#2#3#4#5#6#7#8#9{
1592 \xdef\curr_file_list{#2}
1593 \ifx\prev_file_list\curr_file_list\else
1594  \egroup\bgroup
1595  \expandafter\process_csep_list \expandafter\input_mtx_file
1596  \curr_file_list,\process_csep_list,
1597  \global\let\prev_file_list=\curr_file_list

1598 \fi

1599 #9{#3}{#1}
1600 \x_cs\ifx{#4-#5-#6-#7}\x_relax
1601  \let\do_shape=\x_relax
1602  \x_cs\xdef{#4-#5}{
1603  \x_cs\ifx{#4-#5}\x_relax\else
1604  \csname#4-#5\endcsname

1605 \fi

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

1607 } 1608 \fi

1609 \let\do_size=\x_relax
1610 \x_cs\xdef{#4-#5-#6-#7}{
1611  \x_cs\ifx{#4-#5-#6-#7}\x_relax\else
1612  \csname#4-#5-#6-#7\endcsname

1613 \fi

1614  \do_size{#8}{#1}

1615 } 1616 }

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

1617 \def\endinstallfonts{
1618 \let\do_shape=\fd_shape
1619 \let\do_size=\fd_size
1620 \the\family_toks
1621 \global\family_toks{}
1622 \egroup

1623 }

\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, .afm, or .vpl file in the call to \fromany.

1624 \def\input_mtx_file#1{
1625 \ifx\x_relax#1\x_relax\else
1626  \get_file_name #1~scaled~1000~;

1627  \fromany\file_name
1628  \ifisstr{transform-source}\then
1629  \inputmtx\file_name

1630 \fi 1631 \fi 1632 }

\get_file_name The macro \get_file_name is expanded in the following context

      \get_file_name ⟨filename⟩␣scaled␣⟨scale⟩␣⟨junk⟩;
1633 \def\get_file_name #1~scaled~#2~#3;{
1634 \edef\file_name{#1}
1635 \ifnum#2=\one_thousand
1636  \unsetint{rawscale}
1637 \else
1638  \x_resetint{rawscale}{#2}

1639 \fi 1640 }

13.1 Writing font definition files

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

1641 \def\fd_family#1#2#3{
1642 \a_toks{#3}
1643 \edef\lowercase_file{\lowercase{
1644  \edef\noexpand\lowercase_file{#1#2.fd}}}
1645 \lowercase_file
1646 \open_out{\lowercase_file}
1647 \out_line{\percent_char~Filename:~\lowercase_file}
1648 \out_line{\percent_char~Created~by:~tex~\jobname}
1649 \out_line{\percent_char~Created~using~fontinst~v\fontinstversion}
1650 \out_line{}
1651 \out_line{\percent_char~THIS~FILE~SHOULD~BE~PUT~IN~A~TEX~INPUTS~
1652  DIRECTORY}
1653 \out_line{}
1654 \out_line{\string\ProvidesFile{\lowercase_file}}
1655 \out_lline{[
1656  \the\year/
1657  \ifnum10>\month0\fi\the\month/
1658  \ifnum10>\day0\fi\the\day\space
1659  Fontinst~v\fontinstversion\space
1660  font~definitions~for~#1/#2.

1661 ]}

1662 \out_line{}
1663 \out_line{\string\DeclareFontFamily{#1}{#2}{\the\a_toks}}

1664 {

1665  \csname #1-#2\endcsname
1666  \out_line{}
1667  \let\do_shape=\substitute_shape
1668  \csname #1-#2\endcsname
1669  \let\do_shape=\remove_shape

1670  \csname #1-#2\endcsname

1671 }

1672 \x_cs\g_let{#1-#2}\x_relax
1673 \out_line{}
1674 \out_line{\string\endinput}
1675 \close_out{Font~definitions}

1676 }

\fd_shape  \fd_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1677 \def\fd_shape#1#2#3#4{
1678 \out_line{}
1679 \out_line{\string\DeclareFontShape{#1}{#2}{#3}{#4}\left_brace_char}
1680 \csname #1-#2-#3-#4\endcsname
1681 \x_cs\g_let{#1-#2-#3-#4}\empty_command
1682 \out_line{\right_brace_char{}}

1683 }

\fd_size  \fd_size{SIZE}{FONT-NAME}
1684 \def\fd_size#1#2{
1685 \x_cs\ifx{siz-#1}\x_relax
1686  \out_lline{#1~#2}
1687 \else
1688  \out_lline{\csname siz-#1\endcsname\space #2}

1689 \fi 1690 }

\remove_shape  \remove_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1691 \def\remove_shape#1#2#3#4{
1692 \x_cs\g_let{#1-#2-#3-#4}\x_relax

1693 }

\substitute_shape  \substitute_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1694 \def\substitute_shape#1#2#3#4{
1695 \edef\orig_shape{#4}
1696 \substitute_series{#1}{#2}{#3}{\orig_shape}
1697 \x_cs\ifx{sub-\orig_shape}\x_relax\else
1698  \edef\subst_shape{\csname sub-\orig_shape\endcsname}
1699  \x_cs\ifx{#1-#2-#3-\subst_shape}\x_relax
1700  \out_line{
1701  \string\DeclareFontShape{#1}{#2}{#3}{\subst_shape}{
1702  <->\csname typ-\orig_shape\endcsname\space
1703  *~#2/#3/\orig_shape

1704 }{} 1705 }

1706  \x_cs\let{#1-#2-#3-\subst_shape}\empty_command
1707  \substitute_shape{#1}{#2}{#3}{\subst_shape}

1708 \fi 1709 \fi 1710 }

\substitute_series  \substitute_series{ENCODING}{FAMILY}{SERIES}{SHAPE}
1711 \def\substitute_series#1#2#3#4{
1712 \edef\orig_series{#3}

1713 \x_cs\ifx{sub-\orig_series}\x_relax\else
1714  \edef\subst_series{\csname sub-\orig_series\endcsname}
1715  \x_cs\ifx{#1-#2-\subst_series-#4}\x_relax
1716  \out_line{
1717  \string\DeclareFontShape{#1}{#2}{\subst_series}{#4}{
1718  <->\csname typ-\orig_series\endcsname\space
1719  *~#2/\orig_series/#4

1720 }{} 1721 }

1722  \x_cs\let{#1-#2-\subst_series-#4}\empty_command
1723  \substitute_series{#1}{#2}{\subst_series}{#4}

1724 \fi 1725 \fi 1726 }

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

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

1730 }

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

1734 }

1735 \substitutesilent{bx}{b}
1736 \substitutesilent{b}{bx}
1737 \substitutesilent{b}{sb}
1738 \substitutesilent{b}{db}
1739 \substitutesilent{m}{mb}
1740 \substitutesilent{m}{l}
1741 \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)

1742 \substitutesilent{sl}{it}
1743 \substitutesilent{it}{sl}

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

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

Old TEX text font encodings.

1745 \declareencoding{TEX~TEXT}{OT1}
1746 \declareencoding{TEX~TEXT~WITHOUT~F-LIGATURES}{OT1}
1747 \declareencoding{TEX~TYPEWRITER~TEXT}{OT1TT}

Old TEX math font encodings.

1748 \declareencoding{TEX~MATH~ITALIC}{OML}
1749 \declareencoding{TEX~MATH~SYMBOLS}{OMS}
1750 \declareencoding{TEX~MATH~EXTENSION}{OMX}
1751 \declareencoding{LATEX~SYMBOLS}{lasy}

Euler math font encodings.

1752 \declareencoding{TEX~TEXT~SUBSET}{eufrak}
1753 \declareencoding{TEX~MATH~ITALIC~SUBSET}{eurm}
1754 \declareencoding{TEX~MATH~SYMBOLS~SUBSET}{euscr}
1755 \declareencoding{EULER~SUBSTITUTIONS~ONLY}{euex}

New TEX text font encodings.

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

Rencoded PostScript font encdings.

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

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

1761 \declaresize{}{<->}
1762 \declaresize{5}{<5>}
1763 \declaresize{6}{<6>}
1764 \declaresize{7}{<7>}
1765 \declaresize{8}{<8>}
1766 \declaresize{9}{<9>}
1767 \declaresize{10}{<10>}
1768 \declaresize{11}{<10.95>}
1769 \declaresize{12}{<12>}
1770 \declaresize{14}{<14.4>}
1771 \declaresize{17}{<17.28>}
1772 \declaresize{20}{<20.74>}
1773 \declaresize{25}{<24.88>}

14 Debugging

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

1774 \def\NOFILES{
1775 \def\transformfont##1##2{
1776  \touch_file{##1.mtx}
1777  \touch_file{##1.pl}

1778 }

1779 \def\installfonts{}
1780 \def\endinstallfonts{}
1781 \def\installfont##1##2##3##4##5##6##7##8{%
1782  \touch_file{##1.vpl}

1783 }

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

1786 }

1787 \def\installfamily##1##2##3{
1788  \touch_file{##1##2.fd}

1789 } 1790 }

\touch_file
1791 \def\touch_file#1{
1792 \edef\lowercase_file{\lowercase{
1793  \edef\noexpand\lowercase_file{#1}}}
1794 \lowercase_file
1795 \open_out{\lowercase_file}
1796 \out_line{\percent_char~TEST~FILE.}
1797 \out_line{\percent_char~Created~whilst~debugging~fontinst.}
1798 \close_out{Test~file}

1799 } 1800 ⟨/pkg⟩

    Set \newlinechar for \errhelp messages.

1801 ⟨∗pkg | misc⟩

1802 \newlinechar=`\^^J

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

1803 \errorcontextlines=999

1804 ⟨/pkg | misc⟩

File c

ficonv.dtx

15 Basic file format conversions

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

1 ⟨∗misc⟩

 2 \newif\ifmissingslots
 3 \x_cs\def{o-.notdef}#1{\global\missingslotstrue}
\enctoext
 4 {
 5 \catcode`\/=\active
 6 \catcode`\]=\active
 7 \gdef\enctoetx#1#2{{
 8  \catcode`\/=\active
 9  \catcode`\]=\active
10  \def/##1[{
11  \a_count=0
12  \global\missingslotsfalse
13  \def/####1~{
14  \csname~o-####1\endcsname{
15  \ifmissingslots
16  \out_line{\string\nextslot{\the\a_count}}
17  \fi
18  \global\missingslotsfalse
19  \out_line{\string\setslot{####1}}
20  \out_line{\string\endsetslot}
21  \out_line{}

22 }

23  \advance\a_count by 1

24 } 25 }

26  \def]~def{}
27  \make_etx{#1}{#2}
28 }}

29 }

   \make_etx finishes the job of \enctoext.
30 \def\make_etx#1#2{
31 \open_out{\temp_prefix#2.etx}
32 \out_line{\percent_char~Filename:~#2.etx}
33 \out_line{\percent_char~Created~by:~tex~\jobname}

34 \out_line{\percent_char~Created~using:~\string\enctoetx{#1}{#2}}
35 \out_line{}
36 \out_line{\percent_char~This~file~contains~the
37  information~of~#1.enc~in~a~form}
38 \out_line{\percent_char~more~easily~read~by~TeX.
39  It~is~used~by~the~fontinst~package.}
40 \out_line{}
41 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
42 \out_line{}
43 \out_line{\string\relax}
44 \out_line{}
45 \out_line{\string\documentclass[twocolumn]{article}}
46 \out_line{\string\usepackage{fontdoc}}
47 \out_line{}
48 \out_line{\string\begin{document}}
49 \out_line{}
50 \out_line{This~document~describes~the~#1~encoding.}
51 \out_line{It~was~automatically~generated~by~the}
52 \out_line{{\string\tt\space~fontinst}~package.}
53 \out_line{}
54 \out_line{\string\encoding}
55 \out_line{}
56 \out_line{\string\needsfontinstversion{\fontinstversion}}
57 \out_line{}
58 \primitiveinput #1.enc\x_relax
59 \out_line{}
60 \out_line{\string\end encoding}
61 \out_line{}
62 \out_line{\string\end{document}}
63 \close_out{Encoding~vector}

64 } 65 ⟨/misc⟩

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

66 ⟨∗pkg⟩

67 \def\afmtomtx#1#2{{
68 \open_out{\temp_prefix#2.mtx}
69 \def\raw_font_name{#2}
70 \x_resetint{italicslant}{0}
71 \let\italcorr_expression=\uprightitalcorr
72 \x_setint{minimumkern}{0}
73 \minimum_kern=\int{minimumkern}
74 \global\let\afm_font_name=\empty_command
75 \out_line{\percent_char~Filename:~#2.mtx}
76 \out_line{\percent_char~Created~by:~tex~\jobname}
77 \out_line{\percent_char~Created~using:~\string\afmtomtx{#1}{#2}}

78 \out_line{}
79 \out_line{\percent_char~This~file~contains~the
80  information~of~#1.afm~in~a~form}
81 \out_line{\percent_char~more~easily~read~by~TeX.~
82  It~is~used~by~the~fontinst~package.}
83 \out_line{}
84 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
85 \out_line{}
86 \out_line{\string\relax}
87 \out_line{\string\metrics}
88 \out_line{}
89 \out_line{\string\needsfontinstversion{\fontinstversion}}
90 \out_line{}
91 \catcode`\^^M=12
92 \catcode`\ =10
93 \expandafter\afm_line\primitiveinput #1.afm\x_relax
94 \out_line{}
95 \out_line{\endmetrics_text}
96 \close_out{Metrics}
97 }}

Kerns below this value are ignored.

98 \newcount\minimum_kern

\afm_length \afm_unit_dimen The call \afm_length⟨count⟩{⟨real⟩} interprets the ⟨real⟩ as a real number, rounds it to the nearest integer, and sets the ⟨count⟩ (a \count register) to that integer. In this process, \a_dimen is used as a temporary storage.

99 \def\afm_length#1#2{
100 \a_dimen=#2\afm_unit_dimen
101 #1=\a_dimen
102 \divide #1 by \afm_unit_dimen
103 \advance \a_dimen by -#1\afm_unit_dimen
104 \ifdim \a_dimen>0.5\afm_unit_dimen
105  \advance #1 by 1
106 \else \ifdim \a_dimen<-0.5\afm_unit_dimen
107  \advance #1 by -1
108 \fi\fi
109 \x_relax

110 }

The dimen \afm_unit_dimen is used to keep track of how long an AFM unit is interpreted as being in this routine. Lowering its value makes \afm_length capable of handling greater lengths but looses some very slight precision in the rounding, increasing the value has the opposite effects. The current value of 1000 sp means it reads lengths with three decimals accuracy (not very much use for them though as the number is rounded to zero decimals accuracy anyway, but it does make a difference when deciding how a ⟨real⟩ like 0.502 should be rounded) and can handle lengths of an absolute value of a good million AFM units. This should be adequate in most cases. It is, by the way, probably wisest to keep it a power of ten scaled points in all cases, as this should reduce the rounding errors caused by various base conversions.

111 \newdimen\afm_unit_dimen
112 \afm_unit_dimen=1000sp

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

113 {\catcode`\^^M=12 \gdef\afm_line#1
114 {\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.

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

This all stops when we reach the command EndFontMetrics.

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

\afm_def To define an AFM command, you say \afm_def{⟨command⟩}(⟨pattern⟩){⟨result⟩}

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

\afm_let Saying \afm_let{⟨dest-command⟩}{⟨source-command⟩} copies the definition of one AFM command to another.

120 \def\afm_let#1#2{
121 \expandafter\let \csname afm-#1\expandafter\endcsname
122  \csname afm-#2\endcsname

123 }

For example, we can define the following AFM commands:

124 \afm_def{CharWidth}(#1){\afm_length\char_x_width{#1}}
125 \afm_def{ItalicAngle}(#1){\calculate_it_slant{#1}}
126 \afm_def{XHeight}(#1){
127 \afm_length\a_count{#1}
128 \out_line{\string\setint{xheight}{\the\a_count}}}
129 \afm_def{CapHeight}(#1){
130 \afm_length\a_count{#1}
131 \out_line{\string\setint{capheight}{\the\a_count}}}
132 \afm_def{Ascender}(#1){
133 \afm_length\a_count{#1}
134 \out_line{\string\setint{ascender}{\the\a_count}}}
135 \afm_def{Descender}(#1){
136 \afm_length\a_count{#1}
137 \out_line{\string\setint{descender_neg}{\the\a_count}}}
138 \afm_def{UnderlineThickness}(#1){
139 \afm_length\a_count{#1}
140 \out_line{\string\setint{underlinethickness}{\the\a_count}}}
141 \afm_def{FontBBox}(#1~#2~#3~#4){
142 \afm_length\a_count{#4}
143 \out_line{\string\setint{maxheight}{\the\a_count}}
144 \afm_length\a_count{#2}
145 \out_line{\string\setint{maxdepth_neg}{\the\a_count}}}
146 \afm_def{IsFixedPitch}(#1){
147 \if\first_char#1=f
148 \else\out_line{\string\setint{monowidth}{1}}
149 \fi

150 }

\afm_font_name The FontName of a font is recorded in the macro \afm_font_name. This information is of no use when making TFMs and VFs, but it is likely to be of use for generation of map files, so it will be included in a file of recorded transforms, if such a file is being generated.

151 \afm_def{FontName}(#1~){\xdef\afm_font_name{#1}}

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

152 \afm_def{KP}(#1~#2~#3~#4){
153 \if\first_char#1=.\else
154 \if\first_char#2=.\else
155  \afm_length\a_count{#3}
156  \ifnum \a_count>\minimum_kern
157  \out_line{\string\setkern{#1}{#2}{\the\a_count}}
158  \else\ifnum \a_count<-\minimum_kern
159  \out_line{\string\setkern{#1}{#2}{\the\a_count}}
160  \fi\fi
161 \fi\fi

162 }

163 \afm_let{KPX}{KP}

Processing char metrics.

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

Processing composite chars.

166 \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:

167 \newcount\char_slot
168 \newcount\char_x_width
169 \newcount\x_width
170 \newcount\bbox_llx
171 \newcount\bbox_lly
172 \newcount\bbox_urx
173 \newcount\bbox_ury
174 \let\char_name=\empty_command

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

175 \def\init_afm#1{
176 \char_slot=#1\x_relax
177 \x_width=\char_x_width
178 \bbox_llx=0
179 \bbox_lly=0
180 \bbox_urx=0
181 \bbox_ury=0
182 \let\char_name=\empty_command

183 }

184 \def\afm_char{
185 \a_count=-\bbox_lly
186 \eval_expr{
187  \italcorr_expression\x_width\bbox_llx\bbox_urx\bbox_lly\bbox_ury

188 }

189 \out_line{
190  \ifnum -1<\char_slot
191  \string\setrawglyph
192  \else
193  \string\setnotglyph
194  \fi
195  {\char_name}
196  {\raw_font_name}
197  {10pt}
198  {\the\char_slot}
199  {\the\x_width}
200  {\the\bbox_ury}
201  {\the\a_count}
202  {\the\result}

203 } 204 }

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

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

208 }

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

212 }

\italcorr_expression The way the italic correction is computed has been changed quite a bit, although the computed values are still the same. The point is that it is much simpler to modify the formula according to which the value is computed using this method than using the previous method.

The call

\italcorr_expression{⟨width⟩}{⟨left⟩}{⟨right⟩}{⟨bottom⟩}{⟨top⟩},

where the arguments are TEX ⟨number⟩s, should expand to an integer expression. The value of that expression will be taken as the italic correction of the current character.

⟨width⟩ is the width of the character. ⟨left⟩, ⟨right⟩, ⟨bottom⟩, and ⟨top⟩ are the respective coordinates of the sides of the bounding box of the character. A quantity which is not given as an argument, but which nontheless might be of interest for a calculation of italic correction, is the italic slant of the font. This quantity can be found in the fontinst integer italicslant. (The MTX file written will also set the integer italicslant to this value.)

\uprightitalcorr \slanteditalcorr These two commands are what \italcorr_expression will get set to—the slanted

version is used if the italic slant is positive and the upright version is used otherwise. The default definitions compute the same values as in fontinst v 1.8, but the definitions can easily be modified using \resetcommand.

213 \def\uprightitalcorr#1#2#3#4#5{0}
214 \def\slanteditalcorr#1#2#3#4#5{\max{\sub{#3}{#1}}{0}}

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.

? \afm_line always inserts a space at the end of the line. Could we therefore save us a bit of trouble by simply changing the pattern for \ItalicAngle to (#1~)? /LH

215 \def\calculate_it_slant#1{
216 \edef\theangle{\strip_spaces#1~\end_strip_spaces}
217 \CalculateTan{\theangle}
218 \a_dimen=-\one_thousand sp
219 \a_dimen=\UseTan{\theangle}\a_dimen
220 \a_count=\a_dimen
221 \out_line{\string\setint{italicslant}{\the\a_count}}
222 \x_resetint{italicslant}{\a_count}
223 \ifnum 0<\a_count
224  \let\italcorr_expression=\slanteditalcorr
225 \else
226  \let\italcorr_expression=\uprightitalcorr
227 \fi

228 }

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

230 \def\do_list[~#1~#2;~#3]{
231 \csname~list-#1\endcsname\gobble_one_semi#2;
232 \ifx\x_relax#3\x_relax\expandafter\gobble_one
233 \else\expandafter\identity_one\fi
234 {\do_list[~#3]}

235 }

236 \def\gobble_one_semi#1;{}

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

237 \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:

238 \list_def{W}(#1~#2){\afm_length\x_width{#1}}
239 \list_def{WX}(#1){\afm_length\x_width{#1}}
240 \list_def{WY}(#1){}
241 \list_def{N}(#1){\def\char_name{#1}}
242 \list_def{B}(#1~#2~#3~#4){
243 \afm_length\bbox_llx{#1}
244 \afm_length\bbox_lly{#2}
245 \afm_length\bbox_urx{#3}
246 \afm_length\bbox_ury{#4}

247 }

248 \list_def{PCC}(#1~#2~#3){
249 \afm_length\a_count{#2}
250 \afm_length\b_count{#3}
251 \out_lline{\string\glyphpcc{#1}{\the\a_count}{\the\b_count}}

252 }

15.3 Converting a PL file to an MTX file

\generalpltomtx The macro

\generalpltomtx{⟨plfile⟩}{⟨mtxfile⟩}{⟨plsuffix⟩}{⟨opt-enc⟩}

reads ⟨plfile⟩.⟨plsuffix⟩, interprets it as having the encoding specified by the file ⟨opt-enc⟩.etx, and writes the same metric information out to ⟨mtxfile⟩.mtx. In case ⟨opt-enc⟩ is empty, the encoding will be determined using the CODINGSCHEME

\pltomtx property of the file being read. The macro

\pltomtx{⟨plfile⟩}{⟨mtxfile⟩}

reads ⟨plfile⟩.pl, uses the CODINGSCHEME property in that file to determine its encoding, and writes the same metric information out to ⟨mtxfile⟩.mtx.

None of these commands can cope with SKIP commands.

\generalpltomtx
253 \def\generalpltomtx#1#2#3#4{{
254 \ifx _#4_\else
255  \def\do_slot{\x_cs\let{name-\the\slot_number}\slot_name}
256  \def\do_boundary{\x_cs\let{name-BOUNDARYCHAR}\slot_name}
257  \inputetx{#4}
258  \let\CODINGSCHEME=\ignore_parens
259 \fi
260 \pl_to_mtx{#1}{#2}{#3}{\string\generalpltomtx{#1}{#2}{#3}{#4}}

261 }}

\pltomtx
262 \def\pltomtx#1#2{\generalpltomtx{#1}{#2}{pl}{}}

\pl_to_mtx The \pl_to_mtx macro contains all code that was common to \pltomtx and \generalpltomtx before the former was redefined to a call of the latter. The structure of a call of \pl_to_mtx is

\pl_to_mtx{⟨plfile⟩}{⟨mtxfile⟩}{⟨plsuffix⟩}{⟨call⟩}

⟨call⟩ is what should be written in the “Created using:” comment at the top of the MTX file written.

263 \def\pl_to_mtx#1#2#3#4{
264 \def\raw_font_name{#1}
265 \open_out{\temp_prefix#2.mtx}
266 \out_line{\percent_char~Filename:~#2.mtx}
267 \out_line{\percent_char~Created~by:~tex~\jobname}
268 \out_line{\percent_char~Created~using:~#4}
269 \out_line{}
270 \out_line{\percent_char~This~file~contains~the~
271  information~of~#1.#3~in~a~form}
272 \out_line{\percent_char~more~easily~read~by~TeX.~
273  It~is~used~by~the~fontinst~package.}
274 \out_line{}
275 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
276 \out_line{}
277 \out_line{\string\relax}

278 \out_line{\string\metrics}
279 \out_line{}
280 \out_line{\string\needsfontinstversion{\fontinstversion}}
281 \out_line{}
282 \catcode`\(=0 \catcode`\)=9
283 \let\/=\ignore_parens
284 \let\do_pl_glyph=\x_relax
285 \primitiveinput #1.#3\x_relax
286 \do_pl_glyph
287 \out_line{}
288 \ifisint{\percent_char boundarychar}\then
289  \f_count=\int{\percent_char boundarychar}
290  \x_cs\ifx{name-\the\f_count}\x_relax \else
291  \out_line{\string\setstr{rightboundary}
292  {\csname name-\the\f_count\endcsname}

293 }

294  \out_line{}
295  \fi
296 \fi
297 \out_line{\endmetrics_text}
298 \close_out{Metrics}

299 }

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.

300 \def\ignore_parens{\bgroup\catcode`(=1 \catcode`)=2 \x_relax
301 \expandafter\expandafter\expandafter\gobble_parens
302  \iftrue\expandafter{\else}\fi}
303 \def\gobble_parens#1{\egroup}

Convert a PL real to an AFM unit, assuming it contains a decimal point. \pl_real only works if the DESIGNUNITS setting is at the default value

A 1. Luckily, this is the case with the Computer Modern fonts (at least the ones I looked at), so it works for those. What is not so luckily is that it fails quite spectacularly for the VPL files fontinst generates itself—usually everything comes out ten times as large as it should be. Is there a reasonable way around this? /LH

304 \def\pl_real#1{\pl_realer(#1000)}
305 \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.

306 \def\pl_int#1#2{
307 \ifx#1C `#2
308 \else\ifx#1D #2
309 \else\ifx#1O '#2
310 \else\ifx#1H "#2
311 \else -1\errmessage{Unknown~PL~number~prefix~`#1'}
312 \fi\fi\fi\fi

313 }

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.

314 \let\COMMENT=\ignore_parens
315 \let\FAMILY=\ignore_parens
316 \let\FACE=\ignore_parens
317 \let\CHECKSUM=\ignore_parens
318 \let\LIG=\ignore_parens
319 \let\NEXTLARGER=\ignore_parens
320 \let\VARCHAR=\ignore_parens

The properties which are unique for VPL files—VTITLE, MAPFONT, MAP,

FONTNAME, FONTAREA, FONTCHECKSUM, FONTAT, FONTDSIZE, SELECTFONT, SETCHAR,
SETRULE, MOVERIGHT, MOVELEFT, MOVEUP, MOVEDOWN, PUSH, POP, SPECIAL, and

SPECIALHEX—should also be ignored, but it is actually sufficient to ignore the first three since the others are only allowed inside MAP or MAPFONT property lists.

321 \let\VTITLE=\ignore_parens
322 \let\MAPFONT=\ignore_parens
323 \let\MAP=\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_encoding defines a macro \enc-⟨codingscheme⟩ which expands to ⟨encoding⟩.

If the PL file is converted using the \generalpltomtx command with a nonempty ⟨opt-enc⟩ argument then the CODINGSCHEME instruction is ignored since an encoding file has already been read in.

324 \def\CODINGSCHEME{\bgroup\catcode`\)=12\x_relax\CODINGSCHEME_cont}
325 \def\CODINGSCHEME_cont#1){
326 \egroup
327 \x_cs\ifx{enc-#1}\x_relax
328  \errhelp{The~encoding~`#1'~has~not~been~declared.^^J
329  You~should~declare~it~with~
330  \string\declareencoding{#1}{ETXFILE}.^^J
331  Press~<RETURN>~to~carry~on~with~fingers~crossed,^^J
332  or~X~<RETURN>~to~exit.}
333  \errmessage{Undeclared~encoding~`#1'}
334 \else
335  \def\do_slot{\x_cs\let{name-\the\slot_number}\slot_name}
336  \def\do_boundary{\x_cs\let{name-BOUNDARYCHAR}\slot_name}
337  \catcode`\(=12 \catcode`\)=12
338  \x_cs\inputetx{enc-#1}\x_relax
339  \catcode`\(=0 \catcode`\)=9
340 \fi

341 }

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

345 }

\DESIGNUNITS The PL to MTX converter assumes that the (V)PL files to convert look like the ones created by TFtoPL/VFtoVP, and the interpretation of the DESIGNUNITS property is one thing specifically affected by this. The TFM file format does not store the DESIGNUNITS value used, so the two above programs always generate (V)PL files with the default setting of design unit equal to the design size. Hence any occurence of the DESIGNUNITS property is an indication of an error.

The incorrect metrics can be corrected by scaling by a suitable amount (1000 divided by the designunits dimen), but it is much simpler to convert the PL to a TFM and then convert it back, that will also fix the units.

346 \def\DESIGNUNITS~#1~#2~{
347 \a_dimen=#2pt
348 \ifdim 1pt=\a_dimen \else
349  \fontinsterror{PL-to-MTX}{Nondefault~unit~used~in~PL~file}
350  {You~may~continue,~but~the~metrics~for~this~font~will~be~wrong.}
351 \fi
352 \out_line{\string\setdim{designunits}{\the\a_dimen}}

353 }

354 \def\BOUNDARYCHAR~#1~#2~{
355 \x_setint{\percent_char boundarychar}{\pl_int{#1}{#2}}

356 }

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

357 \let\FONTDIMEN=\x_relax
358 \def\SLANT~R~#1~{\out_line{\string\setint{italicslant}{\pl_real{#1}}}}
359 \def\SPACE~R~#1~{\out_line{\string\setint{interword}{\pl_real{#1}}}}
360 \def\STRETCH~R~#1~{\out_line{\string\setint{stretchword}{\pl_real{#1}}}}
361 \def\SHRINK~R~#1~{\out_line{\string\setint{shrinkword}{\pl_real{#1}}}}
362 \def\XHEIGHT~R~#1~{\out_line{\string\setint{xheight}{\pl_real{#1}}}}
363 \def\QUAD~R~#1~{\out_line{\string\setint{quad}{\pl_real{#1}}}}
364 \def\EXTRASPACE~R~#1~{
365 \out_line{\string\setint{extraspace}{\pl_real{#1}}}

366 }

367 \def\DEFAULTRULETHICKNESS~R~#1~{
368 \out_line{\string\setint{underlinethickness}{\pl_real{#1}}}

369 }

The following fontdimens are ignored.

370 \def\HEADER~#1~#2~#3~#4~{}
371 \def\SEVENBITSAFEFLAG~#1~{}
372 \def\PARAMETER~#1~#2~#3~#4~{}
373 \def\NUM#1~#2~#3~{}
374 \def\DENOM#1~#2~#3~{}
375 \def\SUP#1~#2~#3~{}
376 \def\SUB#1~#2~#3~{}
377 \def\SUBDROP~#1~#2~{}
378 \def\SUPDROP~#1~#2~{}
379 \def\DELIM#1~#2~#3~{}
380 \def\AXISHEIGHT~#1~#2~{}
381 \def\BIGOPSPACING#1~#2~#3~{}

The following ligtable commands are processed.

382 \def\LIGTABLE{\let\do=\never_do\let\a_macro\empty_command}
383 \def\LABEL~#1{\ifx #1B
384  \expandafter\LABEL_boundarychar
385 \else
386  \expandafter\LABEL_slot \expandafter#1

387 \fi

388 }

389 \def\LABEL_slot #1~#2~{
390 \f_count=\pl_int{#1}{#2}
391 \edef\a_macro{\a_macro
392  \x_cs\do_if_defined{name-\the\f_count}

393 } 394 }

395 \def\LABEL_boundarychar OUNDARYCHAR{
396 \edef\a_macro{\a_macro
397  \x_cs\do_if_defined{name-BOUNDARYCHAR}

398 } 399 }

400 \def\do_if_defined#1{\ifx #1\x_relax \else \do{#1} \fi}
401 \def\STOP{\let\a_macro\empty_command}
402 \def\SKIP~#1~#2~{\immediate\write16{Warning:~SKIP~instruction~ignored.}}
403 \def\KRN~#1~#2~R~#3~{
404 \edef\do{\noexpand\write_pl_krn{\pl_int{#1}{#2}}{\pl_real{#3}}}
405 \a_macro
406 \let\do=\never_do

407 }

408 \def\write_pl_krn#1#2#3{
409 \f_count=#1\x_relax
410 \x_cs\ifx{name-\the\f_count}\x_relax \else
411  \out_line{\string\setkern{#3}
412  {\csname name-\the\f_count\endcsname}{#2}

413 }

414 \fi

415 }

The following character metrics are processed.

416 \def\CHARWD~R~#1~{\b_count=\pl_real{#1}}
417 \def\CHARHT~R~#1~{\c_count=\pl_real{#1}}
418 \def\CHARDP~R~#1~{\d_count=\pl_real{#1}}
419 \def\CHARIC~R~#1~{\e_count=\pl_real{#1}}
420 \def\CHARACTER~#1~#2~{
421 \do_pl_glyph
422 \a_count=\pl_int{#1}{#2}
423 \b_count=0
424 \c_count=0
425 \d_count=0
426 \e_count=0
427 \let\do_pl_glyph=\write_pl_glyph

428 }

429 \def\write_pl_glyph{
430  \x_cs\ifx{name-\the\a_count}\x_relax\else
431  \out_line{\string\setrawglyph
432  {\csname~name-\the\a_count\endcsname}
433  {\raw_font_name}
434  {\the\a_dimen}
435  {\the\a_count}
436  {\the\b_count}
437  {\the\c_count}

438  {\the\d_count}
439  {\the\e_count}}
440  \fi

441 }

15.4 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
442 \def\mtxtopl#1#2{{
443 \open_out{#2.pl}
444 \out_line{(COMMENT~raw~font~#2~created~by~fontinst~
445  v\fontinstversion)}
446 \out_line{}
447 \out_line{(COMMENT~Filename:~#2.pl)}
448 \out_line{(COMMENT~Created~by:~tex~\jobname)}
449 \out_line{(COMMENT~Created~using:~\string\mtxtopl{#1}{#2})}
450 \out_line{}
451 \out_line{(COMMENT~This~file~can~be~turned~into~a~TeX~font~with)}
452 \out_line{(COMMENT~pltotfm~#2.pl~#2.tfm)}
453 \out_line{}
454 \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
455 \out_line{}
456 \out_line{(DESIGNSIZE~R~10.0)}
457 \out_line{(DESIGNUNITS~R~10.0)}
458 \out_line{}
459 \scaled_design_size=10pt
460 \let\setglyph=\iffalse
461 \let\endsetglyph=\fi
462 \let\setkern=\gobble_three
463 \let\setrawglyph=\pl_raw_glyph
464 \inputmtx{#1}
465 \out_line{}
466 \out_line{(COMMENT~END~OF~FILE~#2.pl)}
467 \close_out{Raw~font}

468 }}

\pl_raw_glyph
469 \def\pl_raw_glyph#1#2#3#4#5#6#7#8{
470 \a_count=#4
471 \afm_convert\a_dimen=#5;
472 \afm_convert\b_dimen=#6;
473 \afm_convert\c_dimen=#7;
474 \afm_convert\d_dimen=#8;
475 \out_line{(CHARACTER~\vpl_int\a_count\space(COMMENT~#1)}
476 \out_lline{(CHARWD~\vpl_real\a_dimen)}
477 \out_lline{(CHARHT~\vpl_real\b_dimen)}

478 \out_lline{(CHARDP~\vpl_real\c_dimen)}
479 \out_lline{(CHARIC~\vpl_real\d_dimen)}
480 \out_lline{)}

481 }

16 Font transformations

16.1 Transformable metric files

A transformable metric file is a metric file which complies with certain restrictions in its syntax. The only metric commands allowed are

\setrawglyph{⟨glyph⟩}{⟨font⟩}{⟨size⟩}{⟨slot⟩}{⟨width⟩}{⟨height⟩}

{⟨depth⟩}{⟨italic⟩} \setnotglyph{⟨glyph⟩}{⟨font⟩}{⟨size⟩}{⟨slot⟩}{⟨width⟩}{⟨height⟩}

{⟨depth⟩}{⟨italic⟩} \setkern{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨amount⟩}

     \setglyph{⟨glyph⟩} ⟨glyph commands⟩ \endsetglyph

where ⟨glyph⟩, ⟨glyph1 ⟩, ⟨glyph2 ⟩, and ⟨font⟩ are strings without any variable references (no \str or \strint are allowed), ⟨slot⟩, ⟨width⟩, ⟨height⟩, ⟨depth⟩, ⟨italic⟩, and ⟨amount⟩ are TEX numbers, and ⟨size⟩ is a TEX dimen. (More accurately, all dimens in a transformable metric file should be on the form ⟨optional signs⟩ ⟨decimal constant⟩⟨physical unit⟩, but that’s at the “dangerous bend” level.)

The only ⟨glyph commands⟩ allowed are

     \samesize{⟨glyph⟩}

\glyphpcc{⟨glyph⟩}{⟨xoffset⟩}{⟨yoffset⟩}

where ⟨glyph⟩ is as above, and ⟨xoffset⟩ and ⟨yoffset⟩ are TEX numbers. The only general commands allowed are

\setint{⟨name⟩}{⟨number⟩} \setdim{⟨name⟩}{⟨dimen⟩} \setstr{⟨name⟩}{⟨string⟩}

where ⟨name⟩ and ⟨string⟩ are strings without variable references, ⟨number⟩ is a TEX number, and ⟨dimen⟩ is a TEX dimen.

The metric files produced by \afmtomtx and \generalpltomtx are meant to be transformable. If they are not then there is a bug somewhere.

The name of the integer in \setint commands are intepreted. This name is used to determine how the number should be transformed, see the implementation

of \mtxtomtx_setint below.

16.2 Making font transformations

\transformfont The macro:

\transformfont{⟨font-name⟩}{⟨transformed font⟩}

transforms the metrics of a raw font. As far as TEX is concerned, ⟨font-name⟩ will be a new font. It is up to some other piece of software, in most cases the DVI driver, to implement this transformation and provide the transformed font.

\fromafm The ⟨transformed font⟩ commands are:

\frommtx
\frompl
\scalefont
\xscalefont
\yscalefont
\slantfont
\reencodefont

File c: ficonv.dtx  104

      \fromafm{⟨AFM file⟩}
      \frompl{⟨PL file⟩}
      \fromplgivenetx{⟨PL file⟩}{⟨etx⟩}
      \frommtx{⟨MTX file⟩}
      \fromany{⟨file⟩}

\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, \frompl, or \fromplgivenetx command also generates an

.mtx file for the source font, which is written out by \afmtomtx or \generalpltomtx. In addition, \fromafm also uses \mtxtopl to generate a corresponding raw .pl file.

\fromany reads an MTX, PL, AFM, or VPL file depending on what it can find. It tries them in the order first MTX, then PL, then AFM, and last VPL.

\transformfont
482 \def\transformfont#1#2{{
483 \unsetstr{afm-name}
484 \unsetstr{etx-name}
485 \x_resetint{x-scale}{\one_thousand}
486 \x_resetint{y-scale}{\one_thousand}
487 \x_resetint{slant-scale}{0}

488 #2

489 \ifisstr{transform-source}\then
490  \ifisstr{etx-name}\then
491  \edef\a_macro{\string\reencodefont{\str{etx-name}}}
492  \else
493  \let\a_macro=\empty_command
494  \fi
495  \_a_true
496  \ifnum \int{x-scale}=\one_thousand
497  \ifnum \int{slant-scale}=\z@
498  \ifnum \int{y-scale}=\one_thousand
499  \_a_false
500  \fi \fi \fi
501  \if_a_
502  \edef\a_macro{\a_macro
503  \string\transformfont{\strint{x-scale}}{\strint{slant-scale}}
504  {\strint{y-scale}}

505 }

506  \fi
507  \record_transform{#1}{\str{transform-source}}{\a_macro}
508  \mtxtomtx{\str{afm-name}}{#1}
509  \mtxtopl{#1}{#1}
510 \else
511  \errmessage{Failed~to~transform~font~\str{afm-name};^^J
512  font~metrics~file~not~found.

514 \fi

515 }}

\fromafm
516 \def\fromafm#1{
517 \x_setstr{afm-name}{#1}
518 \afmtomtx{#1}{#1}
519 \resetstr{transform-source}{\string\fromafm{#1}{\afm_font_name}}
520 \record_transform{#1}{\str{transform-source}}{}
521 \mtxtopl{#1}{#1}

522 }

\frommtx
523 \def\frommtx#1{
524 \x_setstr{afm-name}{#1}
525 \resetstr{transform-source}{\string\frommtx{#1}}

526 }

\frompl
\fromplgivenetx
527 \def\frompl#1{
528 \x_setstr{afm-name}{#1}
529 \generalpltomtx{#1}{#1}{pl}{}
530 \resetstr{transform-source}{\string\frompl{#1}}
531 \record_transform{#1}{\string\frompl{#1}}{}

532 }

533 \def\fromplgivenetx#1#2{
534 \x_setstr{afm-name}{#1}
535 \generalpltomtx{#1}{#1}{pl}{#2}
536 \resetstr{transform-source}{\string\frompl{#1}}
537 \record_transform{#1}{\string\frompl{#1}}{}

538 }

\fromvpl \fromvplgivenetx I realized that there isn’t any point in reading metrics for a font that is to be transformed from a VPL file, since no driver I know of can transform virtual fonts. If someone has a problem with this then I suppose he or she should send word about it. /LH

539 % \def\fromvpl#1{
540 %    \x_setstr{afm-name}{#1}
541 %    \generalpltomtx{#1}{#1}{vpl}{}
542 %    \resetstr{transform-source}{\string\frompl{#1}}

543 % }

544 % \def\fromvplgivenetx#1#2{
545 %    \x_setstr{afm-name}{#1}
546 %    \generalpltomtx{#1}{#1}{vpl}{#2}
547 %    \resetstr{transform-source}{\string\frompl{#1}}

548 % }

\fromany The \fromany transformed font command searches for font metrics for #1 by looking for, in turn, the files #1.mtx, #1.pl, #1.afm, and #1.vpl. If an MTX file doesn’t exist, it is generated, and if the MTX is generated from an AFM then a corresponding (non-ligful) PL file is generated as well. \fromany also sets the fontinst string transform-source according to what kind of font it found. If none of the fonts existed then transform-source is unset.

549 \def\fromany#1{
550 \x_setstr{afm-name}{#1}
551 \if_file_exists{#1.mtx}\then
552  \resetstr{transform-source}{\string\frommtx{#1}}
553 \else

1997/01/15 SPQR changed the below search order to .pl before .afm because of the cmr*.afm files found in the TEXMF/fonts/afm hierarchy.

554  \if_file_exists{#1.pl}\then
555  \generalpltomtx{#1}{#1}{pl}{}
556  \resetstr{transform-source}{\string\frompl{#1}}
557  \record_transform{#1}{\string\frompl{#1}}{}
558  \else
559  \if_file_exists{#1.afm}\then
560  \afmtomtx{#1}{#1}
561  \resetstr{transform-source}{
562  \string\fromafm{#1}{\afm_font_name}

563 }

564  \record_transform{#1}{\str{transform-source}}{}
565  \mtxtopl{#1}{#1}
566  \else
567  \if_file_exists{#1.vpl}\then
568  \generalpltomtx{#1}{#1}{vpl}{}
569  \resetstr{transform-source}{\string\fromvpl}
570  \record_transform{#1}{\string\fromvpl}{}
571  \else
572  \unsetstr{transform-source}
573  \fi
574  \fi
575  \fi
576 \fi

577 }

The mathematical basis for the metric font transformations

Mathematically, all the metric font transformations (\scalefont, \xscalefont, \yscalefont, and \slantfont) are linear mappings of the real plane onto itself. All quantities in a transformable metric file are interpreted as being determined by some point in this plane and hence their transformation depends on how that point would be moved by the metric font transformations performed. This is usually simpler than it sounds, since all quantities except italicslant are interpreted as either the x- or the y-coordinate of some point. italicslant is interpreted as the quotient \frac{x}{y} for a point.

The best way to describe a linear mapping of the real plane to itself is by a 2 × 2 matrix whose components are real numbers. Since true real numbers are not available in TEX, integers are used instead, with the convention that they are in units of thousandths. In a concrete form this means that 0 represents 0, 500 represents \frac{1}{2}, 1000 represents 1, etc. This works just as for the scaling factors used in \scale. It also means that the matrix

( \begin{matrix}1000 & 0 \\ 0 & 1000 \end{matrix} )

represents the identity mapping (the mapping taking everything to itself).

Thinking of points as column vectors (2 × 1 matrices) with the x-coordinate in the first component and the y-coordinate in the second, the respective elementary metric font transformations correspond to the following matrices:

\scalefont\{⟨n⟩\} is ( \begin{matrix}⟨n⟩ & 0 \\ 0 & ⟨n⟩ \end{matrix} )
\xscalefont\{⟨n⟩\} is ( \begin{matrix}⟨n⟩ & 0 \\ 0 & 1000 \end{matrix} )
\yscalefont\{⟨n⟩\} is ( \begin{matrix}1000 & 0 \\ 0 & ⟨n⟩ \end{matrix} )
\slantfont\{⟨n⟩\} is ( \begin{matrix}1000 & ⟨n⟩ \\ 0 & 1000 \end{matrix} )

Since all these matrices are upper triangular, all products of such matrices (corresponding to compositions of the linear mappings) will be upper triangular as well. It is therefore unnecessary to store the subdiagonal component anywhere (it is always zero), and hence fontinst represents an arbitrary metric transform by the matrix

                      ( \begin{matrix}x-scale & slant-scale \\ 0 & y-scale \end{matrix} )

where x-scale, y-scale, and slant-scale are fontinst integers.

The reason there is a representation of arbitrary metric transforms is that all the elementary metric transforms listed in the second argument of \transformfont are concatenated before the actual font file conversion is made. This reduces the amount of calculations performed in case there are many transformations of the font.

Why do we only consider transformations that correspond to upper triangular matrices? Well, a transformation corresponds to an upper triangular matrix if and only if it leaves horizontal lines horizontal. Since in particular the baseline must always be horizontal in TEX, there is no point in considering other linear transformations.

\scalefont
\xscalefont
\yscalefont
\slantfont
\reencodefont

578 \def\scalefont#1#2{
579 \eval_expr_to\d_count{#1}
580 \x_resetint{x-scale}{\scale{\d_count}{\int{x-scale}}}
581 \x_resetint{y-scale}{\scale{\d_count}{\int{y-scale}}}
582 \x_resetint{slant-scale}{\scale{\d_count}{\int{slant-scale}}}

583 #2 584 }

585 \def\xscalefont#1#2{
586 \x_resetint{x-scale}{\scale{#1}{\int{x-scale}}}

587 #2 588 }

589 \def\yscalefont#1#2{
590 \eval_expr_to\d_count{#1}
591 \x_resetint{y-scale}{\scale{\d_count}{\int{y-scale}}}
592 \x_resetint{slant-scale}{\scale{\d_count}{\int{slant-scale}}}

593 #2

595 \def\slantfont#1#2{
596 \x_resetint{slant-scale}{
597  \add{\scale{#1}{\int{x-scale}}}{\int{slant-scale}}

598 } 599 #2 600 }

601 \def\reencodefont#1#2{

602 #2

603 \resetstr{etx-name}{#1}

604 }

\mtxtomtx  The macro:

\mtxtomtx{⟨source MTX ⟩}{⟨destination 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 the transformable ones.

\mtxtomtx
605 \def\mtxtomtx#1#2{{
606 \ifisstr{etx-name}\then
607  \def\do_slot{\x_resetint\slot_name\slot_number}
608  \inputetx{\str{etx-name}}
609 \fi
610 \open_out{\temp_prefix#2.mtx}
611 \def\raw_font_name{#2}
612 \out_line{\percent_char~Filename:~#2.mtx}
613 \out_line{\percent_char~Created~by:~tex~\jobname}
614 \out_line{\percent_char~Created~using:~\string\mtxtomtx{#1}{#2}}
615 \out_line{}
616 \out_line{\percent_char~This~file~is~used~by~the~fontinst~package.}
617 \out_line{}
618 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
619 \out_line{}
620 \out_line{\string\relax}
621 \out_line{\string\metrics}
622 \out_line{}
623 \out_line{\string\needsfontinstversion{\fontinstversion}}
624 \out_line{}
625 \let\setint=\mtxtomtx_setint
626 \let\setdim=\mtxtomtx_setdim
627 \let\setstr=\mtxtomtx_setstr
628 \let\setrawglyph=\mtxtomtx_setrawglyph
629 \let\setnotglyph=\mtxtomtx_setrawglyph
630 \let\setkern=\mtxtomtx_setkern
631 \let\setglyph=\mtxtomtx_setglyph
632 \let\glyphpcc=\mtxtomtx_glyphpcc
633 \let\samesize=\mtxtomtx_samesize
634 \let\endsetglyph=\mtxtomtx_endsetglyph
635 \inputmtx{#1}
636 \out_line{}
637 \out_line{\endmetrics_text}

638 \close_out{Transformed~metrics}

639 }}

\mtxtomtx_setint \italicslant_name Currently all integers except italicslant are interpreted as being the ycoordinate of some point. italicslant is interpreted as the quotient \frac{x}{y} for a point (x, y), but represented as a real number (i.e., the TEX number is really a thousand times the actual quotient).

If some new integer is added that cannot be transformed as a y-coordinate, then the \mtxtomtx_setint macro must be rewritten.

640 \def\mtxtomtx_setint#1#2{
641 \def\a_macro{#1}
642 \ifx\a_macro\italicslant_name
643  \eval_expr{#2}
644  \global\multiply \result \int{x-scale}
645  \a_count=\int{slant-scale}
646  \multiply \a_count \one_thousand
647  \advance \a_count \result
648  \divide \a_count \int{y-scale}\x_relax
649 \else
650  \eval_expr_to\a_count{\scale{#2}{\int{y-scale}}}
651 \fi
652 \out_line{\string\setint{#1}{\the\a_count}}

653 }

654 \def\italicslant_name{italicslant}

\mtxtomtx_setdim \mtxtomtx_setstr Strings and dimens are not affected by the \mtxtomtx transforms.

655 \def\mtxtomtx_setdim#1#2{
656 \out_line{\string\setdim{#1}{#2}}

657 }

658 \def\mtxtomtx_setstr#1#2{
659 \out_line{\string\setstr{#1}{#2}}

660 }

\mtxtomtx_setrawglyph #5 (the width) is transformed as the x-coordinate of a point on the baseline. #6 and #7 (the height and depth respectively) are transformed as y-coordinates. The depth should probably really have been transformed as the negative of a ycoordinate, but it comes out the same in the end anyway. #8 (the italic correction) is transformed as the x-coordinate of a point whose y-coordinate equals the height of the character. If the italic slant of the font is negative then it should probably be the depth instead, but it is hard to say for sure how that case should be treated.

661 \def\mtxtomtx_setrawglyph#1#2#3#4#5#6#7#8{
662 \eval_expr_to\a_count{\scale{#5}{\int{x-scale}}}
663 \eval_expr_to\b_count{\scale{#6}{\int{y-scale}}}
664 \eval_expr_to\c_count{\scale{#7}{\int{y-scale}}}
665 \eval_expr_to\d_count{#8} \eval_expr{#6}
666 \multiply \d_count \int{x-scale}
667 \global\multiply \result \int{slant-scale}
668 \global\advance \result \d_count
669 \rounded_thousandths
670 \d_count=\result
671 \ifisstr{etx-name}\then
672  \ifisint{#1}\then

673  \e_count=\int{#1}
674  \else
675  \e_count=-1
676  \fi
677 \else
678  \e_count=#4
679 \fi
680 \out_line{
681  \ifnum\e_count>-1
682  \string\setrawglyph
683  \else
684  \string\setnotglyph
685  \fi
686  {#1}{\raw_font_name}{#3}{\the\e_count}
687  {\the\a_count}{\the\b_count}{\the\c_count}{\the\d_count}

688 } 689 }

\mtxtomtx_setkern Kerns are transformed as the x-coordinate of a point on the baseline.

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

693 }

\mtxtomtx_setglyph
\mtxtomtx_samesize
\mtxtomtx_endsetglyph

694 \def\mtxtomtx_setglyph#1{\out_line{\string\setglyph{#1}}}
695 \def\mtxtomtx_samesize#1{\out_lline{\string\samesize{#1}}}
696 \def\mtxtomtx_endsetglyph{\out_line{\string\endsetglyph}}

\mtxtomtx_glyphpcc #2 is transformed as the x-coordinate and #3 is transformed as the y-coordinate of a point—the same point for both parameters.

697 \def\mtxtomtx_glyphpcc#1#2#3{
698 \eval_expr_to\b_count{\scale{\int{y-scale}}{#3}}
699 \eval_expr_to\a_count{#2} \eval_expr{#3}
700 \multiply \a_count \int{x-scale}
701 \global\multiply \result \int{slant-scale}
702 \global\advance \result \a_count
703 \rounded_thousandths
704 \out_lline{\string\glyphpcc{#1}{\the\result}{\the\b_count}}

705 }

16.3 Changing glyph names

fontinst uses names to identify glyphs, and if for example the font in question is a postscript font, then names will also be used to identify glyphs in the printer. Between those two points however, and in particular inside TEX itself, glyphs are represented with numbers (slots). Therefore there is no real need for the glyph names used within fontinst and the glyph names used in the printer (the names gotten from the AFM file) to be equal, but they usually are. There are some cases though where the glyph names of a font are unsuitable for use with fontinst— mainly because fontinst can mix glyphs from different printer fonts—and therefore fontinst also offers the ability to automatically change the names of glyphs in transformable metric files.

\reglyphfonts \endreglyphfonts       \reglyphfonts ⟨reglyphing commands⟩ \endreglyphfonts
706 \def\reglyphfonts{
707 \begingroup
708 \x_setint{renameweight}{1}
709 \x_setint{killweight}{-10}
710 \setcommand\iftokeep##1\then{\ifnum -1<##1}

711 }

712 \def\endreglyphfonts{\endgroup}

The ⟨reglyphing commands⟩ are

     \renameglyph{⟨to⟩}{⟨from⟩}
     \renameglyphweighted{⟨to⟩}{⟨from⟩}{⟨weight⟩}
     \killglyph{⟨glyph⟩}
     \killglyphweighted{⟨glyph⟩}{⟨weight⟩}
     \offmtxcommand{⟨command⟩}
     \onmtxcommand{⟨command⟩}

\reglyphfont{⟨destination font⟩}{⟨source font⟩}

The only reglyphing command that actually convert the names of any glyphs is

\reglyphfont \reglyphfont; it reads a font ⟨source font⟩ (which may be of type MTX, PL, AFM, or VPL) and writes another font ⟨destination font⟩ in which the names of glyphs have been converted. All the other commands control how this conversion should be made, and these settings get cleared at the closing \endreglyphfonts.

The conversion works in two ways. First of all, the names of the glyphs can be

\renameglyph changed. This works as a general mapping and is controlled by the \renameglyph \renameglyphweighted and \renameglyphweighted commands. Any mensioning of the glyph ⟨from⟩ in

a command will be converted to a mensioning of the glyph ⟨to⟩, if that command survives the conversion. The other way the conversion works is that it can selectively kill—refrain from including in ⟨destination font⟩—commands in the metric file. This part weighs in several factors.

For one thing, one can specify that all metric commands of a certain type should

\offmtxcommand be killed, and this is done with the \offmtxcommand command. For example, one can see to that all kerning commands are killed by

     \offmtxcommand{\setkern}

The effect is the same as that of saying

offkern,⟨destination font⟩,onkern

rather than just ⟨destination font⟩ in the second argument to \installfont, but it is somewhat faster since less text is written to and subsequently read from the ⟨destination font⟩.mtx file. The effect of a previous \offmtxcommand can be

\onmtxcommand canceled by a call to \onmtxcommand, just like with \offcommand and \oncommand.

The survivance of a command is also affected by the glyphs it refers to. Each glyph has a weight associated with it and the sum of the weights for all glyphs mensioned by a command is also used to decide whether that command should

\iftokeep survive. The test here is performed by the macro \iftokeep, whose parameter text must be #1\then, where #1 will be a \count register. This macro must eventually expand to an if of some sort and that if evaluating to true is interpreted as that the command should be kept. The default replacement text is \ifnum -1<#1, which causes a command to be killed (not kept) iff the sum of weights for it is negative.

   The weight of a glyph is set by \renameglyph, \renameglyphweighted,
\killglyph  \killglyph, and \killglyphweighted. The \rename. . . commands also set a

\killglyphweighted new name for the glyph if it survives, whereas the \kill… commands will keep the old name. Since the standard settings are that a \rename… weight is small and positive and a \kill… weight is large and negative, glyphs for which a \kill… has been done will usually not survive.

   Any one of \renameglyph, \renameglyphweighted, \killglyph, and \killglyphweighted

for a glyph will override all previous settings by any of these four commands for that glyph. The equivalent of the neutral state for a glyph (no settings by any of these commands have been made for that glyph) is achieved by the command

     \killglyphweighted{⟨glyph⟩}{0}
\offmtxcommand \onmtxcommand These two are just special forms of \offcommand and \oncommand.
713 \def\offmtxcommand#1{
714 \x_cs\offcommand{reglyph_\expandafter\gobble_one\string#1}

715 }

716 \def\onmtxcommand#1{
717 \x_cs\oncommand{reglyph_\expandafter\gobble_one\string#1}

718 }

\slots-GLYPH  Inside a \reglyphfonts . . . \endreglyphfonts block, the family \slots-⟨glyph⟩

of control sequences is used to store the information about how glyph ⟨glyph⟩ should be converted. These control sequences are either undefined or parameterless macros whose replacement texts are of one of the forms

     \rename_glyph{⟨to⟩}{⟨weight⟩}
     \rename_glyph{⟨to⟩}\i-renameweight
     \kill_glyph{⟨weight⟩}
     \kill_glyph\i-killweight

⟨to⟩ is what the glyph will be renamed to and ⟨weight⟩ is the associated weight. These four different forms are generated by the four different commands

\renameglyphweighted, \renameglyph, \killglyphweighted, and \killglyph

respectively.

\renameglyph \renameglyphweighted The difference between the commands \renameglyphweighted and \renameglyph

is that the former lets one specify the weight exactly while the latter will use the value of the integer renameweight at the time of conversion. By changing the value of renameweight between two conversions, one changes the weights used for all glyph renamings declared using \renameglyph.

719 \begingroup
720 \catcode`\-=11
721 \gdef\renameglyph#1#2{
722  \x_cs\edef{slots-#2}{
723  \noexpand\rename_glyph{#1}\noexpand\i-renameweight

724 } 725 }

726 \endgroup
727 \def\renameglyphweighted#1#2#3{
728 \eval_expr{#3}
729 \x_cs\edef{slots-#2}{\noexpand\rename_glyph{#1}{\the\result}}

730 }

\killglyph \killglyphweighted The difference between the commands \killglyphweighted and \killglyph is

that the former lets one specify the weight exactly while the latter will use the value of the integer killweight at the time of conversion. By changing the value of killweight between two conversions, one changes the weights used for all glyph killings declared using \killglyph.

731 \begingroup
732 \catcode`\-=11
733 \gdef\killglyph#1{
734  \x_cs\def{slots-#1}{\kill_glyph\i-killweight}

735 }

736 \endgroup
737 \def\killglyphweighted#1#2{
738 \eval_expr{#2}
739 \x_cs\edef{slots-#1}{\noexpand\kill_glyph{\the\result}}

740 }

\reglyphfont The command

\reglyphfont{⟨destination font⟩}{⟨source font⟩}

reads the font metric file ⟨source font⟩.mtx (which must be transformable), ⟨source font⟩.pl, or ⟨source font⟩.afm (the possibilities are tried in that order) and writes out a font metric file ⟨destination font⟩.mtx that is the converted (as described above) form of the source font.

⟨destination font⟩ and ⟨source font⟩ may not be equal.

741 \def\reglyphfont#1#2{
742 \fromany{#2}
743 \ifisstr{transform-source}\then
744  \reglyph_font{#1}{#2}
745  \record_transform{#1}{\str{transform-source}}{\string\reglyphfont}
746 \else
747  \errmessage{Could~not~find~font~metrics~for~#2.}
748 \fi

749 }

\reglyph_font This macro does the actual conversion.

750 \def\reglyph_font#1#2{{
751 \open_out{\temp_prefix#1.mtx}
752 \out_line{\percent_char~Filename:~#1.mtx}
753 \out_line{\percent_char~Created~by:~tex~\jobname}
754 \out_line{\percent_char~Created~using:~\string\reglyphfont{#1}{#2}}
755 \out_line{}
756 \out_line{\percent_char~This~file~is~used~by~the~fontinst~package.}
757 \out_line{}
758 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
759 \out_line{}
760 \out_line{\string\relax}
761 \out_line{\string\metrics}
762 \out_line{}
763 \out_line{\string\needsfontinstversion{\fontinstversion}}
764 \out_line{}
765 \let\setint=\reglyph_setint
766 \let\setdim=\reglyph_setdim

767 \let\setstr=\reglyph_setstr
768 \let\setrawglyph=\reglyph_setrawglyph
769 \let\setnotglyph=\reglyph_setrawglyph
770 \let\setkern=\reglyph_setkern
771 \let\setglyph=\reglyph_setglyph
772 \let\glyphpcc=\reglyph_glyphpcc
773 \let\samesize=\reglyph_samesize
774 \let\endsetglyph=\reglyph_endsetglyph
775 \inputmtx{#2}
776 \out_line{}
777 \out_line{\endmetrics_text}
778 \close_out{Reglyphed~metrics}

779 }}

\reglyph_setint \reglyph_setdim \reglyph_setstr These are just copied to the file generated.
780 \def\reglyph_setint#1#2{\out_line{\string\setint{#1}{#2}}}
781 \def\reglyph_setdim#1#2{\out_line{\string\setdim{#1}{#2}}}
782 \def\reglyph_setstr#1#2{\out_line{\string\setstr{#1}{#2}}}

\command_survivance This \count register stores the sum of the weights associated with the glyphs considered so far. It is updated by \rename_glyph and \kill_glyph.

783 \newcount\command_survivance

\glyphname The macro \glyphname holds the name of the glyph currently under consideration. It is altered by \rename_glyph.

\rename_glyph
\kill_glyph
784 \def\rename_glyph#1{\def\glyphname{#1}\kill_glyph}
785 \def\kill_glyph#1{\advance \command_survivance #1\x_relax}

\reglyph_setrawglyph The \reglyph_setrawglyph macro is straightforward. Whether it writes a \setrawglyph or a \setnotglyph command depends on the fourth parameter,

 just like with \mtxtomtx_setrawglyph.
786 \def\reglyph_setrawglyph#1#2#3#4#5#6#7#8{
787 \command_survivance=0
788 \def\glyphname{#1}
789 \csname slots-#1\endcsname
790 \iftokeep\command_survivance\then
791  \out_line{
792  \ifnum #4<\z@
793  \string\setnotglyph
794  \else
795  \string\setrawglyph
796  \fi
797  {\glyphname}{#2}{#3}{#4}{#5}{#6}{#7}{#8}

798 }

799 \fi

800 }

\reglyph_setkern
801 \def\reglyph_setkern#1#2#3{
802 \command_survivance=0
803 \def\glyphname{#1}

804 \csname slots-#1\endcsname
805 \let\a_macro=\glyphname
806 \def\glyphname{#2}
807 \csname slots-#2\endcsname
808 \iftokeep\command_survivance\then
809  \out_line{\string\setkern{\a_macro}{\glyphname}{#3}}
810 \fi

811 }

\reglyph_setglyph \off-\reglyph_setglyph \reglyph_glyphpcc \reglyph_samesize \reglyph_endsetglyph In \setglyph . . . \endsetglyph constructions (which are written for composite

characters in AFM files), the decision of whether to write a command or not due to glyph weights is done only once for the entire construction. This means that the commands must be saved until the \endsetglyph where the result is finally known. The token list register \a_toks is used for this purpose.

812 \def\reglyph_setglyph#1{
813 \command_survivance=0
814 \def\glyphname{#1}
815 \csname slots-#1\endcsname
816 \edef\a_macro{\string\out_line{\string\setglyph{\glyphname}}}
817 \a_toks=\expandafter{\a_macro}

818 }

819 \x_cs\def{off-\string\reglyph_setglyph}#1{\gobble_glyph}
820 \def\reglyph_glyphpcc#1#2#3{
821 \def\glyphname{#1}
822 \csname slots-#1\endcsname
823 \edef\a_macro{\string\out_lline{
824  \string\glyphppc{\glyphname}{#2}{#3}

825 }}

826 \a_toks=\expandafter{\the\expandafter\a_toks \a_macro}

827 }

828 \def\reglyph_samesize#1{
829 \def\glyphname{#1}
830 \csname slots-#1\endcsname
831 \edef\a_macro{\string\out_lline{
832  \string\samesize{\glyphname}

833 }}

834 \a_toks=\expandafter{\the\expandafter\a_toks \a_macro}

835 }

836 \def\reglyph_endsetglyph{
837 \iftokeep\command_survivance\then
838  \the\a_toks
839  \out_line{\string\endsetglyph}
840 \fi
841 \a_toks={}

842 } 843 ⟨/pkg⟩

Two common reglyphing schemes

As is mensioned elsewhere, the most common reglyphing operation is to take a caps and small caps font produced by some major foundry and change the glyph names so that they agree with the glyph names used in expert fonts. The following code contains the modifying reglyphing commands to set up this reglyphing, in two different variants.

The commands are currently based on a comparision of Adobe Garamond Small Caps & Oldstyle Figures (padrc8a in the Berry scheme) with Adobe Garamond Regular Expert (padr8x in the Berry scheme), so they should be correct for a fair amount of Adobe font families, but it is also highly probable that there are lots of fonts out there for which it doesn’t work quite right. In case you do find such a font, please write to tell the fontinst mailing list about it—it would be rather easy to add various alternative setup schemes, controlled by switches, to these files. Just make sure first (by checking the newest version of fontinst) that the alternative setting you have found hasn’t already been included.

As mensioned, there are two different reglyphing schemes that are set up by the code below—one has docstrip guard ⟨glyphs⟩, the other has guard ⟨!glyphs⟩— but they both change CSC names to Expert names. The difference lies instead in what information is copied from source font to destination font: the ⟨glyphs⟩ variant copies everything, whereas the ⟨!glyphs⟩ variant doesn’t copy \setrawglyph commands, \setnotglyph commands, or \setglyph constructions. The ⟨!glyphs⟩ variant also suppresses kerns between two glyphs that doesn’t change name.

The motive for having such a curious setup naturally lies in how the files are meant to be used. If you have CSC fonts, but no Expert fonts, then you should definately use the ⟨glyphs⟩ variant. If on the other hand you have both CSC and Expert fonts for a family, then it is worth considering using the ⟨!glyphs⟩ variant instead. The observation this is based on is that within a triad of the corresponding regular, expert, and CSC fonts, almost all glyphs present in the CSC font can also be found in either the regular or the expert font; furthermore the only missing glyphs were FIsmall, FLsmall, and SSsmall, which (i) were included in the CSC font only to complete the 8a encoding vector and (ii) are identical to fontinst’s fakes for them. Thus by constructing the sc shape fonts from the regular and expert variants, instead of the CSC variant, one can get away with using one raw font less, thus reducing the time needed for downloading the fonts to the printer. One thing not found in either of the regular or expert font in the triad is however the kerns between capitals and small capitals, but these can be extracted from the metrics of the CSC font, and doing this is the primary objective for the ⟨!glyphs⟩ variant.

First there is the English alphabet:

844 ⟨∗reglyph⟩

845 \renameglyph{Asmall}{a}
846 \renameglyph{Bsmall}{b}
847 \renameglyph{Csmall}{c}
848 \renameglyph{Dsmall}{d}
849 \renameglyph{Esmall}{e}
850 \renameglyph{Fsmall}{f}
851 \renameglyph{Gsmall}{g}
852 \renameglyph{Hsmall}{h}
853 \renameglyph{Ismall}{i}
854 \renameglyph{Jsmall}{j}
855 \renameglyph{Ksmall}{k}
856 \renameglyph{Lsmall}{l}
857 \renameglyph{Msmall}{m}
858 \renameglyph{Nsmall}{n}

859 \renameglyph{Osmall}{o}
860 \renameglyph{Psmall}{p}
861 \renameglyph{Qsmall}{q}
862 \renameglyph{Rsmall}{r}
863 \renameglyph{Ssmall}{s}
864 \renameglyph{Tsmall}{t}
865 \renameglyph{Usmall}{u}
866 \renameglyph{Vsmall}{v}
867 \renameglyph{Wsmall}{w}
868 \renameglyph{Xsmall}{x}
869 \renameglyph{Ysmall}{y}
870 \renameglyph{Zsmall}{z}

Then there are the figures:

871 \renameglyph{zerooldstyle}{zero}
872 \renameglyph{oneoldstyle}{one}
873 \renameglyph{twooldstyle}{two}
874 \renameglyph{threeoldstyle}{three}
875 \renameglyph{fouroldstyle}{four}
876 \renameglyph{fiveoldstyle}{five}
877 \renameglyph{sixoldstyle}{six}
878 \renameglyph{sevenoldstyle}{seven}
879 \renameglyph{eigtholdstyle}{eight}
880 \renameglyph{nineoldstyle}{nine}

Then there are the accents and a couple of miscellaneous symbols. You might want to check these carefully, as there might not always be a distinction.

881 \renameglyph{Gravesmall}{grave}
882 \renameglyph{Acutesmall}{acute}
883 \renameglyph{Circumflexsmall}{circumflex}
884 \renameglyph{Tildesmall}{tilde}
885 \renameglyph{Macronsmall}{macron}
886 \renameglyph{Brevesmall}{breve}
887 \renameglyph{Dotaccentsmall}{dotaccent}
888 \renameglyph{Dieresissmall}{dieresis}
889 \renameglyph{Ringsmall}{ring}
890 \renameglyph{Cedillasmall}{cedilla}
891 \renameglyph{Ogoneksmall}{ogonek}
892 \renameglyph{Caronsmall}{caron}
893 \renameglyph{dollaroldstyle}{dollar}
894 \renameglyph{ampersandsmall}{ampersand}
895 \renameglyph{centoldstyle}{cent}

There are also all the non-English letters:

896 \renameglyph{AEsmall}{ae}
897 \renameglyph{Ethsmall}{eth}
898 \renameglyph{Lslashsmall}{lslash}
899 \renameglyph{Oslashsmall}{oslash}
900 \renameglyph{OEsmall}{oe}
901 \renameglyph{Thornsmall}{thorn}
902 \renameglyph{Agravesmall}{agrave}
903 \renameglyph{Egravesmall}{egrave}
904 \renameglyph{Igravesmall}{igrave}
905 \renameglyph{Ogravesmall}{ograve}
906 \renameglyph{Ugravesmall}{ugrave}

907 \renameglyph{Aacutesmall}{aacute}
908 \renameglyph{Eacutesmall}{eacute}
909 \renameglyph{Iacutesmall}{iacute}
910 \renameglyph{Oacutesmall}{oacute}
911 \renameglyph{Uacutesmall}{uacute}
912 \renameglyph{Yacutesmall}{yacute}
913 \renameglyph{Acircumflexsmall}{acircumflex}
914 \renameglyph{Ecircumflexsmall}{ecircumflex}
915 \renameglyph{Icircumflexsmall}{icircumflex}
916 \renameglyph{Ocircumflexsmall}{ocircumflex}
917 \renameglyph{Ucircumflexsmall}{ucircumflex}
918 \renameglyph{Atildesmall}{atilde}
919 \renameglyph{Ntildesmall}{ntilde}
920 \renameglyph{Otildesmall}{otilde}
921 \renameglyph{Adieresissmall}{adieresis}
922 \renameglyph{Edieresissmall}{edieresis}
923 \renameglyph{Idieresissmall}{idieresis}
924 \renameglyph{Odieresissmall}{odieresis}
925 \renameglyph{Ydieresissmall}{ydieresis}
926 \renameglyph{Udieresissmall}{udieresis}
927 \renameglyph{Aringsmall}{aring}
928 \renameglyph{Ccedillasmall}{ccedilla}
929 \renameglyph{Scaronsmall}{scaron}
930 \renameglyph{Zcaronsmall}{zcaron}

The following four glyphs aren’t really necessary, since they are usually identical to another glyph or to their fakes.

931 \killglyph{dotlessi}

932 ⟨∗glyphs⟩

933 \renameglyph{FIsmall}{fi}
934 \renameglyph{FLsmall}{fl}
935 \renameglyph{SSsmall}{germandbls}

936 ⟨/glyphs⟩ 937 ⟨∗!glyphs⟩

938 \killglyph{fi}
939 \killglyph{fl}
940 \killglyph{germandbls}

941 ⟨/!glyphs⟩

The ⟨!glyphs⟩ settings have no need for \setrawglyph or \setglyph commands, and no need for the kerns between capitals either, since these are already known from the regular variant.

942 ⟨∗!glyphs⟩

943 \offmtxcommand\setrawglyph
944 \offmtxcommand\setglyph
945 \resetcommand\iftokeep#1\then{\ifnum 0<#1}

946 ⟨/!glyphs⟩ 947 ⟨/reglyph⟩

File d

filtfam.dtx

17 Installing Latin families

\latinfamily The macro:

\latinfamily{⟨family⟩}{⟨commands⟩}

installs a Latin font family.

1 ⟨∗pkg⟩

 2 \def\latinfamily#1#2{{
 3 \edef\a_macro{#1}
 4 \expandafter\parse_family\a_macro
 5  \empty_command\empty_command\end_parse_family
 6 \installfonts
 7  \if_file_exists{\raw_encoding.mtx}\then
 8  \installfamily{\raw_encoding}{\latex_family}{#2}
 9  \fi
10  \installfamily{OT1}{\latex_family}{#2}
11  \installfamily{T1}{\latex_family}{#2}

12 ⟨∗textcomp⟩

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

14 ⟨/textcomp⟩

15  \latin_weights
16 \endinstallfonts
17 }}
\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.

18 \def\parse_family #1#2#3#4#5\end_parse_family{
19 \gdef\font_family{#1#2#3}
20 \gdef\font_variant{#4#5}
21 \gdef\raw_variant{#4#5}
22 \gdef\latex_family{#1#2#3#4#5}
23 \_expert_false
24 \_oldstyle_false
25 \ifx#4x
26  \_expert_true
27  \gdef\raw_variant{#5}

28  \gdef\font_variant{#5}
29  %\setcommand\digit##1{##1}
30 \else\ifx#4j
31  \_expert_true
32  \_oldstyle_true
33  \gdef\raw_variant{#5}
34  \gdef\font_variant{#5}
35  %\setcommand\digit##1{##1oldstyle}
36 \else\ifx#49
37  \gdef\latex_family{#1#2#3j#5}
38  \_expert_true
39  \_oldstyle_true
40  \gdef\raw_variant{#5}
41  \gdef\font_variant{#5}
42  %\setcommand\digit##1{##1oldstyle}
43 \else
44  \_expert_false
45  \_oldstyle_false
46  %\setcommand\digit##1{##1}
47 \fi\fi\fi

48 ⟨∗debug⟩

49 \if_oldstyle_
50 \immediate\write16{INFO>~parse~family~<#1#2#3><#5>~(oldstyle)}
51 \else\if_expert_
52 \immediate\write16{INFO>~parse~family~<#1#2#3><#5>~(expert)}
53 \else
54 \immediate\write16{INFO>~parse~family~<#1#2#3><#4#5>}
55 \fi\fi

56 ⟨/debug⟩ 57 }

\if_expert_
\if_oldstyle_
58 \newif\if_expert_
59 \newif\if_oldstyle_

17.1 Processing a list of weights, widths and shapes

\latin_weight \font_weight \latex_weight  \latin_weight{FONTWEIGHT}{LATEXWEIGHT}
60 \def\latin_weight#1#2{
61 \gdef\font_weight{#1}%
62 \gdef\latex_weight{#2}%
63 \latin_widths

64 }

\latin_width \font_width \latex_width  \latin_width{FONTWIDTH}{LATEXWIDTH}
65 \def\latin_width#1#2{
66 \gdef\font_width{#1}
67 \gdef\latex_width{#2}
68 \latin_shapes

69 }

\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.
70 \def\latin_shape#1#2#3#4#5{
71 \gdef\font_shape{#1}
72 \gdef\raw_shape{#2}
73 \gdef\encoding_shape{#3}
74 \if_oldstyle_
75  \gdef\encoding_shape{#3\oldstyle_shape}
76 \fi
77 \gdef\latex_shape{#4}
78 \gdef\encoding_switches{#5}

79 ⟨∗debug⟩

80 \immediate\write16{
81  INFO>~to~make~LaTeX~font~shape~<\latex_family,
82  \latex_weight,\latex_shape,\latex_width>~seek~
83  \font_family\font_weight\raw_shape
84  \raw_variant\raw_encoding\font_width.mtx}

85 ⟨/debug⟩

86 \csname fake_width_\font_width\endcsname
87 \csname fake_shape_\raw_shape\endcsname
88 \if_file_exists{
89  \font_family\font_weight\raw_shape
90  \raw_variant\raw_encoding\font_width.mtx
91 }\then
92  \latin_encodings
93 \fi

94 }

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

95 \def\fake_shape_{
96 \if_file_exists{
97  \font_family\font_weight\raw_shape\raw_variant
98  \adobe_encoding\font_width.afm
99 }\then
100  \fake_shape_raw_encoding

101 \fi
102 \if_expert_
103  \if_file_exists{
104  \font_family\font_weight\raw_shape\raw_variant
105  \expert_encoding\font_width.afm
106  }\then
107  \fake_shape_expert_encoding
108  \fi
109 \fi

110 ⟨∗oldstyle⟩

111 \if_oldstyle_
112  \gdef\oldstyle_variant{\oldstyle_shape}
113  \if_file_exists{
114  \font_family\font_weight\raw_shape\oldstyle_variant
115  \adobe_encoding\font_width.afm
116  }\then
117  \fake_shape_oldstyle_encoding
118  \else
119  \gdef\oldstyle_variant{\caps_shape}
120  \if_file_exists{
121  \font_family\font_weight\raw_shape\oldstyle_variant
122  \adobe_encoding\font_width.afm
123  }\then
124  \fake_shape_oldstyle_encoding
125  \fi
126  \fi
127 \fi

128 ⟨/oldstyle⟩ 129 }

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

130 \def\fake_shape_raw_encoding{
131 \if_file_exists{
132  \font_family\font_weight\raw_shape\raw_variant
133  \raw_encoding\font_width.mtx
134 }\then % no action required
135 \else

136 ⟨∗debug⟩

137  \immediate\write16{
138  INFO>~run~\string\transformfont\space\space
139  <\font_family\font_weight\raw_shape\raw_variant
140  \raw_encoding\font_width>~from~
141  <\font_family\font_weight\raw_shape\raw_variant
142  \adobe_encoding\font_width>

143 } 144 ⟨/debug⟩

145  \transformfont{
146  \font_family\font_weight\raw_shape\raw_variant
147  \raw_encoding\font_width

148 }{

149  \reencodefont{\raw_encoding}{
150  \fromafm{
151  \font_family\font_weight\raw_shape\raw_variant
152  \adobe_encoding\font_width

153 } 154 } 155 }

156  \if_file_exists{ \raw_encoding.mtx }\then

157 ⟨∗debug⟩

158  \immediate\write16{
159  INFO>~run~\string\installrawfont\space
160  <\font_family\font_weight\font_shape\raw_variant
161  \raw_encoding\font_width>
162  <\font_family\font_weight\raw_shape\raw_variant
163  \raw_encoding\font_width,
164  \raw_encoding>
165  <\raw_encoding>
166  <\raw_encoding>
167  <\latex_family>
168  <\latex_weight\latex_width>
169  <\latex_shape>}

170 ⟨/debug⟩

171  \installrawfont{
172  \font_family\font_weight\raw_shape\raw_variant
173  \raw_encoding\font_width
174  }{ \font_family\font_weight\raw_shape\raw_variant
175  \raw_encoding\font_width,
176  \raw_encoding
177  }{ \raw_encoding
178  }{ \raw_encoding
179  }{ \latex_family
180  }{ \latex_weight\latex_width
181  }{ \latex_shape
182  }{}
183  \fi
184 \fi

185 }

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

186 \def\fake_shape_expert_encoding{
187 \if_file_exists{
188  \font_family\font_weight\raw_shape\raw_variant
189  \expert_encoding\font_width.mtx
190 }\then % no action required
191 \else
192  \fromafm{

193  \font_family\font_weight\raw_shape\raw_variant
194  \expert_encoding\font_width

195 }

196 \fi

197 }

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

198 ⟨∗oldstyle⟩

199 \def\fake_shape_oldstyle_encoding{
200 \if_file_exists{
201  \font_family\font_weight\raw_shape\oldstyle_variant
202  \adobe_encoding\font_width.mtx
203 }\then % no action required
204 \else

205 ⟨∗debug⟩

206  \immediate\write16{
207  INFO>~run~\string\transformfont\space\space
208  <\font_family\font_weight\raw_shape\oldstyle_variant
209  \raw_encoding\font_width>~from~
210  <\font_family\font_weight\raw_shape\oldstyle_variant
211  \adobe_encoding\font_width>

212 } 213 ⟨/debug⟩

214  \transformfont{
215  \font_family\font_weight\raw_shape\oldstyle_variant
216  \raw_encoding\font_width

217 }{

218  \reencodefont{\raw_encoding}{
219  \fromafm{
220  \font_family\font_weight\raw_shape\oldstyle_variant
221  \adobe_encoding\font_width

222 } 223 } 224 }

225 \fi

226 } 227 ⟨/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.

228 \def\fake_shape_c{
229 \if_file_exists{
230  \font_family\font_weight\raw_shape\raw_variant
231  \adobe_encoding\font_width.afm
232 }\then
233  \fake_shape_

234 \else
235  % If real smallcaps font doesn't exist, fake it from the roman.
236  \gdef\raw_shape{}
237  \if_oldstyle_
238  \gdef\encoding_shape{cj}
239  \else
240  \gdef\encoding_shape{c}
241  \fi
242  \fake_shape_
243 \fi

244 }

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

245 \def\fake_shape_o{
246 \if_file_exists{
247  \font_family\font_weight\raw_shape\raw_variant
248  \adobe_encoding\font_width.afm
249 }\then
250  \fake_shape_
251 \else
252  \fake_shape_o_raw_encoding
253  \if_expert_
254  \fake_shape_o_expert_encoding
255  \fi

256 ⟨∗oldstyle⟩

257  \if_oldstyle_
258  \fake_shape_o_oldstyle_encoding
259  \fi

260 ⟨/oldstyle⟩

261 \fi

262 }

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

263 \def\fake_shape_o_raw_encoding{
264 \if_file_exists{
265  \font_family\font_weight\raw_variant
266  \raw_encoding\font_width.mtx
267 }\then
268  \if_file_exists{
269  \font_family\font_weight\font_shape\raw_variant
270  \raw_encoding\font_width.mtx
271  }\then % no action required
272  \else

273 ⟨∗debug⟩

274  \immediate\write16{
275  INFO>~run~\string\transformfont\space\space
276  <\font_family\font_weight\font_shape\raw_variant
277  \raw_encoding\font_width>~from~
278  <\font_family\font_weight\raw_variant
279  \raw_encoding\font_width>~(faking~oblique)

280 } 281 ⟨/debug⟩

282  %%% WARNING: famtool.pl relies on this message format!!!
283  \immediate\write16{
284  Faking~oblique~font~
285  \font_family\font_weight\font_shape\raw_variant
286  \raw_encoding\font_width
287  \space from~
288  \font_family\font_weight\raw_variant
289  \raw_encoding\font_width

290 }

291  \transformfont{
292  \font_family\font_weight\font_shape\raw_variant
293  \raw_encoding\font_width

294 }{

295  \slantfont{\SlantAmount}{
296  \frommtx{
297  \font_family\font_weight\raw_variant
298  \raw_encoding\font_width

299 } 300 } 301 }

302  \if_file_exists{ \raw_encoding.mtx }\then

303 ⟨∗debug⟩

304  \immediate\write16{
305  INFO>~run~\string\installrawfont\space
306  <\font_family\font_weight\font_shape\raw_variant
307  \raw_encoding\font_width>
308  <\font_family\font_weight\font_shape\raw_variant
309  \raw_encoding\font_width,
310  \raw_encoding>
311  <\raw_encoding>
312  <\raw_encoding>
313  <\latex_family>
314  <\latex_weight\latex_width>
315  <\latex_shape>}

316 ⟨/debug⟩

317  \installrawfont{
318  \font_family\font_weight\font_shape\raw_variant
319  \raw_encoding\font_width
320  }{ \font_family\font_weight\font_shape\raw_variant
321  \raw_encoding\font_width,
322  \raw_encoding
323  }{ \raw_encoding
324  }{ \raw_encoding
325  }{ \latex_family
326  }{ \latex_weight\latex_width

327  }{ \latex_shape
328  }{}
329  \fi
330  \fi
331 \fi

332 }

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

333 \def\fake_shape_o_expert_encoding{
334 \if_file_exists{
335  \font_family\font_weight\raw_variant
336  \expert_encoding\font_width.mtx
337 }\then
338  \if_file_exists{
339  \font_family\font_weight\font_shape\raw_variant
340  \expert_encoding\font_width.mtx
341  }\then % no action required
342  \else

343 ⟨∗debug⟩

344  \immediate\write16{
345  INFO>~run~\string\transformfont\space\space
346  <\font_family\font_weight\font_shape\raw_variant
347  \expert_encoding\font_width>~from~
348  <\font_family\font_weight\raw_variant
349  \expert_encoding\font_width>~(faking~oblique)

350 } 351 ⟨/debug⟩

352  %%% WARNING: famtool.pl relies on this message format!!!
353  \immediate\write16{
354  Faking~oblique~font~
355  \font_family\font_weight\font_shape\raw_variant
356  \expert_encoding\font_width
357  \space from~
358  \font_family\font_weight\raw_variant
359  \expert_encoding\font_width

360 }

361  \transformfont{
362  \font_family\font_weight\font_shape\raw_variant
363  \expert_encoding\font_width

364 }{

365  \slantfont{\SlantAmount}{
366  \frommtx{
367  \font_family\font_weight\raw_variant
368  \expert_encoding\font_width

369 } 370 } 371 }

372  \fi
373 \fi

374 }

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

375 ⟨∗oldstyle⟩

376 \def\fake_shape_o_oldstyle_encoding{
377 \if_file_exists{
378  \font_family\font_weight\oldstyle_variant
379  \raw_encoding\font_width.mtx
380 }\then
381  \if_file_exists{
382  \font_family\font_weight\font_shape\oldstyle_variant
383  \raw_encoding\font_width.mtx
384  }\then % no action required
385  \else

386 ⟨∗debug⟩

387  \immediate\write16{
388  INFO>~run~\string\transformfont\space\space
389  <\font_family\font_weight\font_shape\oldstyle_variant
390  \raw_encoding\font_width>~from~
391  <\font_family\font_weight\oldstyle_variant
392  \raw_encoding\font_width>~(faking~oblique)

393 } 394 ⟨/debug⟩

395  %%% WARNING: famtool.pl relies on this message format!!!
396  \immediate\write16{
397  Faking~oblique~font~
398  \font_family\font_weight\font_shape\oldstyle_variant
399  \raw_encoding\font_width
400  \space from~
401  \font_family\font_weight\oldstyle_variant
402  \raw_encoding\font_width

403 }

404  \transformfont{
405  \font_family\font_weight\font_shape\oldstyle_variant
406  \raw_encoding\font_width

407 }{

408  \slantfont{\SlantAmount}{
409  \frommtx{
410  \font_family\font_weight\oldstyle_variant
411  \raw_encoding\font_width

412 } 413 } 414 }

415  \fi
416 \fi

417 } 418 ⟨/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.

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

17.3 Faking font widths

\if_fake_narrow_
420 \newif\if_fake_narrow_
421 \_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.

422 \def\fakenarrow#1{
423 \_fake_narrow_true
424 \gdef\fake_narrow_width{#1}

425 }

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

426 \def\fake_width_{}
427 \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.
428 \def\fake_width_n{
429 \if_fake_narrow_
430  \if_file_exists{
431  \font_family\font_weight\raw_shape\raw_variant
432  \adobe_encoding\font_width.afm
433  }\then % no action required
434  \else
435  \fake_width_n_raw_encoding
436  \if_expert_
437  \fake_width_n_expert_encoding
438  \fi
439  \fi
440 \fi

441 }

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

442 \def\fake_width_n_raw_encoding{
443 \if_file_exists{
444  \font_family\font_weight\font_shape\raw_variant
445  \raw_encoding.mtx
446 }\then

447  \if_file_exists{
448  \font_family\font_weight\font_shape\raw_variant
449  \raw_encoding\font_width.mtx
450  }\then % no action required
451  \else

452 ⟨∗debug⟩

453  \immediate\write16{
454  INFO>~run~\string\transformfont\space\space
455  <\font_family\font_weight\font_shape\raw_variant
456  \raw_encoding\font_width>~from~
457  <\font_family\font_weight\font_shape\raw_variant
458  \raw_encoding>~(faking~narrow)

459 } 460 ⟨/debug⟩

461  %%% WARNING: famtool.pl relies on this message format!!!
462  \immediate\write16{
463  Faking~narrow~font~
464  \font_family\font_weight\font_shape\raw_variant
465  \raw_encoding\font_width
466  \space from~
467  \font_family\font_weight\font_shape\raw_variant
468  \raw_encoding

469 }

470  \transformfont{
471  \font_family\font_weight\font_shape\raw_variant
472  \raw_encoding\font_width

473 }{

474  \xscalefont{\fake_narrow_width}{
475  \frommtx{
476  \font_family\font_weight\font_shape\raw_variant
477  \raw_encoding

478 } 479 } 480 }

481  \if_file_exists{ \raw_encoding.mtx }\then

482 ⟨∗debug⟩

483  \immediate\write16{
484  INFO>~run~\string\installrawfont\space
485  <\font_family\font_weight\font_shape\raw_variant
486  \raw_encoding\font_width>
487  <\font_family\font_weight\font_shape\raw_variant
488  \raw_encoding\font_width,
489  \raw_encoding>
490  <\raw_encoding>
491  <\raw_encoding>
492  <\latex_family>
493  <\latex_weight\latex_width>
494  <\latex_shape>}

495 ⟨/debug⟩

496  \installrawfont{
497  \font_family\font_weight\font_shape\raw_variant
498  \raw_encoding\font_width
499  }{ \font_family\font_weight\font_shape\raw_variant
500  \raw_encoding\font_width,

501  \raw_encoding
502  }{ \raw_encoding
503  }{ \raw_encoding
504  }{ \latex_family
505  }{ \latex_weight\latex_width
506  }{ \latex_shape
507  }{}
508  \fi
509  \fi
510 \fi

511 }

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

512 \def\fake_width_n_expert_encoding{
513 \if_file_exists{
514  \font_family\font_weight\font_shape\raw_variant
515  \expert_encoding.mtx
516 }\then
517  \if_file_exists{
518  \font_family\font_weight\font_shape\raw_variant
519  \expert_encoding\font_width.mtx
520  }\then % no action required
521  \else

522 ⟨∗debug⟩

523  \immediate\write16{
524  INFO>~run~\string\transformfont\space\space
525  <\font_family\font_weight\font_shape\raw_variant
526  \expert_encoding\font_width>~from~
527  <\font_family\font_weight\font_shape\raw_variant
528  \expert_encoding>~(faking~narrow)

529 } 530 ⟨/debug⟩

531  %%% WARNING: famtool.pl relies on this message format!!!
532  \immediate\write16{
533  Faking~narrow~font~
534  \font_family\font_weight\font_shape\raw_variant
535  \expert_encoding\font_width
536  \space from~
537  \font_family\font_weight\font_shape\raw_variant
538  \expert_encoding

539 }

540  \transformfont{
541  \font_family\font_weight\font_shape\raw_variant
542  \expert_encoding\font_width

543 }{

544  \xscalefont{\fake_narrow_width}{
545  \frommtx{
546  \font_family\font_weight\font_shape\raw_variant
547  \expert_encoding

549 } 550 }

551  \fi
552 \fi

553 }

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

554 \def\latin_encoding#1#2#3#4#5{
555 \gdef\latex_encoding{#4}
556 \gdef\latex_mtx{#5}
557 \if_oldstyle_
558  \gdef\font_encoding{#3}
559 \else\if_expert_
560  \gdef\font_encoding{#2}
561 \else
562  \gdef\font_encoding{#1}
563 \fi\fi
564 \gdef\expert_font{}
565 \gdef\oldstyle_font{}
566 \if_expert_
567  \if_file_exists{
568  \font_family\font_weight\raw_shape\raw_variant
569  \expert_encoding\font_width.mtx
570  }\then
571  \gdef\expert_font{
572  \font_family\font_weight\raw_shape\raw_variant
573  \expert_encoding\font_width,

574 }

575  \fi
576 \fi

577 ⟨∗oldstyle⟩

578 \if_oldstyle_
579  \if_file_exists{
580  \font_family\font_weight\raw_shape\oldstyle_variant
581  \raw_variant\raw_encoding\font_width.mtx
582  }\then
583  \gdef\oldstyle_font{
584  unsetnum,
585  \font_family\font_weight\raw_shape\oldstyle_variant
586  \raw_variant\raw_encoding\font_width,
587  resetosf,

588 }

589  \fi
590 \fi

591 ⟨/oldstyle⟩ 592 ⟨∗debug⟩

593 \immediate\write16{
594  INFO>~run~\string\installfont\space
595  <\font_family\font_weight\font_shape\font_variant
596  \font_encoding\font_width>
597  <\font_family\font_weight\raw_shape\raw_variant
598  \raw_encoding\font_width,
599  \if_oldstyle_
600  \ifx\raw_shape\caps_shape
601  resetosf,
602  \fi
603  \fi
604  \expert_font
605  \oldstyle_font
606  \latex_mtx>
607  <\latex_encoding\encoding_shape>
608  <\latex_encoding>
609  <\latex_family>
610  <\latex_weight\latex_width>
611  <\latex_shape>}

612 ⟨/debug⟩

613 \installfont{
614  \font_family\font_weight\font_shape\font_variant
615  \font_encoding\font_width

616 }{

617  \font_family\font_weight\raw_shape\raw_variant
618  \raw_encoding\font_width,
619  \if_oldstyle_
620  \ifx\raw_shape\caps_shape
621  resetosf,
622  \fi
623  \fi
624  \expert_font
625  \oldstyle_font
626  \latex_mtx

627 }{

628  \latex_encoding\encoding_shape

629 }{

630  \latex_encoding

631 }{

632  \latex_family

633 }{

634  \latex_weight\latex_width

635 }{

636  \latex_shape
637 }{}

638 }

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

639 \def\latin_weights{
640 \latin_weight{r}{m}
641 \latin_weight{k}{m}
642 \latin_weight{b}{b}
643 \latin_weight{s}{sb}
644 \latin_weight{d}{db} % was {d}{sb}, SPQR changed
645 \latin_weight{m}{mb} % was {m}{m},  UV changed
646 \latin_weight{c}{eb} % UV added
647 \latin_weight{h}{eb} % UV added
648 \latin_weight{x}{eb}
649 \latin_weight{u}{ub}
650 \latin_weight{l}{l}
651 %\latin_weight{j}{el}
652 %\latin_weight{a}{ul} % UV added

653 }

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.

654 \def\latin_widths{
655 \latin_width{}{}
656 \latin_width{n}{c}
657 %latin_width{c}{c}
658 %latin_width{x}{x}

659 }

\latin_shapes The fifth argument of \latin_shape is stored in the variable \encoding_switches.
660 \def\latin_shapes{
661 \latin_shape{} {} {} {n} {\_textcomp_true }
662 \latin_shape{c}{c}{} {sc}{\_textcomp_false}
663 \latin_shape{o}{o}{} {sl}{\_textcomp_true }
664 \latin_shape{i}{i}{i}{it}{\_textcomp_true }

665 }

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

set it as appropriate for the curent shape.

666 \def\latin_encodings{
667 \latin_encoding{7t}{9t}{9o}{OT1}{latin}
668 \latin_encoding{8t}{9e}{9d}{T1} {latin}

669 ⟨∗textcomp⟩

670 \encoding_switches
671 \if_textcomp_
672  \latin_encoding{8c}{9c}{9c}{TS1}{textcomp}
673 \fi

674 ⟨/textcomp⟩ 675 }

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

676 \newif\if_textcomp_

\raw_encoding
\adobe_encoding
\expert_encoding

677 \def\raw_encoding{8r}
678 \def\adobe_encoding{8a}
679 \def\expert_encoding{8x}
\caps_shape
\oldstyle_shape
680 \def\caps_shape{c}
681 \def\oldstyle_shape{j}
\SlantAmount
682 \def\SlantAmount{167}

683 ⟨/pkg⟩

File e

fimapgen.dtx

18 Generating map file fragments

A map file is a file which is used by some DVI driver to link various kinds of font information to each other, as is needed for the driver’s operation. Examples of such files are the file psfonts.map used by dvips and the config files of OzTEX. There are however many other such files around in the TEX world.

Not all of a map file need to be related to linking specific kinds of font information to each other. OzTEX config files can for example be used to set the values of TEX implementation parameters^{6} and there need not be any font-related information at all in them. The important thing is however that there can be map information in them—that information could be automatically written by the routines described here.

Since there may be other kinds of information in these files (and often enough need to be for everthing to work right), the routines described here will only generate map file fragments. These fragments will then have to be inserted in the final map files somehow, usually through manual editing. The purpose of the routines described here is only to save the user a good deal of (often quite boring) typing, not to actually install everything where it needs to be.

\mapfrags_subsystem This macro holds the name of the automatic map file fragments writer subsystem of fontinst, as it appears in error messages.

 1 \def\mapfrags_subsystem{Map~fragments~writer}

18.1 Interface to main fontinst

The automatic generation of map file fragments is based on the two commands \storemapdata and \makemapentry. Their respective syntaxes are

\storemapdata{⟨TEX font name⟩}{⟨source⟩}{⟨transforms⟩}

     \makemapentry{⟨TEX font name⟩}

\storemapdata \storemapdata commands are written when a metric file ⟨TEX font name⟩.mtx is generated. The purpose of these commands is to record where the data for that file came from, and what was done to these data. The source of the data is specified in the ⟨source⟩ argument, which can contain one of

\fromafm{⟨AFM name⟩}{⟨PS name⟩}

     \frompl{⟨PL name⟩}
     \frommtx{⟨MTX name⟩}
     \fromvpl

There is a difference between \fromvpl and the first three in that virtual fonts need no map file entry (and hence there should not be any either). Besides some error checking, \fromvpl causes a \makemapentry to do essentially nothing.

What was done to the data is specified by the ⟨transforms⟩ argument, which is a possibly empty sequence of commands, in which each item is one of \transformfont{⟨x-scale⟩}{⟨slant-scale⟩}{⟨y-scale⟩}

6The kind of things that were Pascal constants in the original Web sources for TEX.

     \reencodefont{⟨etx⟩}
     \reglyphfont

The order is interpreted so that the thing done first appear first in the sequence. In normal cases there is at most one of each, and then the order is not important. ⟨x-scale⟩, ⟨slant-scale⟩, and ⟨y-scale⟩ are the values of these variables used for the transformation, as TEX numbers. ⟨etx⟩ is the name of the ETX file used for the font reencoding. \reglyphfont is an error marker. It will not be encountered (but it may well get stored in some table) unless a metric font transform is applied to a font that has been reglyphed, which is illegal.

\makemapentry \makemapentry commands are written when a VPL that uses or a ligfull PL for a font is generated. These commands are the ones which actually cause the map file fragment generator to write an entry, but entries are only written if they haven’t been written before. \makemapentry uses information that was stored by a previous call to \storemapdata.

\storemapdata stores its arguments in one of the control sequences \Tf-⟨font⟩, where ⟨font⟩ is the same thing as ⟨TEX font name⟩ above. Tf stands for “TEX font”. The control sequences in this family are paramterless macros whose replacement texts have the following form:

{⟨source⟩}{⟨transforms⟩}{⟨made⟩}

Here ⟨source⟩ and ⟨transforms⟩ are exactly as above. ⟨made⟩ is either \if_false or \if_true in case a map file entry for the font in question has been written or not, respectively. These control sequences should always be set globally.

\recordtransforms \endrecordtransforms \transform_record_file In main fontinst, the command
     \recordtransforms{⟨filename⟩}

starts a block of code within which font transforms will be recorded in the file ⟨filename⟩. \endrecordtransforms ends such a block.

2 ⟨∗pkg⟩

 3 \def\recordtransforms#1{\open_pout\transform_record_file{#1}}
 4 \def\endrecordtransforms{
 5 \close_pout\transform_record_file{Font~transformation~records}
 6 }
 7 \chardef\transform_record_file=\closed_stream

8 ⟨/pkg⟩

\storemapdata There should not be two \storemapdata for the same font, hence the check below.

9 ⟨∗map⟩

10 \def\storemapdata#1#2#3{
11 \x_cs\ifx{Tf-#1}\x_relax \else
12  \fontinstwarning\mapfrags_subsystem{Font~#1~generated~again}
13 \fi
14 \x_cs\gdef{Tf-#1}{{#2}{#3}\if_true}

15 } 16 ⟨/map⟩

\record_transform In main fontinst, the call

\record_transform{⟨TFM name⟩}{⟨source⟩}{⟨transforms⟩} writes

\storemapdata{⟨TFM name⟩}{⟨source⟩}{⟨transforms⟩}

to the transformation recordings file, if font transforms are being recorded. Note that the caller of \record_transform must see to that macros in ⟨source⟩ and ⟨transforms⟩ are written correctly to the file (this is usually accomplished by adding \string in suitable places of these arguments during their construction).

17 ⟨∗pkg⟩

18 \def\record_transform#1#2#3{
19 \ifnum \transform_record_file=\closed_stream \else
20  \pout_line\transform_record_file{\string\storemapdata{#1}{#2}{#3}}
21 \fi

22 } 23 ⟨/pkg⟩

\transformfont \reencodefont \reglyphfont These are initially \relax, so they can be \edefed with safely.

24 ⟨∗map⟩

25 \let\transformfont\x_relax
26 \let\reencodefont\x_relax
27 \let\reglyphfont\x_relax
\makemapentry  \makemapentry sets \TeX_font_name, checks if any map data have been stored

for the font in question, and passes them on to \make_map_entry if they have; otherwise it raises an error. There is also a group which is begun and ended by \makemapentry, to stop values deduced for one entry to interfere with the deduction of values in the following.

28 \def\makemapentry#1{\begingroup
29 \def\TeX_font_name{#1}
30 \expandafter\let \expandafter\a_macro \csname Tf-#1\endcsname
31 \ifx\a_macro\x_relax
32  \from_unknown{#1}
33  \x_cs\gdef{Tf-#1}{{\from_unknown{#1}}{}\if_false}
34 \else
35  \expandafter\make_map_entry\a_macro
36 \fi
37 \endgroup

38 }

\make_map_entry \make_map_entry oversees the interpretation of the ⟨source⟩ part of the map data,

something which sets \source_font_TeX_name and possibly \PS_font_name. It

also stores the transforms in \font_transforms, calls a list macro \entry_makers_list which causes the actual entries to be written, and records in \Tf-⟨TEX font name⟩ that the entries have been written.

39 \def\make_map_entry#1#2#3{
40 #3
41  \def\font_transforms{#2}
42  #1
43  \begingroup
44  \_a_false
45  \let\transformfont\gobble_three
46  \let\reencodefont\gobble_one
47  \let\reglyphfont\_a_true

48  \font_transforms
49  \expandafter\endgroup \if_a_
50  \fontinsterror\mapfrags_subsystem{
51  \string\makemapentry\space for~reglyphed~font
52  }{ No~entry~for~font~\TeX_font_name\space
53  can~be~written,\messagebreak
54  since~it~had~been~reglyphed!~\error_help_a

55 }

56  \else
57  \entry_makers_list
58  \fi
59  \x_cs\gdef{Tf-\TeX_font_name}{{#1}{#2}\if_false}
60 \fi

61 } 62 ⟨/map⟩

\record_usage In main fontinst, the call

     \record_usage{⟨TFM name⟩}

writes

     \makemapentry{⟨TFM name⟩}

to the transformation recordings file, if font transforms are being recorded. The \record_usage command is, roughly speaking, only used by \installfont and

\installrawfont.

63 ⟨∗pkg⟩

64 \def\record_usage#1{
65 \ifnum \transform_record_file=\closed_stream \else
66  \pout_line\transform_record_file{\string\makemapentry{#1}}
67 \fi

68 } 69 ⟨/pkg⟩

\fromafm \fromafm saves its two arguments in the suitable string macros.

70 ⟨∗map⟩

71 \def\fromafm#1#2{
72 \def\source_font_TeX_name{#1}
73 \def\PS_font_name{#2}

74 }

\frompl \frompl saves its argument in the suitable string macro.

75 \def\frompl#1{
76 \def\source_font_TeX_name{#1}

77 }

\frommtx This one is tricky, since it will have to work recursively, fetching data that were stored for some other font.

78 \def\frommtx#1{%
79 \expandafter\let\expandafter\a_macro \csname Tf-#1\endcsname
80 \ifx \a_macro\x_relax
81  \from_unknown{#1}
82  \x_cs\gdef{Tf-#1}{{\from_unknown{#1}}{}\if_true}

 83 \else
 84  \expandafter\from_mtx \a_macro
 85 \fi

86 }

\from_mtx
 87 \def\from_mtx#1#2#3{
 88 \edef\font_transforms{#2\font_transforms}
 89 #1

90 }

\fromvpl The \fromvpl command checks if \font_transforms is empty. If it is then everything is fine, but no entry should be written for this font. If it isn’t then someone has tried to make a transformation of a virtual font, which doesn’t work.

 91 \def\fromvpl{
 92 \ifx \empty_command\font_transforms \else
 93  \fontinsterror\mapfrags_subsystem{
 94  Font~is~virtual,~it~cannot~be~transformed}{
 95  No~entry~for~font~\TeX_font_name\space can~be~written.
 96  \messagebreak\error_help_a

97 }

 98 \fi
 99 \let\maker_do\gobble_one

100 }

\AssumeMetafont The \AssumeMetafont general settings command makes \frompl behave like

 \fromvpl.
101 \def\AssumeMetafont{
102 \def\frompl{
103  \ifx \empty_command\font_transforms \else
104  \fontinsterror\mapfrags_subsystem{
105  A~Metafont~cannot~be~transformed}{
106  No~entry~for~font~\TeX_font_name\space can~be~written.
107  \messagebreak\error_help_a

108 }

109  \fi
110  \let\maker_do\gobble_one

111 } 112 }

\from_unknown This special value for ⟨source⟩ is used for fonts that are referenced by some \frommtx but which have no \storemapdata themselves.

113 \def\from_unknown#1{
114 \fontinstwarningnoline\mapfrags_subsystem{
115  No~map~data~stored~for~font~#1.\messagebreak
116  No~entry~for~\TeX_font_name\space will~be~written,\messagebreak
117  due~to~insufficient~information}
118 \global\G_unknown_source_true
119 \let\maker_do\gobble_one

120 }

18.2 User interface

The basic usage of the automatic map file fragment generator consists of specifying for which driver(s) entries should be generated, \inputing a file of recorded transformations generated by main fontinst, and signaling that there isn’t anything more to write. This can be done with the commands

\adddriver{⟨driver name⟩}{⟨fragment file name⟩}

⟨possible additional \adddriver commands⟩

\input ⟨recorded transforms file⟩

\donedrivers
\bye

It should however be noted that this is the basic usage. I imagine that there should be lots of ways in which the texts written can be configured—the various settings that might be needed on different systems are simply to diverse for one default setting to work everywhere! Some questions for starters are (and these are for dvips alone; that’s the driver I know best):

• Is the font resident on the printer or must it be downloaded?

• If the font must be downloaded, what is the name of the file it is in? Here one must take into account not only the possibility that the font file might have to be shared with some other software (such as a GUI) and thus cannot be named according to the Berry scheme—even if it is named according to the Berry scheme one still has the question of its extension: .pfa, .pfb, or something else? For instances of Multiple Master fonts, you (at least sometimes) have to download more than one file.

• Again if the font must be downloaded, can/should it be partially downloaded?

• In case the font has been reencoded, what is the name of the file which defines this encoding, and by what name does that file make the encoding known to the postscript interpreter? This question is rather easily solved by defining a table which lists a postscript encoding file name and object name for each ETX file, but there must be a user level interface for entering additional data in this table, in case the user defines an encoding of his or hers own.

I suspect map files for DVI viewers are on average more complicated than map files for DVI printer drivers, since the latter are more likely to be restricted to platform-specific font names.

An entry maker is a group of macros which write the entry for the font currently under consideration to a map fragments file each time they are called. The macro to call must have a name of the form \make_⟨driver⟩ for \adddriver to recognise it. Each entry maker has a separate output file (opened using \open_pout) and the identifier connected to that file is called \output_⟨driver⟩.

A list of all entry makers currently active is maintined in the macro \entry_makers_list. Each item in this list has the form

\maker_do\make_⟨driver⟩

\maker_do is usually \relax, but it does occationally get set to other values.

\adddriver The \adddriver command adds the named driver to the list of drivers to write entries for and opens an output file where the entries for that particular driver will go. Repeated calls to \adddriver for the same driver have no effect.

121 \def\adddriver#1#2{
122 \x_cs\ifx{make_#1}\x_relax
123  \fontinsterror\mapfrags_subsystem
124  {There~is~no~entry~maker~for~#1}\error_help_a
125 \else
126  \x_cs\ifx{output_#1}\x_relax \_a_true \else
127  \x_cs\ifx{output_#1}\closed_stream \_a_true \else
128  \_a_false
129  \fi\fi
130  \if_a_
131  \x_cs\open_pout{output_#1}{#2}
132  \expandafter\add_to \expandafter\entry_makers_list
133  \expandafter{ \expandafter\maker_do
134  \csname make_#1\endcsname}
135  \fi
136 \fi

137 }

\entry_makers_list
\maker_do
138 \let\entry_makers_list\empty_command
139 \let\maker_do\x_relax

\donedrivers The main function performed by the \donedrivers command is to close all the open output files. It might also prints some warning messages.

140 \def\donedrivers{
141 \def\maker_do##1{
142  \x_cs\close_pout{output\expandafter\gobble_five\string##1}
143  {Map~file~fragments}

144 }

145 \entry_makers_list
146 \let\maker_do\x_relax
147 \let\entry_makers_list\empty_command
148 \errorstopmode
149 \ifG_unknown_source_
150  \fontinstwarningnoline\mapfrags_subsystem{
151  Some~font~is~missing~from~the~output~file(s),\messagebreak
152  since~its~source~is~unknown}
153 \fi
154 \global\G_unknown_source_false
155 \if_undecided_
156  \fontinstwarningnoline\mapfrags_subsystem{
157  Check~the~output~file(s)--some~data~could~not~be~determined}
158 \fi
159 \_undecided_false
160 \if_uncertain_
161  \fontinstwarningnoline\mapfrags_subsystem{
162  Check~the~output~file(s)--some~data~was~considered~uncertain}

163 \fi
164 \_uncertain_false

165 }

\gobble_five
166 \def\gobble_five#1#2#3#4#5{}
\if_undecided_ \_undecided_true \_undecided_false This switch should be made true if a \clueless_str is written to some of the

output files.

167 \def\_undecided_true{\global\let\if_undecided_\iftrue}
168 \def\_undecided_false{\global\let\if_undecided_\iffalse}
169 \_undecided_false

\if_uncertain_ \_uncertain_true \_uncertain_false A value-determining macro can set this switch to true if it thinks that the value it just set its string to has a fair chance of being wrong. Hopefully, it shouldn’t have to be used too often.

170 \def\_uncertain_true{\global\let\if_uncertain_\iftrue}
171 \def\_uncertain_false{\global\let\if_uncertain_\iffalse}
172 \_uncertain_false

\ifG_unknown_source_ \G_unknown_source_true \G_unknown_source_false If at some point the named source for a font is unknown, this switch should be set to true. The G is because it should be set globally.

173 \newif\ifG_unknown_source_

18.3 Deducing values for the map file entries

18.3.1 Basic principles

The automatic generation of map file fragments mainly consists of determining various text strings and writing these to a file as the format of the map file being written requires. The complicated part is usually to determine what these text strings should be, since the only restriction imposed by the output format often is that the strings should be written in the right order and with separating whitespace.

It is furthermore the case that some of these text strings seem to be hard to deduce from the information primarily given in the command to write the entry, but somewhat easier to deduce from some other deduced text string.

Therefore the following model seems appropriate. For each text string that may need to be deduced, there is one macro which is used to store the string (if it has been deduced) and one macro which can be called to set the former macro to an appropriate value. Thus there is one macro \PS_font_name which stores the postscript name for the font currently in question and one macro \get_PS_font_name which determines the proper value for \PS_font_name.

\unknown_str There is also a macro \unknown_str to which all the string storing macros should initially be \let, so that it can be easily tested whether a string storing macro has been given its proper value or not.

Typically, if \PS_font_name is used somewhere, one would first have a piece of code that says

     \ifx\PS_font_name\unknown_str
        \get_PS_font_name
     \fi

to ensure that it is known when it is used.

\unknown_str A suitable value for this macro seems to be ?????.

174 \def\unknown_str{?????}

\clueless_str To further support this model, there is also a macro \clueless_str which a string storing macro should be \let equal to if its proper value could not be determined. This distinction is useful for the \get_… macros, since if \get_A can determine the correct value of A from B, but also from C, then it helps if \get_A can easily check whether it has previously turned out to be impossible to determine the value of B, because then it can simply deduce A from C instead.

175 \edef\clueless_str{\unknown_str ?}

An example of how \clueless_str should be used is the following skeleton of a \get_A macro:

     \def\get_A{
        \ifx\unknown_str\B \get_B \fi
        \ifx\clueless_str\B
           \ifx\unknown_str\C \get_C \fi
           \ifx\clueless_str\C
              \let\A\clueless_str
           \else

⟨Deduce A from C⟩

           \fi
        \else

⟨Deduce A from B⟩

        \fi
     }

18.3.2 Implementation

\TeX_font_name This is the name (as appearing in a DVI or VF file) of the font for which an entry should be made. It is set by \makemapentry, so no \get_… macro is needed.

176 \let\TeX_font_name\unknown_str

\source_font_TeX_name This is the name (as AFM or PL) of the font whose metrics were used by fontinst. It is set by \fromafm or \frompl, so no \get_… macro is needed.

177 \let\source_font_TeX_name\unknown_str

\PS_font_name This is the name (as FontName entry in an AFM or correspondingly) of the font in question.

178 \let\PS_font_name\unknown_str

\get_PS_font_name I expect this to become one of the central macros in the map file generation (at least when entries are generated for postscript fonts), but for the moment it does the closest thing to nothing a \get_… macro is allowed to do; it admits it hasn’t got a clue about what the proper value is.

179 \def\get_PS_font_name{\let\PS_font_name\clueless_str}

\AssumeAMSBSYY \AssumeBaKoMa These commands redefine \get_PS_font_name so that it returns the PS name

this font would have if it was part of the AMS/Blue Sky/Y&Y and BaKoMa respectively distribution of the Computer Modern fonts—the TEX font name in all upper case and all lower case respectively.

180 \def\AssumeAMSBSYY{\def\get_PS_font_name{
181 \expandafter\uppercase \expandafter{ \expandafter\def
182  \expandafter\PS_font_name \expandafter{ \source_font_TeX_name}

183 } 184 }}

185 \def\AssumeBaKoMa{\def\get_PS_font_name{
186 \expandafter\lowercase \expandafter{ \expandafter\def
187  \expandafter\PS_font_name \expandafter{ \source_font_TeX_name}

188 } 189 }}

\font_transforms This is argument #3 of \makemapentry. It is not a string, so its default value is

 not \unknown_str.
190 \let\font_transforms\empty_command

18.4 Driver makers

This subsection contains the definitions of macros that makes up the driver makers.

18.4.1 The debug driver

The debug driver maker doesn’t really generate entries for any DVI driver map file, it just prints the data that was available. It is mainly intended for debugging purposes, but it might also serve as a basic model for other driver makers.

\make_debug
191 \def\make_debug{
192 \pout_line\output_debug{Driver~data~for~font~\TeX_font_name:}
193 \pout_lline\output_debug{Source~font~TeX~name:~\source_font_TeX_name}
194 \ifx \font_transforms\empty_command
195  \pout_lline\output_debug{No~font~transforms~applied.}
196 \else
197  \pout_lline\output_debug{Font~transforms~applied:}
198  \bgroup
199  \let\reencodefont\debug_reencodefont
200  \let\transformfont\debug_transformfont
201  \let\reglyphfont\debug_reglyphfont
202  \font_transforms
203  \egroup
204 \fi
205 \debug_values_hook

206 }

\debug_reencodefont
207 \def\debug_reencodefont#1{
208 \pout_llline\output_debug{Font~reencoded~using~#1.etx.}

209 }

\debug_transformfont
210 \def\debug_transformfont#1#2#3{
211 \pout_llline\output_debug{Font~transformed~by~(
212  (\make_factor{#1}~\make_factor{#2})~(0.000~\make_factor{#3})).}

213 }

\debug_reglyphfont Remember that executing \reglyphfont is a sign that something is wrong.

214 \def\debug_reglyphfont{
215 \pout_llline\output_debug{ERROR!~Reglyphed~fonts~shouldn't~
216  appear~here!}
217 \fontinsterror\mapfrags_subsystem{
218  \string\reglyphfont\space encountered~among~font~transforms}
219  \error_help_d

220 }

\debug_value The \debug_value macro can be used to print the name and contents of an arbitrary value macro in the debug driver. It is called with the value macro as argument, e.g.

      \debug_value\PS_font_name
221 \def\debug_value#1{
222 \ifx #1\unknown_str
223  \csname get_\expandafter\gobble_one \string#1 \endcsname
224 \fi
225 \pout_lline\output_debug{\string#1:~#1}
226 \ifx #1\clueless_str \_undecided_true \fi

227 }

\debugvalue \debug_values_hook The \debugvalue command is a user level interface for adding value macros to the list of those that are displayed by the debug driver. The argument is the name of the value in question, e.g.

      \debugvalue{PS_font_name}

Note that the name given to \debugvalue is not the control sequence in which the name is stored.

228 \def\debugvalue#1{
229 \expandafter\add_to \expandafter\debug_values_hook
230 \expandafter{ \expandafter\debug_value \csname#1\endcsname}

231 }

232 \let\debug_values_hook\empty_command
233 \debugvalue{PS_font_name}

234 ⟨/map⟩

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.

Symbols

\_uncertain_false . . . . . . . . . . \underline{e-170}
\_uncertain_true . . . . . . . . . . . \underline{e-170}
\_undecided_false . . . . . . . . . . \underline{e-167}
\_undecided_true . . . . . . . . . . . \underline{e-167}

A

\add . . . . . . . . . . . . . . . . . . . . . . \underline{b-201} \add_to . . . . . . . . . . . . . . . . . . . \underline{a-237} \adddriver . . . . . . . . . . . . . . . . \underline{e-121} \adobe_encoding . . . . . . . . . . . . \underline{d-677} \afm_def . . . . . . . . . . . . . . . . . . \underline{c-118} \afm_font_name . . . . . . . . . . . . . \underline{c-151} \afm_length . . . . . . . . . . . . . . . . . \underline{c-99} \afm_let . . . . . . . . . . . . . . . . . . \underline{c-120} \afm_unit_dimen . . . . . . . . . . . . . \underline{c-99} \afmconvert . . . . . . . . . . . . . . . \underline{b-1188} \afmtomtx . . . . . . . . . . . . . . . \underline{c-66}, 92 \Aheading . . . . . . . . . . . . . . . . . \underline{a-194}

\allocate_stream . . . . . . . . . . . \underline{a-266}

Ambiguity . . . . . . . . . . . . . . . . 50, 99 \AMOUNT . . . . . . . . . . . . . . . . . . . . . 56

\assign_rboundary . . . . . . . . . \underline{b-1132}

\assign_slot . . . . . . . . . . . . . . \underline{b-1118} \AssumeAMSBSYY . . . . . . . . . . . . . \underline{e-180} \AssumeBaKoMa . . . . . . . . . . . . . . \underline{e-180} \AssumeMetafont . . . . . . . . . . . . \underline{e-101}

B

\bad_makerightboundary . . . . . \underline{b-1132}

\begincomment . . . . . . . . . . . . . . \underline{b-279} \Bheading . . . . . . . . . . . . . . . . . \underline{a-194} \body-NAME . . . . . . . . . . . . . . . . . . 44

\boundary_liglabel . . . . . . . . . \underline{b-1368}

\bracket . . . . . . . . . . . . . . . . . . \underline{b-245} \branches@else . . . . . . . . . . . . . \underline{a-374} \branches@fi . . . . . . . . . . . . . . . \underline{a-374} \branches@if . . . . . . . . . . . . . . . \underline{a-374} \branches@par . . . . . . . . . . . . . . \underline{a-374} \branches@type . . . . . . . . . . . . . \underline{a-374}

C

\caps_shape . . . . . . . . . . . . . . . . \underline{d-680} \ch@ck . . . . . . . . . . . . . . . . . . . . \underline{a-266} \close_out . . . . . . . . . . . . . . . . \underline{a-252} \close_pout . . . . . . . . . . . . . . . . \underline{a-293} \closed_stream . . . . . . . . . . . . . \underline{a-262} \clueless_str . . . . . . . . . . . . . . \underline{e-175}

\command_survivance . . . . . . . . . \underline{c-783}

\comment . . . . . . . . . . . . . . . . . . \underline{b-273} \count_hashes . . . . . . . . . . . . . . \underline{b-108} \curr_bearings . . . . . . . . . . . . \underline{b-1200}

D

\debug_reencodefont . . . . . . . . . \underline{e-207}
\debug_reglyphfont . . . . . . . . . . \underline{e-214}
\debug_transformfont . . . . . . . . \underline{e-210}

\debug_value . . . . . . . . . . . . . . . \underline{e-221}

\debug_values_hook . . . . . . . . . . \underline{e-228}

\debugvalue . . . . . . . . . . . . . . . . \underline{e-228}

\declareencoding . . . . . . . . . . \underline{b-1744}

\declaresize . . . . . . . . . . . . . . \underline{b-1760} \depth . . . . . . . . . . . . . . . . . . . . \underline{b-710} \DESIGNUNITS . . . . . . . . . . . . . . . \underline{c-346} \dim . . . . . . . . . . . . . . . . . . . . \underline{b-49}, 38 \div . . . . . . . . . . . . . . . . . . . . . . \underline{b-201} \do_boundary . . . . . . . . . . . . . . . \underline{b-338} \do_character . . . . . . . . . . . . . \underline{b-1411}

\do_character_map . . . . . . . . . \underline{b-1443}
\do_character_no_letterspacing .

. . . . . . . . . . . . . . . . . . . . \underline{b-1454}

\do_character_sidebearings . . \underline{b-1433}

\do_mapfont . . . . . . . . . . . . . . . \underline{b-1238} \do_slot . . . . . . . . . . . . . . . . . . \underline{b-325} \donedrivers . . . . . . . . . . . . . . . \underline{e-140}

E

\Else . . . . . . . . . . . . . . . . . . . . . \underline{a-361} \empty_command . . . . . . . . . . . . . \underline{a-211} \encoding . . . . . . . . . . . . . . . . . \underline{b-282}

\ENCODING-FAMILY . . . . . . . . . . . . . 84

\encoding_shape . . . . . . . . . . . . . \underline{d-70}

\encoding_switches . . . . . . . . . . . \underline{d-70}

\enctoext . . . . . . . . . . . . . . . . \underline{c-4}, 91

\end_assign_slot . . . . . . . . . . \underline{b-1118}
\end_do_character . . . . . . . . . \underline{b-1478}

\end_do_slot . . . . . . . . . . . . . . . \underline{b-325}

\end_vpl_varchar . . . . . . . . . . \underline{b-1493}

\endcomment . . . . . . . . . . . . . . . . \underline{b-279} \endencoding . . . . . . . . . . . . . . . \underline{b-282} \endfor . . . . . . . . . . . . . . . . . . . \underline{b-136}

\endinstallfonts . . . . . . . \underline{b-1617}, 84

\endmetrics . . . . . . . . . . . . . . . . \underline{b-439}

\endmetrics_text . . . . . . . . . . . \underline{b-439}
\endrecordtransforms . . . . . . . . . . \underline{e-2}
\endreglyphfonts . . . . . . . . . . . \underline{c-706}

\endresetglyph . . . . . . . . . . . . . \underline{b-782} \endsetglyph . . . . . . . . . . . . . . . \underline{b-782}

\endsetleftboundary . . . . . . . . . \underline{b-338}

\endsetslot . . . . . . . . . . . . . . . . \underline{b-315} \endvarchar . . . . . . . . . . . . . \underline{b-400}, 51

\entry_makers_list . . . . . . . . . . \underline{e-138}

\error_help_a . . . . . . . . . . . . . . \underline{a-573} \error_help_c . . . . . . . . . . . . . . \underline{a-573} \error_help_d . . . . . . . . . . . . . . \underline{a-573} \etx_to_font . . . . . . . . . . . . . . \underline{b-1067} \etxtopl . . . . . . . . . . . . . . \underline{b-1045}, 69 \etxtovpl . . . . . . . . . . . . . \underline{b-1045}, 69 \eval_expr . . . . . . . . . . . . . . . . \underline{b-189} \eval_expr_to . . . . . . . . . . . . . . \underline{b-189}

\expert_encoding . . . . . . . . . . . \underline{d-677}

\expression . . . . . . . . . . . . . . . . \underline{b-245}

F

\fake_shape_. . . . . . . . . . . . . . . . \underline{d-95} \fake_shape_c . . . . . . . . . . . . . . \underline{d-228}

\fake_shape_expert_encoding . . \underline{d-186}

\fake_shape_i . . . . . . . . . . . . . . \underline{d-419} \fake_shape_o . . . . . . . . . . . . . . \underline{d-245}

\fake_shape_o_expert_encoding   \underline{d-333}
\fake_shape_o_oldstyle_encoding .

. . . . . . . . . . . . . . . . . . . . . \underline{d-375}

\fake_shape_o_raw_encoding . . . \underline{d-263}
\fake_shape_oldstyle_encoding   \underline{d-198}
\fake_shape_raw_encoding . . . . . \underline{d-130}

\fake_width_. . . . . . . . . . . . . . . \underline{d-426} \fake_width_n . . . . . . . . . . . . . . \underline{d-428}

\fake_width_n_expert_encoding   \underline{d-512}
\fake_width_n_raw_encoding . . . \underline{d-442}

\fakenarrow . . . . . . . . . . . . . . . . \underline{d-422} \fd_family . . . . . . . . . . . . . . . \underline{b-1641} \fd_shape . . . . . . . . . . . . . . . . \underline{b-1677} \fd_size . . . . . . . . . . . . . . . . . \underline{b-1684} \Fi . . . . . . . . . . . . . . . . . . . . . . \underline{a-361} \fifth_of_six . . . . . . . . . . . . . . \underline{b-726} \first_char . . . . . . . . . . . . . . . . \underline{a-236} \first_of_six . . . . . . . . . . . . . . \underline{b-726} \first_of_two . . . . . . . . . . . . . . \underline{a-211} \font_count . . . . . . . . . . . . . . . \underline{b-1263} \font_encoding . . . . . . . . . . . . . \underline{d-554} \font_family . . . . . . . . . . . . . . . . \underline{d-18} \font_shape . . . . . . . . . . . . . . . . . \underline{d-70}

\font_transforms . . . . . . . . . . . \underline{e-190}

\font_variant . . . . . . . . . . . . . . . \underline{d-18} \font_weight . . . . . . . . . . . . . . . . \underline{d-60} \font_width . . . . . . . . . . . . . . . . . \underline{d-65} \fontinsterror . . . . . . . . . . . . . \underline{a-528} \fontinstinfo . . . . . . . . . . . . . . \underline{a-528}

\fontinstversion . . . . . . . . . . . . . \underline{a-7}
\fontinstwarning . . . . . . . . . . . \underline{a-528}

\fontinstwarningnoline . . . . . . \underline{a-528}

\for . . . . . . . . . . . . . . . . . . . . . . \underline{b-136} \for-NAME . . . . . . . . . . . . . . . . . . . 43 \foreach . . . . . . . . . . . . . . . . . . \underline{b-176} \foreach_i . . . . . . . . . . . . . . . . \underline{b-176} \four_spaces . . . . . . . . . . . . . . . \underline{a-572} \fourth_of_six . . . . . . . . . . . . . \underline{b-726} \from_mtx . . . . . . . . . . . . . . . . . . \underline{e-87} \from_unknown . . . . . . . . . . . . . . \underline{e-113} \fromafm . . . . . . . . . . \underline{c-516}, \underline{e-70}, 104 \fromany . . . . . . . . . . . . . . . . . . \underline{c-549} \frommtx . . . . . . . . . . \underline{c-523}, \underline{e-78}, 104 \frompl . . . . . . . . . . . \underline{c-527}, \underline{e-75}, 104 \fromplgivenetx . . . . . . . . . . . . \underline{c-527} \fromvpl . . . . . . . . . . . . . . \underline{c-539}, \underline{e-91}

\fromvplgivenetx . . . . . . . . . . . \underline{c-539}

G

\g-NAME . . . . . . . . . . . . . . . . . . . . . 61 \g_eval_expr_to . . . . . . . . . . . . \underline{b-189} \g_let . . . . . . . . . . . . . . . . . . . . \underline{a-205}

\G_unknown_source_false . . . . . \underline{e-173}
\G_unknown_source_true . . . . . . \underline{e-173}

\generalpltomtx . . . . . . . . . \underline{c-253}, 98

\generate_off_command . . . . . . . \underline{b-108}

\generic@if . . . . . . . . . . . . . . . . \underline{a-365} \generic_error . . . . . . . . . . . . . \underline{a-499} \generic_info . . . . . . . . . . . . . . \underline{a-486}

\generic_warning . . . . . . . . . . . \underline{a-493}

\get_file_name . . . . . . . . . . . . \underline{b-1633}

\get_PS_font_name . . . . . . . . . . \underline{e-179}

\get_slot_num . . . . . . . . . . . . . \underline{b-1144} \glyph . . . . . . . . . . . . . . . . . . . . \underline{b-863} \glyph_depth . . . . . . . . . . . . . . . \underline{b-747} \glyph_height . . . . . . . . . . . . . . \underline{b-747} \glyph_italic . . . . . . . . . . . . . . \underline{b-747}

\glyph_map_commands . . . . . . . . . \underline{b-747}
\glyph_map_fonts . . . . . . . . . . . \underline{b-747}

\glyph_maxhpos . . . . . . . . . . . . . \underline{b-747}

\glyph_parameter . . . . . . . . . . . \underline{b-726}

\glyph_voffset . . . . . . . . . . . . . \underline{b-747} \glyph_width . . . . . . . . . . . . . . . \underline{b-747} \glyphbboxright . . . . . . . . . . . \underline{b-1016} \glyphname . . . . . . . . . . . . . . . . . 115 \glyphpcc . . . . . . . . . . . . . . . . . \underline{b-998} \glyphrule . . . . . . . . . . . . . . . . \underline{b-899} \glyphspecial . . . . . . . . . . . . . . \underline{b-918} \glyphwarning . . . . . . . . . . . . . . \underline{b-918} \gobble_five . . . . . . . . . . . . . . . \underline{e-166} \gobble_glyph . . . . . . . . . . . . . . \underline{b-755} \gobble_if . . . . . . . . . . . . . . . . \underline{a-333} \gobble_one . . . . . . . . . . . . . . . . \underline{a-211} \gobble_setslot . . . . . . . . . . . \underline{b-1477} \gobble_three . . . . . . . . . . . . . . \underline{a-211}

\gobble_to_xrelax . . . . . . . . . . \underline{b-108}

\gobble_two . . . . . . . . . . . . . . . . \underline{a-211} \grabchars@ . . . . . . . . . . . . . . . . \underline{b-226} \grabchars@i . . . . . . . . . . . . . . . \underline{b-226} \grabchars@ii . . . . . . . . . . . . . . \underline{b-226} \grabchars@iii . . . . . . . . . . . . . \underline{b-226}

H

\hash_char . . . . . . . . . . . . . . . . \underline{a-219} \height . . . . . . . . . . . . . . . . . . . \underline{b-710}

I

\identity . . . . . . . . . . . . . . . . . \underline{b-245} \identity_one . . . . . . . . . . . . . . \underline{a-211} \if_expert_. . . . . . . . . . . . . . . . . \underline{d-58}

\if_fake_narrow_. . . . . . . . . . . \underline{d-420}

\if_false . . . . . . . . . . . . . . . . . \underline{a-329} \if_file_exists . . . . . . . . . . . . \underline{a-350}

\if_including_map_. . . . . . . . . \underline{b-1065}

\if_oldstyle_. . . . . . . . . . . . . . . \underline{d-58} \if_or . . . . . . . . . . . . . . . . . . . . \underline{a-339} \if_textcomp_. . . . . . . . . . . . . . \underline{d-676} \if_true . . . . . . . . . . . . . . . . . . \underline{a-329} \if_uncertain_. . . . . . . . . . . . . \underline{e-170} \if_undecided_. . . . . . . . . . . . . \underline{e-167}

\ifG_unknown_source_. . . . . . . . \underline{e-173}

\ifiscommand . . . . . . . . . . . . . \underline{b-63}, 38 \ifisdim . . . . . . . . . . . . . . . . \underline{b-63}, 38 \ifisglyph . . . . . . . . . . . . . . . \underline{b-1035} \ifisinslot . . . . . . . . . . . . . . . \underline{b-1163} \ifisint . . . . . . . . . . . . . . . . \underline{b-63}, 38 \ifiskern . . . . . . . . . . . . . . . . . \underline{b-623} \ifisstr . . . . . . . . . . . . . . . . \underline{b-63}, 38 \ifnumber . . . . . . . . . . . . . . . . . \underline{b-257} \iftokeep . . . . . . . . . . . . . . . . . . 112 \input_mtx_file . . . . . . . . . . . \underline{b-1624} \inputetx . . . . . . . . . . . . . . \underline{b-282}, 48 \inputmtx . . . . . . . . . . . . . . \underline{b-439}, 54 \install_font . . . . . . . . . . . . . \underline{b-1591} \installfamily . . . . . . . . . \underline{b-1579}, 84 \installfont . . . . . . . . . . . \underline{b-1584}, 84 \installfonts . . . . . . . . . . \underline{b-1573}, 84 \installrawfont . . . . . . . . \underline{b-1584}, 84 \int . . . . . . . . . . . . . . . . . . . . \underline{b-49}, 38

\italcorr_expression . . . . . . . . . . 96

\italic . . . . . . . . . . . . . . . . . . . \underline{b-710}

\italicslant_name . . . . . . . . . . \underline{c-640}

K

\k . . . . . . . . . . . . . . . . . . . . . . . . . 56 \kerning . . . . . . . . . . . . . . . . . . \underline{b-611} \kill_glyph . . . . . . . . . . . . . . . . \underline{c-784} \killglyph . . . . . . . . . . . . \underline{c-731}, 113

\killglyphweighted . . . . . . \underline{c-731}, 113

L

\l-NAME . . . . . . . . . . . . . . . . . . . . . 56 \latex_encoding . . . . . . . . . . . . \underline{d-554} \latex_mtx . . . . . . . . . . . . . . . . \underline{d-554} \latex_shape . . . . . . . . . . . . . . . . \underline{d-70} \latex_variant . . . . . . . . . . . . . . \underline{d-18} \latex_weight . . . . . . . . . . . . . . . \underline{d-60} \latex_width . . . . . . . . . . . . . . . . \underline{d-65} \latin_encoding . . . . . . . . . . . . \underline{d-554}

\latin_encodings . . . . . . . . . . . \underline{d-666}

\latin_shape . . . . . . . . . . . . . . . . \underline{d-70} \latin_shapes . . . . . . . . . . . . . . \underline{d-660} \latin_weight . . . . . . . . . . . . . . . \underline{d-60} \latin_weights . . . . . . . . . . . . . \underline{d-639} \latin_width . . . . . . . . . . . . . . . . \underline{d-65} \latin_widths . . . . . . . . . . . . . . \underline{d-654} \latinfamily . . . . . . . . . . . . . . . . . \underline{d-1}

\left_brace_char . . . . . . . . . . . \underline{a-219}

\ligature . . . . . . . . . . . . . . \underline{b-361}, 51 \lose_measure . . . . . . . . . . . . . . \underline{a-231}

M

\make_assignments . . . . . . . . . \underline{b-1102}
\make_characters . . . . . . . . . . \underline{b-1383}

\make_debug . . . . . . . . . . . . . . . . \underline{e-191} \make_factor . . . . . . . . . . . . . . . \underline{a-451} \make_factor_i . . . . . . . . . . . . . \underline{a-459} \make_factor_ii . . . . . . . . . . . . \underline{a-467}

\make_factor_iii . . . . . . . . . . . \underline{a-474}
\make_fontdimens . . . . . . . . . . \underline{b-1266}

\make_header . . . . . . . . . . . . . . \underline{b-1202} \make_ligtable . . . . . . . . . . . . \underline{b-1284} \make_map_entry . . . . . . . . . . . . . \underline{e-39} \make_mapfonts . . . . . . . . . . . . \underline{b-1229} \make_tidy . . . . . . . . . . . . . . . \underline{b-1562} \makemapentry . . . . . . . . . . . \underline{e-28}, 139 \maker_do . . . . . . . . . . . . . . . . . \underline{e-138}

\makerightboundary . . . . . . . \underline{b-389}, 51

\mapcommands . . . . . . . . . . . . . . . \underline{b-722} \mapfonts . . . . . . . . . . . . . . . . . \underline{b-722}

\mapfrags_subsystem . . . . . . . . . . . \underline{e-1}

\max . . . . . . . . . . . . . . . . . . . . . . \underline{b-201} \messagebreak . . . . . . . . . . . . . . \underline{a-484} \metrics . . . . . . . . . . . . . . . . . . \underline{b-439} \min . . . . . . . . . . . . . . . . . . . . . . \underline{b-201} \movert . . . . . . . . . . . . . . . . . . . \underline{b-936} \moveup . . . . . . . . . . . . . . . . . . . \underline{b-936} \mtxtomtx . . . . . . . . . . . . . \underline{c-605}, 109

\mtxtomtx_endsetglyph . . . . . . . \underline{c-694}
\mtxtomtx_glyphpcc . . . . . . . . . . \underline{c-697}
\mtxtomtx_samesize . . . . . . . . . . \underline{c-694}
\mtxtomtx_setdim . . . . . . . . . . . \underline{c-655}
\mtxtomtx_setglyph . . . . . . . . . . \underline{c-694}
\mtxtomtx_setint . . . . . . . . . . . \underline{c-640}

\mtxtomtx_setkern . . . . . . . . . . \underline{c-690}
\mtxtomtx_setrawglyph . . . . . . . \underline{c-661}
\mtxtomtx_setstr . . . . . . . . . . . \underline{c-655}

\mtxtopl . . . . . . . . . . . . . . \underline{c-442}, 103 \mul . . . . . . . . . . . . . . . . . . . . . . \underline{b-201}

N

\needsfontinstversion . . . . . . . . \underline{a-22}

\neg . . . . . . . . . . . . . . . . . . . . . . \underline{b-201} \never_do . . . . . . . . . . . . . . . . . \underline{a-251} \next_mapfont . . . . . . . . . . . . . \underline{b-1263} \nextlarger . . . . . . . . . . . . . \underline{b-389}, 51 \nextslot . . . . . . . . . . . . . . . . . \underline{b-329} \no_kerning . . . . . . . . . . . . . . . . \underline{b-684} \no_kerning_i . . . . . . . . . . . . . . \underline{b-699} \no_kerning_ii . . . . . . . . . . . . . \underline{b-705} \NOFILES . . . . . . . . . . . . . . . . . \underline{b-1774} \noleftkerning . . . . . . . . . . . . . \underline{b-668}

\noleftrightkerning . . . . . . . . . \underline{b-668}

\norightkerning . . . . . . . . . . . . \underline{b-668} Not in doc

\dim . . . . . . . . . . . . . . . . . . . . . 40 \endfor . . . . . . . . . . . . . . . . . . 44 \for . . . . . . . . . . . . . . . . . . . . . 44 \foreach . . . . . . . . . . . . . . . . . 44 \offcommand . . . . . . . . . . . . . . . 42 \oncommand . . . . . . . . . . . . . . . . 42 \str . . . . . . . . . . . . . . . . . . . . . 40 \strint . . . . . . . . . . . . . . . . . . 40 \unsetcommand . . . . . . . . . . . . . 41 \unsetdim . . . . . . . . . . . . . . . . . 41 \unsetglyph . . . . . . . . . . . . . . . 65 \unsetint . . . . . . . . . . . . . . . . . 41 \unsetstr . . . . . . . . . . . . . . . . . 41 \usedas . . . . . . . . . . . . . . . . . . 52

\notdef_name . . . . . . . . . . . . . . \underline{b-1483}

O

\off-\reglyph_setglyph . . . . . . \underline{c-812}

\off-COMMAND . . . . . . . . . . . . . . . . . 41 \offcommand . . . . . . . . . . . . . . . . . \underline{b-89} \offmtxcommand . . . . . . . . . \underline{c-713}, 112 \oldstyle_shape . . . . . . . . . . . . \underline{d-680} \on_line . . . . . . . . . . . . . . . . . . \underline{a-570} \oncommand . . . . . . . . . . . . . . . . . \underline{b-89} \onmtxcommand . . . . . . . . . . \underline{c-713}, 112 \open_out . . . . . . . . . . . . . . . . . \underline{a-252} \open_pout . . . . . . . . . . . . . . . . \underline{a-293} \or_else . . . . . . . . . . . . . . . . . . \underline{a-339} \out_file . . . . . . . . . . . . . . . . . \underline{a-181}

\out_filename--1 . . . . . . . . . . . \underline{a-262}
\out_filename-99 . . . . . . . . . . . \underline{a-262}
\out_filename-STREAM . . . . . . . . . . 25

\out_liglabel . . . . . . . . . . . . . \underline{b-1368} \out_ligstop . . . . . . . . . . . . . . \underline{b-1379} \out_line . . . . . . . . . . . . . . . . . \underline{a-252} \out_lline . . . . . . . . . . . . . . . . \underline{a-252} \out_llline . . . . . . . . . . . . . . . . \underline{a-252}

P

\parse_family . . . . . . . . . . . . . . . \underline{d-18} \percent_char . . . . . . . . . . . . . . \underline{a-219} \pl_raw_glyph . . . . . . . . . . . . . . \underline{c-469} \pl_to_mtx . . . . . . . . . . . . . . . . \underline{c-263} \plaindiv . . . . . . . . . . . . . . . . . \underline{a-202} \plainint . . . . . . . . . . . . . . . . . \underline{a-202} \pltomtx . . . . . . . . . . . . . . . \underline{c-262}, 98 \pop . . . . . . . . . . . . . . . . . . . . . . \underline{b-965}

\post_first_etx_pass_hook . . . \underline{b-1093}
\post_fourth_etx_pass_hook . . \underline{b-1093}
\post_second_etx_pass_hook . . \underline{b-1093}
\post_third_etx_pass_hook . . . \underline{b-1093}

\pout_line . . . . . . . . . . . . . 25, \underline{a-321} \pout_lline . . . . . . . . . . . . . . . . \underline{a-322} \pout_llline . . . . . . . . . . . . . . . \underline{a-322}

\pre_first_etx_pass_hook . . . . \underline{b-1093}
\pre_fourth_etx_pass_hook . . . \underline{b-1093}
\pre_second_etx_pass_hook . . . \underline{b-1093}
\pre_third_etx_pass_hook . . . . \underline{b-1093}

\prep_to . . . . . . . . . . . . . . . . . . \underline{a-244} \prev_mapfont . . . . . . . . . . . . . \underline{b-1263} \primitiveinput . . . . . . . . . . . . \underline{a-417}

\print@csep@list . . . . . . . . . . . \underline{a-434}

\priority . . . . . . . . . . . . . . . . . \underline{b-245}

\process_csep_list . . . . . . . \underline{a-423}, 31
\ProvidesMtxPackage . . . . . . . . . \underline{b-467}

\PS_font_name . . . . . . . . . . . . . . \underline{e-178} \push . . . . . . . . . . . . . . . . . . . . . \underline{b-965}

Q

Question . . . . . . . . . . . . . . . . . . . . 97

R

\r-NAME . . . . . . . . . . . . . . . . . . . . . 56 \raw_encoding . . . . . . . . . . . . . . \underline{d-677} \raw_shape . . . . . . . . . . . . . . . . . \underline{d-70} \raw_variant . . . . . . . . . . . . . . . . \underline{d-18}

\record_transform . . . . . . . . . . . \underline{e-17}

\record_usage . . . . . . . . . . . . . . . \underline{e-63}

\recordtransforms . . . . . . . . . . . . \underline{e-2}

\reencodefont . . . . . . \underline{c-578}, \underline{e-24}, 104

\reglyph_endsetglyph . . . . . . . . \underline{c-812}

\reglyph_font . . . . . . . . . . . . . . \underline{c-750}

\reglyph_glyphpcc . . . . . . . . . . \underline{c-812}
\reglyph_samesize . . . . . . . . . . \underline{c-812}

\reglyph_setdim . . . . . . . . . . . . \underline{c-780}

\reglyph_setglyph . . . . . . . . . . \underline{c-812}

\reglyph_setint . . . . . . . . . . . . \underline{c-780}

\reglyph_setkern . . . . . . . . . . . \underline{c-801}

\reglyph_setrawglyph . . . . . . . . \underline{c-786}

\reglyph_setstr . . . . . . . . . . . . \underline{c-780} \reglyphfont . . . . . . . \underline{c-741}, \underline{e-24}, 112 \reglyphfonts . . . . . . . . . . . . . . \underline{c-706} \remove_shape . . . . . . . . . . . . . \underline{b-1691} \rename_glyph . . . . . . . . . . . . . . \underline{c-784} \renameglyph . . . . . . . . . . . \underline{c-719}, 112

\renameglyphweighted . . . . \underline{c-719}, 112

\resetcommand . . . . . . . . . . . . \underline{b-25}, 38 \resetdepth . . . . . . . . . . . . . . . . \underline{b-986} \resetdim . . . . . . . . . . . . . . . \underline{b-25}, 38 \resetglyph . . . . . . . . . . . . . . . . \underline{b-768} \resetheight . . . . . . . . . . . . . . . \underline{b-986} \resetint . . . . . . . . . . . . . . . \underline{b-25}, 38 \resetitalic . . . . . . . . . . . . . . . \underline{b-986} \resetkern . . . . . . . . . . . . . . . . \underline{b-537}

\resetslotcomment . . . . . . . . . . \underline{b-416}

\resetstr . . . . . . . . . . . . . . . \underline{b-25}, 38 \resetwidth . . . . . . . . . . . . . . . . \underline{b-986}

\right_brace_char . . . . . . . . . . \underline{a-219}
\rounded_thousandths . . . . . . . . \underline{b-194}

S

\samesize . . . . . . . . . . . . . . . . \underline{b-1018} \saved-COMMAND . . . . . . . . . . . . . . . 41

\saved@slot@number . . . . . . . . . . \underline{a-373}

\saved_mapfont . . . . . . . . . . . . . \underline{b-737} \saved_movert . . . . . . . . . . . . . . \underline{b-737} \saved_moveup . . . . . . . . . . . . . . \underline{b-737} \saved_pop . . . . . . . . . . . . . . . . \underline{b-737} \saved_push . . . . . . . . . . . . . . . . \underline{b-737} \saved_raw . . . . . . . . . . . . . . . . \underline{b-737} \saved_rule . . . . . . . . . . . . . . . . \underline{b-737} \saved_scale . . . . . . . . . . . . . . . \underline{b-737} \saved_special . . . . . . . . . . . . . \underline{b-737} \saved_warning . . . . . . . . . . . . . \underline{b-737} \scale . . . . . . . . . . . . . . . . . . . . \underline{b-226} \scale-500X . . . . . . . . . . . . . . . . \underline{b-226} \scale-FACTOR . . . . . . . . . . . . . . . . 46

\scaled_design_size . . . . . . . . \underline{b-1188}

\scalefont . . . . . . . . . . . . \underline{c-578}, 104 \second_of_six . . . . . . . . . . . . . \underline{b-726} \second_of_two . . . . . . . . . . . . . \underline{a-211} \setcommand . . . . . . . . . . . . . . . \underline{b-1}, 38 \setdim . . . . . . . . . . . . . . . . . . \underline{b-1}, 38 \setglyph . . . . . . . . . . . . . . . . . \underline{b-755} \setint . . . . . . . . . . . . . . . . . . \underline{b-1}, 38 \setkern . . . . . . . . . . . . . . . . . . \underline{b-511}

\setleftboundary . . . . . . . . . . . \underline{b-338}

\setleftkerning . . . . . . . . . . . . \underline{b-563}

\setleftrightkerning . . . . . . . . \underline{b-563}

\setnotglyph . . . . . . . . . . . . . . . \underline{b-831} \setrawglyph . . . . . . . . . . . . . . . \underline{b-795}

\setrightboundary . . . . . . . . . . \underline{b-349}

                                       \setrightkerning . . . . . . . . . . . \underline{b-563}

\setslot . . . . . . . . . . . . . . . . . . \underline{b-315} \setslotcomment . . . . . . . . . . . . \underline{b-416} \setstr . . . . . . . . . . . . . . . . . . \underline{b-1}, 38 \showbranches . . . . . . . . . . . . . . \underline{a-365} \side_bearings . . . . . . . . . . . . \underline{b-1200} \sixth_of_six . . . . . . . . . . . . . . \underline{b-726} \skipslots . . . . . . . . . . . . . . . . \underline{b-329} \SlantAmount . . . . . . . . . . . . . . . \underline{d-682}

                                       \slanteditalcorr . . . . . . . . . . . \underline{c-213}

\slantfont . . . . . . . . . . . . \underline{c-578}, 104 \slot@comment . . . . . . . . . . . . . . \underline{b-416} \slot@font . . . . . . . . . . . . . . . . \underline{b-416} \slot@name . . . . . . . . . . . . . . . . \underline{b-315} \slot@number . . . . . . . . . . . . . . . \underline{b-329} \slot_name . . . . . . . . . . . . . . . . \underline{b-315} \slot_number . . . . . . . . . . . . . . . \underline{b-329} \slotexample . . . . . . . . . . . . . . . \underline{b-416} \slots-GLYPH . . . . . . . . . . . . . . 71, 113

                                       \source_font_TeX_name . . . . . . . \underline{e-177}

\storemapdata . . . . . . . . . . . . \underline{e-9}, 138 \str . . . . . . . . . . . . . . . . . . . . \underline{b-49}, 38 \strint . . . . . . . . . . . . . . . . . \underline{b-49}, 38 \sub . . . . . . . . . . . . . . . . . . . . . . \underline{b-201}

                                       \substitute_series . . . . . . . . . \underline{b-1711}
                                       \substitute_shape . . . . . . . . . \underline{b-1694}
                                       \substitutenoisy . . . . . . . . . . \underline{b-1727}
                                       \substitutesilent . . . . . . . . . \underline{b-1727}

T \temp_prefix . . . . . . . . . . . . . . . \underline{a-326} \tempfileprefix . . . . . . . . . . . . \underline{a-326} \TeX_font_name . . . . . . . . . . . . . \underline{e-176} \TeX_terminal . . . . . . . . . . . . . . \underline{a-262} \then . . . . . . . . . . . . . . . . . . . . . \underline{a-329} \third_of_six . . . . . . . . . . . . . . \underline{b-726}

                                       \tidying_up_hook . . . . . . . . . . \underline{b-1093}

\touch_file . . . . . . . . . . . . . . . \underline{b-1791}

                                       \transform_record_file . . . . . . . . \underline{e-2}

\transformfont . . . . . \underline{c-482}, \underline{e-24}, 104 \typeset@dimen . . . . . . . . . . . . . . \underline{b-57} \typeset@glyph . . . . . . . . . . . . . \underline{b-709}

                                       \typeset@integer . . . . . . . . . . . . \underline{b-57}

\typeset@string . . . . . . . . . . . . . \underline{b-57}

U \unknown_str . . . . . . . . . . . \underline{e-174}, 145 \unsetcommand . . . . . . . . . . . . \underline{b-81}, 38 \unsetdim . . . . . . . . . . . . . . . \underline{b-81}, 38 \unsetglyph . . . . . . . . . . . . . . . . \underline{b-862} \unsetint . . . . . . . . . . . . . . . \underline{b-81}, 38 \unsetkerns . . . . . . . . . . . . . . . . \underline{b-636}

                                       \unsetslotcomment . . . . . . . . . . \underline{b-416}

\unsetstr . . . . . . . . . . . . . . . \underline{b-81}, 38

                                       \uprightitalcorr . . . . . . . . . . . \underline{c-213}

\usedas . . . . . . . . . . . . . . . . \underline{b-389}, 51 \useexamplefont . . . . . . . . . . . . \underline{b-416} \usemtxpackage . . . . . . . . . . . . . \underline{b-473}

V

\varbot . . . . . . . . . . . . . . . . \underline{b-400}, 52 \varchar . . . . . . . . . . . . . . . \underline{b-400}, 51 \varmid . . . . . . . . . . . . . . . . \underline{b-400}, 52 \varrep . . . . . . . . . . . . . . . . \underline{b-400}, 52 \vartop . . . . . . . . . . . . . . . . \underline{b-400}, 52 \vpl_int . . . . . . . . . . . . . . . . . \underline{b-1198} \vpl_kern . . . . . . . . . . . . . . . . \underline{b-1349} \vpl_kern_do . . . . . . . . . . . . . . \underline{b-1361} \vpl_kerning . . . . . . . . . . . . . . \underline{b-1343} \vpl_ligature . . . . . . . . . . . . . \underline{b-1324} \vpl_liglabel . . . . . . . . . . . . . \underline{b-1368} \vpl_ligstop . . . . . . . . . . . . . . \underline{b-1379} \vpl_mapfont . . . . . . . . . . . . . . \underline{b-1250} \vpl_movert . . . . . . . . . . . . . . . \underline{b-1552} \vpl_moveup . . . . . . . . . . . . . . . \underline{b-1552} \vpl_nextlarger . . . . . . . . . . . \underline{b-1484} \vpl_pop . . . . . . . . . . . . . . . . . \underline{b-1560} \vpl_push . . . . . . . . . . . . . . . . \underline{b-1560} \vpl_raw . . . . . . . . . . . . . . . . . \underline{b-1531}

\vpl_rboundary_do . . . . . . . . . \underline{b-1311}
\vpl_rbserver_do . . . . . . . . . . \underline{b-1311}

\vpl_real . . . . . . . . . . . . . . . . \underline{b-1198} \vpl_rule . . . . . . . . . . . . . . . . \underline{b-1541} \vpl_scale . . . . . . . . . . . . . . . \underline{b-1243} \vpl_special . . . . . . . . . . . . . . \underline{b-1546} \vpl_varbot . . . . . . . . . . . . . . . \underline{b-1513} \vpl_varchar . . . . . . . . . . . . . . \underline{b-1493} \vpl_varmid . . . . . . . . . . . . . . . \underline{b-1504} \vpl_varrep . . . . . . . . . . . . . . . \underline{b-1522} \vpl_vartop . . . . . . . . . . . . . . . \underline{b-1495} \vpl_warning . . . . . . . . . . . . . . \underline{b-1546}

W \width . . . . . . . . . . . . . . . . . . . . \underline{b-710}

                                       \wrn_rboundary_do . . . . . . . . . \underline{b-1311}

X \x@relax . . . . . . . . . . . . . . . . . . \underline{a-210} \x_cs . . . . . . . . . . . . . . . . . . . . . \underline{a-205} \x_relax . . . . . . . . . . . . . . . . . . \underline{a-205} \x_resetint . . . . . . . . . . . . . . \underline{b-25}, 39 \x_setint . . . . . . . . . . . . . . . . \underline{b-1}, 39 \x_setstr . . . . . . . . . . . . . . . . \underline{b-1}, 39 \xscalefont . . . . . . . . . . . . \underline{c-578}, 104

Y \yscalefont . . . . . . . . . . . . \underline{c-578}, 104

Change History

v 1.6

General: AFM commands fixed, to get fontdimens comparable to EC fonts.

(Thierry Bouche) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 \fromany: Search order changed to PL before AFM. (SPQR) The code wasn’t in

\fromany back then, though. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 v 1.800

General:

\textcompfamily integrated into \latinfamily. (UV) . . . . . . . . . . . . . . . 120

     fontinst.sty and fontdoc.sty now generated from fontinst.dtx. (UV) . 17

v 1.900

General:

VPL-specific properties added to those which are ignored by \pltomtx. (LH) 100 New method of storing slot assignments. (LH) . . . . . . . . . . . . . . . . . . . . . . 71 Added compability code for the old interface for boundary ligatures and kerns. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Method of computing italic corrections changed to using an integer expression. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 fontinst.dtx split into several source files. (LH) . . . . . . . . . . . . . . . . . . . 17 Replaced \relax by \x_relax. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Replaced \resetint by \x_resetint. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 39 Replaced \setint by \x_setint. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Replaced \setstr by \x_setstr. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 \afm_length: Macro added, other macros modified to use it. (LH) . . . . . . . . . 93 \encoding: Changed group in fontdoc to \begingroup type. (LH) . . . . . . . . . 48 \endencoding: Made it outer. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 \endmetrics: Made it outer. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 \get_file_name: Changed \setint to \resetint. (LH) . . . . . . . . . . . . . . . . 86 \glyph: Avoids scaling by 1000. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 \gobble_if: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 \install_font: Use \process_csep_list for file-list. (LH) . . . . . . . . . . . . . . 85

\make_header:

Made integer expression \div a dimen \divide. (LH) . . . . . . . . . . . . . . . . . 75 Removed test for no letterspacing. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 75

\slot@number: Made changes of \slot@number global. (LH) . . . . . . . . . . . . . 50

\vpl_kern:

Macro modified to avoid duplicate kerns. (LH) . . . . . . . . . . . . . . . . . . . . . . 78 Much of the code from \vpl_kern has been moved to \vpl_kern_do. (LH) . 78

v 1.901

General:

Definition of transformable metric file added. (LH) . . . . . . . . . . . . . . . . . . 104 Pooled output file allocation added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 25 Added a temporary switch \if_a_. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . 22

\afm_font_name: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 \foreach: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

\gobble_setslot: Made \gobble_setslot a \long macro. (LH) . . . . . . . . . . 81

\min: Using \rounded_thousands in \scale. (LH) . . . . . . . . . . . . . . . . . . . . 46 \open_out: \xdef instead of \def on \out_filename. (LH) . . . . . . . . . . . . . . 25

v 1.902

General:

Fixed some silly markup. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Collected the material in Section 15 and moved it to ficonv.dtx. /LH …. 91 Moved Section 16 to ficonv.dtx. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Moved Section 8 to fibasics.dtx. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . 23

\fromplgivenetx: Command added. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . 106 \fromvpl: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 \fromvplgivenetx: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 106 \generalpltomtx: Command added, removed \pltomtxgivenetx. (LH) . . . . . 98

v 1.903

General: Introduced the \⟨letter⟩_macro temporary variables, replaced

\temp_command. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

\fromany:

Command added. (LH) Based on a suggestion by Vladimir Volovich. . . . . 106 Added behaviour for AFM not found case. (LH) . . . . . . . . . . . . . . . . . . . 106

\glyph_maxhpos: Variable added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 \glyphbboxright: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 \make_factor: Added this macro. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 \movert: Added update of \glyph_maxhpos. (LH) . . . . . . . . . . . . . . . . . . . . . 66 \pop: Added update of \glyph_maxhpos. (LH) . . . . . . . . . . . . . . . . . . . . . . . 67 \reglyphfont: Using \fromany for locating font. (LH) . . . . . . . . . . . . . . . . 114 \samesize: Added behaviour for nonexistent glyph (based on a suggestion from

Hilmar Schlegel) and fixed typo in fontdoc. (LH) . . . . . . . . . . . . . . . . . . . 68 \transformfont: Added behaviour for the case source file not found. (LH) . . 105

v 1.904

General:

Font transformation recordings moved to fimapgen.dtx, so that the interface will be specified in a single place. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Completed rudimentary map file fragment generator, made it part of finstmsc.sty. /LH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 \fromafm: Added call of \record_transform. (LH) . . . . . . . . . . . . . . . . . . . 106 \fromany: Added search for VPL file and calls to \record_transform. (LH) . 106 \frompl: Added call of \record_transform. (LH) . . . . . . . . . . . . . . . . . . . . 106 \fromplgivenetx: Added call of \record_transform. (LH) . . . . . . . . . . . . . 106 \fromvpl: Command removed. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 \fromvplgivenetx: Command removed. (LH) . . . . . . . . . . . . . . . . . . . . . . . 106

\input_mtx_file:

Now using \fromany to make an MTX file when necessary. (LH) . . . . . . . . . 85 Testing for empty argument using \ifx rather than \if. (LH) . . . . . . . . . . 85

\installrawfont: Added \record_usage. (LH) . . . . . . . . . . . . . . . . . . . . . . 84 \pout_lline: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 \pout_llline: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 \reglyphfont: Added \record_transform. (LH) . . . . . . . . . . . . . . . . . . . . 114 \vpl_mapfont: Added \record_usage. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 75

v 1.905 General: Different config file for finstmsc.sty. (LH) . . . . . . . . . . . . . . . . . . . 20 \DESIGNUNITS: Error message added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 100

v 1.906

General:

Adaptation of L^{A}TEX’s message system completed. (LH) . . . . . . . . . . . . . . . 34 Reglyphing settings files added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

\no_kerning:

Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Macro thoroughly rewritten. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

\noleftkerning: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 \noleftrightkerning: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 60 \norightkerning: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

v 1.907 \end_assign_slot: Slots are not assigned to glyphs that do not exist. (LH) . . 72 \pop: Removed the \edef. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 \push: Removed the \edef. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

v 1.908

General: Glyph commands avoid \edefing old contents of \glyph_map_commands

and \glyph_map_fonts. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 \out_lline: \edef, to save macro expansions later. (LH) . . . . . . . . . . . . . . . 25 \out_llline: \edef and don’t use \out_lline, to save macro expansions later.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 \pout_lline: \edef, to save macro expansions later. (LH) . . . . . . . . . . . . . . 27 \pout_llline: \edef and don’t use \pout_lline, to save macro expansions

later. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 v 1.909

General: System for documenting both branches of if statements in ETX and

MTX files added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

\Aheading:

Use \addvspace to make space above. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 23 Insert a \penalty for pagebreaking after an \Aheading. (LH) . . . . . . . . . . . 23

\div: Changed priority of numerator, so that unnecessary bracketing is reduced.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 \endsetleftboundary: doc definition added. (LH) . . . . . . . . . . . . . . . . . . . . 50 \fontinsterror: New name for \fontinst_error. (LH) . . . . . . . . . . . . . . . . 35 \fontinstinfo: New name for \fontinst_info. (LH) . . . . . . . . . . . . . . . . . . 35

\fontinstwarning: New name for \fontinst_warning. (LH) . . . . . . . . . . . . . 35
\fontinstwarningnoline: New name for \fontinst_warning_no_line. (LH) . 35

\ifiscommand: Changed one fontdoc definition of \ifisglyph to a definition of

\ifiscommand, which was missing from fontdoc. . . . . . . . . . . . . . . . . . . . . 40 \int: doc implementation changed to using \typeset@integer. (LH) . . . . . . . 40 \kerning: A use of #1 where it should have been #2 was corrected. (LH) … 58 \messagebreak: New name for \message_break. (LH) . . . . . . . . . . . . . . . . . . 34 \priority: Changed condition for \ifnum, so that expressions with equal priority

will not get bracketed when nested. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 47 \resetcommand: Since fontdoc adds some grouping, \resetcommand must set its

argument globally there. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 \setcommand: Since fontdoc adds some grouping, \setcommand must set its

argument globally there. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 \setleftboundary: doc definition added. (LH) . . . . . . . . . . . . . . . . . . . . . . . 50 \setrightboundary: doc definition added. (LH) . . . . . . . . . . . . . . . . . . . . . . 51 \strint: Change to stop it from gobbling a following space if the integer is stored

in a macro. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 \sub: Changed priority of first term, so that unnecessary bracketing is reduced.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 \typeset@glyph: Macro added, and most commands that print a glyph name

changed to use this macro. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 v 1.910

General:

Catcodes restored after reading .rc file. (LH&UV) . . . . . . . . . . . . . . . . . . 20 Make \everyjob code optional, and simplify it a little. (LH&UV) . . . . . . . 22 Changed the way slot numbers are stored in \slots-⟨glyph⟩ control sequences. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

\do_new_slot: Macro removed. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 \generalpltomtx: Made this command the standard one, which \pltomtx calls.

(UV&LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 \get_slot_num: Removed redefinition of \do to \gobble_one from temporary

definition of \do, since a \slots- list usually contains only one or two elements anyway. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Internal notes

A Typographic treatment

• I have been following The L^{A}TEX Companion in that I have set all names of packages and the like—fontinst, fontdoc, trig, doc, and docstrip (I might have forgotten some)—in sans serif type. Actually, I have defined a command \package in fisource.sty (or is that fisource?) which does this, so if we decide on some other formating, we can just change that. /LH

• It seems to me that there should indeed be some space between the ‘v’ and the digits in a version number when it is typeset, but I also think a full space is too much, so I have been using thin spaces. These are unbreakable and under L^{A}TEX you can simply use \, to get one (while you are not in math mode, that is). /LH

• While I went through (some of) the code, I came across a few inconsistencies.

A I have marked them out like this—some boldfaced text in a paragraph and a large A in the margin. I defined a command \ambiguity for doing this. /LH

• There is also a similar command \question which is intended for situations where there isn’t really an error, but somethings seems like it should be taken care of in some other way. The \question command puts a question

? mark in the margin.

• I also noticed that there are several fontinst commands, not all of which are

Not in doc: \foo new, which are not defined in fontdoc. To mark out such things, I have written things like the one shown in the margin by this paragraph. I defined a command \missing for doing this. /LH

B Planning topics

This section lists items in the larger design of fontinst which need to be resolved in one way or another. Debates about these items on the fontinst mailing list are welcome.

B.1 Reorganisation of the source

At the moment, all the ideas suggested have been realized.

B.2 Files

Which files should be considered temporary and placed in the location specified with \tempfileprefix? Should files be explicitly be looked for at this location or should it be assumed that fontinst users include that location in their TEX input file search path? In the former case, which files should be looked for in that location? Should files be looked for in the temporary location before they are looked for without a specified location, or should it be the other way round?

C Contributors

[The fontinst source has been pretty inconsistent in how people are credited for what they have done—some appear only as acronyms while others appear as rather striking e-mail addresses—so I thought it best that this is shaped up a bit. My suggestion is that we use names or acronyms in the source and move everything else here. I also thought it could be interesting with a short description of what each person has done and is doing, so I have started ever so slightly on something along those lines. Feel free to add things! /LH]

The following people have contributed substantial amounts of code or documentation to fontinst. They are listed in strict alphabetical order.

Thierry Bouche Thierry saw to that the T1 encoded fonts got font dimensions comparable to the ec fonts. Thierry is also the author of several papers (published in the Cahiers GUTenberg and TUGboat) which deal with nontrivial applications of fontinst, such as creating metrics for Adobe Minion Multiple Master fonts and developing a corresponding math font setup.

E-mail: Thierry.Bouche@ujf-grenoble.fr

Lars Hellström (LH) Lars is responsible for most of the things in v 1.9 that were not there in v 1.8. Lars is currently a member of the fontinst maintenance team. He is also a doctorate student in mathematics at Umeå University.

Alan Jeffrey (ASAJ) Alan is the original author of fontinst. He is not currently on the development team but he is a frequent writer on the fontinst mailing list, which he manually manages subscriptions to. E-mail (fontinst mailing list subscriptions):

    fontinst-request@cogs.susx.ac.uk.

Constantin Kahn (CK) Constantin is one (Sebastian is the other) of the original coauthors of the current \latinfamily command.^{7}

Rowland McDonnell Rowland rewrote Alan’s old v 1.5 documentation for fontinst and updated it for v 1.8.

Sebastian Rahtz (SPQR) Sebastian is one (Constantin is the other) of the original coauthors of the current \latinfamily command. He has also contributed numerous ETX files and made the “unofficial” v 1.6 and v 1.7, which included the first fontinst support for making TS1 encoded files. Sebastian is currently a member of the fontinst maintenance team. Other TEX-related occupations include the fonts/psfonts/ subtree of CTAN, the TEX-live CD collection, …

Ulrik Vieth (UV) Ulrik converted fontinst.sty to doc/docstrip format, reunited Alan’s v 1.511 and Sebastian’s v 1.7, and made the first official release of fontinst (v 1.8) for more than two years. Ulrik is currently a member of the fontinst maintenance team. He is also involved in the Joint TUG/L^{A}TEX 3 Project Working Group on extended math font encodings.

7Am I right about this? It’s a bit before my time, I’ve just read CHANGES. /LH

… Anyone else?

D To do

This section is based on the TODO file from fontinst v 1.504, but a couple of new entries have been added and some have been equipped with comments.

D.1 Things to do in the “near” future

• Update documentation. (Lars, knowing he isn’t saying anything new)

• Update fontdoc.sty and co. for L^{A}TEX 2ε. (Alan)

Some of this was done in v 1.8 when a proper package interface was added and some has been done in v 1.909, but there is still a lot to do. /LH

• latin.mtx fakes composite SC glyphs from the composite glyph, eg.

    \setleftrightkerning{Aacutesmall}{Aacute}{900},

rather than from the SC non-composite, eg.

    \setleftrightkerning{Aacutesmall}{Asmall}{1000}

This may cause problems with SC fonts with explicit SC–C kerns, eg.

    \setkern{V}{Asmall}{100}

This needs to be thought about. Pointed out by Hilmar Schlegel.

• Rewrite the entire substitution mechanism from scratch! The main problem with the current mechanism is that it only allows one substitution per shape and one per series. One cannot substitute the it shape for both the sl and the ui shapes since each new \substitute(noisy|silent) with it in the ⟨from⟩ argument will overwrite the setting made by the previous;

    \substitutenoisy{ui}{it}
    \substitutesilent{sl}{it}

is effectively the same as

    \substitutesilent{sl}{it}

Another big problem is that it isn’t well defined what the substituion mechanism should do. (Lars) I’ve got a sketch for a new substitution mechanism, but I’m not at all sure it will make it into any v 1.9xx. /LH

• Consider writing an \installfontas command which doesn’t generate a (V)PL but makes an entry in the FD file. Typical usage: Install an sc shape of a TS1 font family by using the font made for the n shape. (Lars)

• Use the StdVW property from AFM 4.0 files instead of the width of I for standard stem fontdimen. Pointed out by Hilmar Schlegel.

• Consider removing the following unreliable fakes from textcomp.mtx:

    asciiacutedbl, asciigravedbl, bardbl, openbracketleft, and
    openbracketright

and consider adding fakes for the following unavailable glyphs:

    dollaroldstyle (use dollar), centoldstyle (use cent), lira
    (use sterling), and pilcrow (use paragraph)

These suggestions are of course open for debate. (Ulrik)

D.2 Things that probably won’t be done in the near future

• Find a way to automatically generate math fonts. (Alan)

I doubt that this will ever be possible to do automatically. mathptm and mathptmx are already hackish enough, not to mention the prototype implementations for new math font encodings. /UV

• Investigate using Alternate sets. (Alan)

AFAIK, Thierry Bouche has done some work with alternate sets for AGaramond, ACaslon and Minion, but this implies a lot of manual work to compose the proper calls to fontinst. /UV

• Create L^{A}TEX packages? In fact, rethink the whole package interface … (Alan)

Sebastian’s Perl front-end to fontinst does create trivial L^{A}TEX packages automatically for the CTAN fonts. /UV

• Worry about excessive kern tables in T1 fonts. (Alan)

I think the best way to get at this would be to write a program that can optimize (for size) kern tables by making use of the SKIP instruction. There’s often room for quite a lot of compression. Such a program would however have to be written in some compiling language, otherwise it wouldn’t be fast enough. /LH

• Consider making \set(left|right)kerning parameterized by the size of the other glyph, eg so that faking <Asmall><T> can be different from <Aacutesmall><T>. Suggested by Hilmar Schlegel.

D.3 Things that have been done

• Update documentation (comments from Karl and Damian).

Rowland has meritoriously done the update requested here. On the other hand, it needs to be updated again, since many new features have been added. /LH • Investigate using raw SC fonts. (Alan)

This problem comes up on the mailing list from time to time. The problem is that fontinst’s \latinfamily command is geared towards fonts that come with standard and expert font sets (as with Adobe and Monotype fonts) rather than fonts that come with standard and small caps (as with Linotype fonts). I’m afraid it would be to complicated to handle both cases in the same \latinfamily procedure. /UV

• Investigate problems with duplicate kerns appearing in VPL files (Hilmar Schlegel). The problem has been investigated and is solved with v 1.9. /LH

• Find out why, if you have a font with both medium and light variants but no italic, you get m/it ↦ l/it ↦ l/sl rather than m/it ↦ m/sl. (Sebastian). Because for every shape that fontinst is allowed to use a given font for, it will perform all possible series substitutions. If the \installfont for l/sl came before the \installfont for m/sl, then substitutions will be as described above. See also item about the substitution mechanism. /LH

• AFM files can contain real units, not just integers. (Gintautas Grigelionis). This is fixed with v 1.9. /LH

• Make fontdoc.sty and co. use PS fonts. (Alan)

I think \useexamplefont and friends (introduced with v 1.8) pretty much do what was intended here. /LH

• latin.mtx uses fontinst rather than fontdoc! (Rob Hutchings).

• Allow .vpl files to be read as .pl files. (Constantin)

• Richard Walker reports that if you say

    \latinfamily{mbvx}{}
    \latinfamily{mbv9}{}

then the 2nd run doesn’t use old-style digits, because the 1st run has already defined \digit. If so, this is because \latinfamily is missing a bracing level. I should investigate. I think it is best to do oldstyle and non-oldstyle variants in two separate fontinst runs, i.e. don’t use \latinfamily more than once in a single run. (IIRC, grouping doesn’t work propoerly since every single font closes and reopens a \begingroup-\endgroup pair to encapsulate the kerning info^{8} or something like that.) /UV

D.4 Other notes

Alan’s TODO file also contains some items regarding mathptm, but that seems to have migrated out of fontinst (if it ever really was a part). The problem is that mathptm cannot be changed any more for the sake of checksum consistency and backwards compatibility. A new variant called mathptmx tries to do a little better, but there may still be room for improvements.

8And glyph metrics info, and glyph mapcommands info … /LH

E Efficiency

This section records the results of some (rather simple) test runs that have been made to test the efficiency of fontinst, primarily to see how changes in the implementation affect efficiency by comparing the time and space used by different fontinst versions to complete the same task.

E.1 Alan Jeffrey’s tests

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.

Where possible, we avoid re-scaling kerns, 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

E.2 Current tests

The setup for this test is that TEX is run on a .tex file consisting of the following commands.

\batchmode
\input fontinst.sty
\latinfamily{pad}{}
\tracingstats=1\bye

All the font metrics are generated from the AFM files; temporary MTX, PL, and VPL files are deleted between test runs. The format used was generated by typing \dump at iniTEX’s ** prompt; thus there is no overhead from a typesetting format in the space requirements.

[It appears the exact data from these tests will have to wait, since I haven’t been able to get access to any computer with reliable process timing. For the next release perhaps … /LH]

References

[1] Donald E. Knuth, Duane Bibby (illustrations): The TEXbook, Addison Wesley, 1991; volume A of Computers and typesetting.

[2] Karl Berry: Fontname, CTAN:info/fontname/fontname.texi (and most of the other files in that directory as well).

Some other things which definitely ought to be in the bibliography, but for which I couldn’t find references just when I was at it are:

The L^{A}TEX companion The L^{A}TEX graphics companion L^{A}TEX 2ε font selection (fntguide.tex).