The kerntest package
Harald Harders [email protected]
Version v1.32 (2004/04/14), printed 14th April 2004
Abstract
This class makes it easy to generate tables that show many different kerning pairs of an arbitrary font, usable by LATEX. It shows the kerning values that are used by the the font by default.
In addition, this class enables the user to alternate the kernings and to observe the results. Kerning pairs can be defined for groups of similar glyphs at once. Automatically, anmtxfile is generated that can be loaded by fontinst to introduce the user-made kernings into the virtual font for LATEX.
Contents
1 Introduction 2
2 Usage of the class 3
2.1 Introduction . . . 3
2.2 Most features by example . . . 5
2.3 Encoding-dependent parameters . . . 8
2.4 Advanced features . . . 9
3 Configuration file 10 4 Kerning pairs that are often missing 10 4.1 Character combinations . . . 11
4.2 Quotation marks . . . 11
5 An example of how to optimize a font 12 6 The implementation 16 6.1 Class file . . . 17
6.1.1 Glyph classes . . . 33
6.1.2 Extra commands for special encodings . . . 40
6.2 Footer of mtxfile . . . 40
6.3 Class option files . . . 41
6.3.1 T1 encoding . . . 41
6.3.2 TS1 encoding . . . 47
6.3.3 OT1 encoding . . . 52
6.3.4 T2A encoding . . . 58
6.3.5 T2A encoding . . . 63
6.3.6 LY1 encoding . . . 68
6.4 Templates . . . 72
6.4.1 T1 encoding . . . 73
6.4.2 TS1 encoding . . . 80
6.4.3 OT1 encoding . . . 85
Copyright
Copyright 2004 Harald Harders.
This program can be redistributed and/or modified under the terms of the LaTeX Project Public License Distributed from CTAN archives in directory macros/latex/base/lppl.txt; either version 1.3 of the License, or any later version.
1 Introduction
Every glyph of a font is surrounded by a bouding box. Have a look at these glyphs:
A m f A m f
As can be seen in this example, the glyphs may extend the bounding box.
Normally, one character is placed after the other by simply putting the bound- ing boxes directly after each other:
AHVAmfT AHVAmfT
In most cases, this works great, but sometimes the distance between two glyphs is ugly then. Here, for instance, have a look at “VA”, “fT”, “VA”, and “fT”. To improve these cases, the bounding boxes are moved together or away from another, as shown in the next example. This is called kerning. To be able to do the kerning, the font contains a table of pairs of glyphs and the distance to move the second one.
AHVAmfT AHVAmfT
What you see here is the original kerning of the Times Roman installed in your TEX system. The V–A pairs are improved; but the f still touches the T which is not wanted. The Times Roman font misses this kerning pair. Better were this:
AHVAmfT
AHVAmfT
Most fonts are missing many of these kerning pairs that are necessary for a good typography. Especially if you are writing in a language other than English, many kernig pairs are missing. Have a look at this example with quotation marks used in German, with the original kerning of the Times:
„TA“ »VaV«
As you can see, there is no kerning at all.
And here comes, what this class is intended to do: It is difficult to calculate the necessary kerning automatically. Thus, it can be helpful to generate some kerning pairs and to try different amounts of kernings. Compare the different kernings in this example (this time without the bounding boxes):
A“ A“ A“ A“ A“ A“ A“ A“ A“ A“
The first one is without kerning. The kerning in the last one (−0.35 em) is surely too much since both glyphs touch each other. It really isn’t easy to find the
“perfect” kerning. One remark here: It is worse to have a too tight kerning than too less kerning. Thus please do as little kerning as you think can work well.
With thekerntestclass, it is easy to try out different values. How this can be done is described in the next section.
2 Usage of the class
2.1 Introduction
In the simplest case, you can use the package like this:
\documentclass[family=ptm,extraname=shortexample,footer=false]{kerntest}
\begin{document}
\begin{kerntable}
\testkern{W}{-}{A}{-}{W} original \\
\testkern{V}{-160}{A}{+160}{V} altered \\
\end{kerntable}
\end{document}
You have to define the font family to be tested in the optional argument of the\documentclasscommand. The syntax is family=hfont familyi, whilehfont familyiis the typical abbreviation according to Karl Berry’s name scheme [1], e.g., cmrfor Computer Modern Roman,ptmfor Times Roman,phvfor Helvetica,pmnj for Adobe Minion with old-style numbers, pmnx for Adobe Minion with expert characters.
The optionsextraname=shortexampleand footer=false are not so impor- tant and described later.
The kerning table is generated by thekerntableenvironment which is repre- kerntable
sented by alongtableenvironment internally. Each line of this environment has
\testkern
to contain one\testkerncommand with five arguments:
1. The first one contains the name or character number of the left character in the table (see Fig. 1). Which glyph corresponds to a given value depends on the used encoding, default is the cork encoding T1. The glyph can be
Font t1-ptm-m-n-shortexample 1
slot name orig new both k. 1 k. 2 orig. new comment
065 A
WAW WAW WAW WAW
–120 –90WAexampleAW WAexampleAW
original065 A
VAV VA V VAV VA V
(–135)–160 (–135)+160VAexampleAV VAexampleA V
alteredslot name orig new both k. 1 k. 2 orig. new comment
Figure 1: Example for a part of a kerning table (explanations in the text)
specified by giving a decimal number (0to255), a hexadecimal number ("0 to "FF), an octal number (’0 to ’377), or by giving the PostScript glyph name, e.g., grave, guillemotright, A, Aring. It does not work to give LATEX sequences as<<,\guillemotright, etc.
2. The second argument gives the kerning of the characters defined in the first and in the third argument. The used unit are Postscript Type 1 font units which have the length of 0.001 em. It is not allowed to specify another unit.
If the second argument is “-” the original kerning of the font is shown (first line of the example).
If a value is given (second line) the original kerning is overwritten by the given value. Negative values reduce the distance of the glyphs, positive values increase it.
3. The third argument specifies the second glyph.
4. The fourth argument is the kerning between the second and the third glyph and works exactly as the second argument.
5. The fifth argument specifies the third glyph.
After the\testkerncommand, an arbitrary (but short) comment may be added.
Often, it is good to write the name of the glyph here. Witht1-XXX-m-n.texand ts1-XXX-m-n.tex, two templates are given that contains all glyph names for the T1andTS1encodings.
Each line in thekerntableenvironment (even the last one) has to end with a
\\or\tabularnewline.
The output of this file is shown in Fig. 1. In the first column, the number of the middle character (argument#3of the\testkerncommand is listed, followed by the PostScript glyph name. In the third column, the combination of characters is printed with original kerning for both pairs, while the forth column shows the newly suggested kerning. In the fifth column, both variants are printed over each other (the old one grey, the new one black). The next two columns show the values of the two kerning pairs in Postscript font units (normally, 0.001 em). If the user has not given a new kerning the original value is printed in grey. If the user has defined a new kerning, this new value is printed in black. If, in this case, the old kerning is unequal zero, it is printed in parentheses before the new value (second line of the example). The rest of each line are examples and comments.
2.2 Most features by example
The next example shows some more switches that can be defined by the user:
\listfiles
\documentclass[family=ptm]{kerntest}
\kernsetup{encoding=T1,series=bx,shape=n,example=M}
\kernsetup{size=17.28pt,baselineskip=17pt,papersize=a4paper}
\kernsetup{extraname=example,color=true,footer=false}
\newglyphclass{right}{A}{A,Aring,Adieresis,Abreve[500]}
\newglyphclass{left}{A}{A,Aring,Adieresis,Abreve[500]}
\newglyphclass{right}{fullstop}{period,comma}
\newglyphclass{left}{fullstop}{period,comma}
\begin{document}
\begin{kerntable}
\testkern{016}{-30}{046}{-30}{017} decimal \\
\testkern{"10}{-}{"2C}{-}{"11} hexadecimal \\
\testkern{’020}{-}{’101}{-80}{’021} octal \\
\testkern{quotedblleft}{-}{Aring}{-80}{quotedblright} by name\\
\testkern{quotedblleft}{-100}{AE}{-}{quotedblright} \\
\testkern{quotedblleft}{-}{B}{-60}{quotedblright} \\
\testkern{quotedblleft}{-}{C}{-}{quotedblright} \\
\testkern{T}{-}{f}{+90}{T} \\
\testkern{quotedblbase}{-60}{T}{-}{quotedblleft} \\
\testkern{quotedblbase}{-}{Adieresis}{-}{quotedblleft} \\
\testkern{quotedblbase}{-}{A}{-200}{quotedblleft} \\
\testkern{quotedblbase}{-}{Aring}{-}{quotedblleft} \\
\testkern{quotedblbase}{-}{Abreve}{-}{quotedblleft} \\
\testkern{guillemotright}{-55}{V}{-55}{guillemotleft} \\
\end{kerntable}
\end{document}
Have a look at the results in Fig 2 before the switches are explained.
All class options except family can either be given as class option in
\kernsetup
the optional argument of the \documentclass command or as argument of the \kernsetup command. The family class option has to be given in the
\documentclasscommand. Here comes a list of all class options:
encoding=hfont encodingi: Font encoding (default: T1). Currently,OT1,T1,TS1, encoding
T2A,T2B, andLY11 are supported.
family=hfont familyi: Abbreviation of the font-family name according to Karl family
Berry’s scheme [1]. This option is mandatory in the optional argument of the\documentclasscommand.
series=hfont seriesi: Abbreviation for the series of the font (default: m), e.g., m series
for medium, sbfor semibold,bfor bold,bxfor bold extended.
1While the other encodings are generated starting from.etxfiles, the LY1 encoding has been extracted fromtexnansi.enc. Some glyphs may have incorrect names.
Font t1-ptm-bx-n-example 1
slot name orig new both k. 1 k. 2 orig. new comment
046 period
“.” “.” “.” “.”
–30 (–55)–30“.M.” “.M.”
decimal044 comma
“,” “,” “,” “,”
–30∗ (–45)–30∗“,M,” “,M,”
hexadecimal 065 A“A” “A” “A” “A”
–10 –80“AMA” “AMA”
octal197 Aring
“Å” “Å” “Å” “Å”
–10 –80†“ÅMÅ” “ÅMÅ”
by name198 AE
“Æ” “Æ” “Æ” “Æ”
–100 0“ÆMÆ” “ÆMÆ”
066 B
“B” “B” “B” “B”
0 –60“BMB” “BMB”
067 C
“C” “C” “C” “C”
0 0“CMC” “CMC”
102 f
TfT Tf T TfT Tf T
0 +90TfMfT TfMf T
084 T
„T“ „T“ „T“ „T“
–60 0„TMT“ „TMT“
196 Adieresis
„Ä“ „Ä“ „Ä“ „Ä“
0 0„ÄMÄ“ „ÄMÄ“
065 A
„A“ „A“ „A“ „A“
0 –200„AMA“ „AMA“
197 Aring
„Å“ „Å“ „Å“ „Å“
0 –200∗„ÅMÅ“ „ÅMÅ“
128 Abreve
„ ˘ A“ „ ˘ A“ „ ˘ „ ˘ A“ A“
0 –100∗„ ˘ AM ˘ A“ „ ˘ AM ˘ A“
086 V
»V« »V« »V« »V«
–55 –55»VMV« »VMV«
slot name orig new both k. 1 k. 2 orig. new comment
Figure 2: Example for a part of a kerning table (explanations in the text). The labels marked with a star are described in Section 2.4.
shape=hfont shapei: Abbreviation for the font shape (default: n), e.g., n for up- shape
right, it for italic, sl for slanted, sc for small caps, scit for italic small caps.
size=hfont sizei: Size of the tested font (default: 17.28pt) in arbitrary units.
size
This sets the\baselineskipto 1.2 times the given value. Thesizeoption does not change the size of the legend text which is fixed to 10 pt.
baselineskip=hbaselineskipi: Sets the\baselineskipexplicitly. To take effect, baselineskip
it has to be given after the optionsize (default: 1.2*17.28pt).
designsize=hdesign sizei: For calculating the kerning data, a PostScript font unit designsize
is used which is 1/1000 of the font’s design size. Unfortunately, it is not possible to get this size reliably in LATEX. For most fonts, 1 em corresponds to the design size. But in some cases, it is not true:
1. Some fonts have a different em length, for example, the Computer Mod- ern fonts. Then, the size given by the option size corresponds to the design size, but 1 em does not.
2. If the font is scaled by the.fdfile, 1 em is also scaled and may corre- spond to the design size while the size given withsizedoes not.
Since in most cases, 1 em is the correct design size, this is the default. If it is not, you can give the correct design size by using the optiondesignsize, for example,designsize=0.9em, designsize=17pt.
example=htexti: Alters the example text for columns 5 and 6 (default: example).
example
papersize=hpapersizei Tells the geometrypackage which pagesize to use. Sup- papersize
ported are all pagesizes handled bygeometry, e.g.,a4paper,letter,legal (no default).
extraname=hfontname extensioni: Normally, the heading of each page of out- extraname
put as well as the filename of the mtx file are generated automatically by appending encoding, font family, font series, and font shape, e.g., t1-cmr-m-n.mtx. If you use this option, -hfontname extensioni is added both to the headings and to the filename. For example, extraname=test1 leads to t1-cmr-m-n-test1.mtx. This is useful if you want to generate differentmtxfiles that normally got the same name.2
color=htrue/falsei: Switches on color output (default: false). New values are color
printed in red, while the old ones are printed black instead of black/grey.
copyquotation=htrue/falsei: If a kerning pair containing a double quotation copyquotation
mark, including guillemots, is set, write also the corresponding single one to themtxfile.
writeall=htrue/falsei: Write also the original kerning data to themtxfile.
writeall
footer=htrue/falsei: Switch on or off the footline.3 footer
It has been mentioned some times that anmtxfile is generated automatically.
mtx files contain the font metrics during the fontinst process. Amongst other things, they contain the kerning data. For example, themtxfile generated by the last example looks like this:
%%
%% This is file ‘t1-ptm-bx-n-example.mtx’,
%% generated on 2004/4/14 by kerntest.cls, (c) 2004 Harald Harders.
%%
%% The original source file was:
%%
%% t1-ptm-bx-n-example (.tex?) with these font options:
%% Encoding: T1
%% Family: ptm
%% Series: bx
%% Shape: n
%% User-defined name: -example
%%
\relax
\metrics
\needsfontinstversion{1.926}
%%
%% Kerning data for single characters and
%% the first members of the glyph classes.
%%
2This is why the first example used this option.
3This option seems only to work in the\documentclassoptions. Don’t ask me why.
%% After each \setkern entry, the glyph classes
%% for both glyphs are given (./. means no class).
%%
\setkern{quotedblleft}{period}{-30}% ./. -- left/fullstop
\setkern{period}{quotedblright}{-30}% right/fullstop -- ./.
\setkern{A}{quotedblright}{-80}% right/A -- ./.
\setkern{quotedblleft}{AE}{-100}% ./. -- ./.
\setkern{B}{quotedblright}{-60}% ./. -- ./.
\setkern{f}{T}{+90}% ./. -- ./.
\setkern{quotedblbase}{T}{-60}% ./. -- ./.
\setkern{A}{quotedblleft}{-200}% right/A -- ./.
\setkern{guillemotright}{V}{-55}% ./. -- ./.
\setkern{V}{guillemotleft}{-55}% ./. -- ./.
%%
%% Kerning factors for the different glyph classes.
%%
\setleftkerning{Aring}{A}{1000}% left/A
\setleftkerning{Adieresis}{A}{1000}% left/A
\setleftkerning{Abreve}{A}{500}% left/A
\setleftkerning{comma}{period}{1000}% left/fullstop
%%
\setrightkerning{Aring}{A}{1000}% right/A
\setrightkerning{Adieresis}{A}{1000}% right/A
\setrightkerning{Abreve}{A}{500}% right/A
\setrightkerning{comma}{period}{1000}% right/fullstop
%%
\endmetrics
%%
%% End of file ‘t1-ptm-bx-n-example.mtx’.
Only new or changed kerning values are inserted (e.g., quotedblleft–A is not included).
Using the\mtxcomment{hcommenti}command, you can write the given argu-
\mtxcomment
ment as comment into the mtxfile.
2.3 Encoding-dependent parameters
Some encodings may have slight differences depending on the used shape. For example, typewriter fonts may have ligatures but they are normally not used.
Thus, the encodings do not have some glyphs when used with typewriter fonts (e.g.,ff,fi,ffi,fl, fflare missing).
The class provides an interface to give the necessary parameters to these en-
\encodingsetup
codings. Use the command\encodingsetupthat takes a comma-separated list of options as argument (as\kernsetup).
Here are the encoding-specific options:
T1 encoding:
ligaturing=hnumberi: Level of how many ligatures are used (-2, -1, 0, ligaturing
or 1, default 1). Here is the description fromt1.etx (version 1.923, 2002/10/29):
1 All the standard ligature glyphs (fi,fl,ff,ffi,ffl,IJ, andij) are included and the normal ligaturing instructions (those for the f-ligatures) are included.
0 All the standard ligature glyphs are included, but none of their ligaturing instructions.
−1 The seven slots normally used for ligatures are left empty.
−2 The seven slots normally used for ligatures are left empty, as are the slots normally used forc,f,s,i, andI.
OT1 encoding:
ligaturing=hnumberi: Level of how many ligatures are used (0, 1, or 2, ligaturing
default 2). Please refer to ot1.etxfor more details.
italicizing=htrue/falsei: Usedollarwhenfalseand sterlingwhen italicizing
true (default: false).
2.4 Advanced features
In most fonts, different glyphs need the same kerning because their left or right edges are very similar, for example, the kerning on the left sides of B, D, Ď, Ð, E, Ě, Ę, È, É, Ê, Ë, F, H, I, İ, Ì, Í, Î, Ï, IJ, J, K, L, Ĺ, Ľ, Ł, N, Ń, Ň, Ñ, P, R, Ŕ, Ř, Ŋ, and Þ should be equal.
This can be reached by using so called “glyph classes”. A new glyph class
\defglyphclass
\newglyphclass
\renewglyphclass
\provideglyphclass
can be defined using one of the commands \defglyphclass, \newglyphclass,
\renewglyphclass, and \provideglyphclass. The differences are similar to these of the commands \newcommand, \renewcommand, etc. They all have the syntax \defglyphclass{hsidei}{hnamei}{hglyphlisti}. hsidei specifies the side of the glyphs on which the kerning shall be equal (leftorright). The parameter hnamei specifies the name of the glyph list, the list above could be named “H”
because they all have a similar shape as the H. The third argument, hglyphlisti, contains a comma-separated list of all glyphs (PostScript names or numbers—as usual). For example, the above list is build by this command:4
%\newglyphclass{left}{H}{B,D,Dcaron,Eth,E,Ecaron,Eogonek,Egrave,%
% Eacute,Ecircumflex,Edieresis,F,H,I,Idotaccent,Igrave,Iacute,%
% Icircumflex,Idieresis,IJ,J,K,L,Lacute,Lcaron,Lslash,N,Nacute,%
% Ncaron,Ntilde,P,R,Racute,Rcaron,Ng,Thorn}
You can specify arbitrary glyph classes. If you, for example, use the copyquotation option glyph classes are made containing one double and one single quotation mark each.
When you write a kerning table using thekerntableenvironment and it hap- pens that you change the kerning for a glyph that is member of a glyph class, the kernings for all other glyphs of the same glyph class are automatically changed on the specific side. This can be seen in the example on Page 5 and in Figure 2:
periodandcommabuild a glyph pair on both sides. In the first line of the table, left and right kerning between the period and the quotation marks are changed by the user. The kerning between the comma and quotation marks is then set
4Due to a problem between theltxdoc andverbatim packages, the% signs appear at the beginning of each line. Just delete them in mind.
automatically; the user does not have to specify them again (the kerning data contain a simple -in the second line). If you specify the same value explicitly, a warning is generated. If you specify conflicting values, the programme generates an error message (not shown).
Automatically generated kerning pairs are marked by∗ behind the value (as can be seen in the second and 12th line of the example). Repeated values are marked by†.
There is one shortcoming: If you don’t specify the kerning for a glyph class at the first occurance of this glyph, the correct kerning data are not shown for the occurances before the position you have specified the kerning. In the example, the kerning between the members of the glyph class “A” (A, Ä, and Å) and the right German quotation mark (“), is not specified for the first char of the glyph class, Ä, but for the second one, A. Thus, the kerning of−150is shown for “A” and for
“Å”, but not for “Ä”. But nevertheless, the kerning data written to the mtx files are correct.
All glyphs, given by\defglyphclassget the same kerning by default. You can specify different scale factors by appending[hscalei]to each glyph name; while a factor of1000is the default and means “the same kerningn width”.
For example,
%\defglyphclass{right}{A}{A,Aring[800],Adieresis[1200],Abreve}
defines a glyph class containing “A”, “Å”, “Ä”, and “Ă”. All kernings on the right side of “Å” have a width of 80 of these “A” has. “Ä” is kerned 120 % of “A”. “Ă” is again kerned as “A”.
You can also specify a different scaling for the first glyph in the glyph class.
But then, all values are scaled in order to reach a factor of1000for the first entry.
For example,
%\defglyphclass{right}{A}{A[500],Aring[400],Adieresis[600],Abreve[500]}
is identical to the example above.
The effect of scaled kernings can be seen in the example on Page 5 and in Figure 2 where “Ă” has half the scaling of “A” and “Å”.
If two glyphs with scalings different from 1000 meet each other both scaling factors are multiplicated.
There are some interesting commands to handle these glyph classes. Please have a look in Section 6.1.1 for their description.
3 Configuration file
If you are too lazy to put the same options into every source file you may write all options exceptfamilyinto the configuration filekerntest.cfgand put it into the LATEX path. If it is present, it is loaded automatically.
4 Kerning pairs that are often missing
This section shows some kerning pairs that are often missing, even in expensive fonts. This problem arises since most fonts are merely designed for the English language.
4.1 Character combinations
Some glyphs need a kerning to many other glyphs, including “A”, “T”, “V”, “W”, and “Y”. For the ordinary lowercase letters, these kernings are included in most fonts (if the lowercase letter is on the right of the capital). But often, glyphs of other Languages than English are forgotten, e.g., “Tç”, “Vé”, etc. But you may not simply copy all kernings of, for instance, “Ta” to “Tä”, “Tá”, “Tå”, “T¸a” etc. Often, these glyphs have parts that force the kerning to be reduced or even deleted.
Most character pairs with the uppercase letters (“A”, “T”, “V”, “W”, “Y”) after a lowercase letters are not kerned in the fonts. In most cases, this should not be a problem because these combinations are never printed. (Nowadays, its getting more and more important to have these kernings since it is a fashion to use up- percase letters within words, e.g., “ServicePoint”.5) But some combinations really should be kerned: “eV” (electronvolt), “mV” (millivolt).
4.2 Quotation marks
Most fonts don’t provide kerning for quotation marks other than the English ones. In English, “Hello” is used (“66–99”). French uses « and »: «Bon- jour». In German, the three possibilities „Hallo“ (“99–66”), »Hallo«, and »Hallo«
are used. In Italian, «Ciao» or “Ciao„ are possible. Swedish uses »Hi» or
”Hi” [2]. For all non-English possibilities, most fonts have no kerning informa- tion. Thus, you should generate five tables for every font, hopefully containing all possibilities («H», »H«, “H”, „H“, ”H„): \testkern{019}{-}{hglyphi}{-}{020},
\testkern{020}{-}{hglyphi}{-}{019}, \testkern{016}{-}{hglyphi}{-}{017},
\testkern{018}{-}{hglyphi}{-}{016}, \testkern{017}{-}{hglyphi}{-}{018}, wherehglyphistands for all 256 glyphs contained in a T1 encoded font.
All problems mentioned for the double quotation marks apply also for their single variants (‚, ‘, ’, ‹, and ›). In most cases, they need the same kerning as their double counterparts.
There are two templates enclosed to build these kerning tables:t1-XXX-m-n.tex andts1-XXX-m-n.tex. Hopefully, the names tell you which one to use. They con- tain some comments that should help to use them.
One (repeated) remark: Please don’t overdo the kerning if you adjust it. In most cases, good is less than you think on first sight. You can also orientate on predefined kernings. For example, the kerning for A“ should be similar to A”.
But you are still not save to get the correct kerning when your font knows them. This is due to the fact that there are multiple possibilities to access the quotation marks. For example, « can be produced by<<, \guillemotleft, and even by \symbol{19} (if you are using T1 encoding). If you useinputenc.sty you may use the characters directly, e.g., «. And after loading babel.sty, you can use\flqqand when writing German"<.
These possibilities are not equivalent.
The direct commands \textquotedblleft, \textquotedblright,
\quotedblbase, \guillemotleft, \guillemotright, \textquoteleft,
\textquoteright, \quotesinglbase, \guilsinglleft, and \guilsinglright work properly; they kern on their left and their right side.
The directly written quotation marks («, », etc.) also work correctly because the corresponding encoding file (e.g., latin1.def) translates them to the direct
5The German railway company really uses this term!
commands.
The ligatures‘‘and’’seem also to work correctly. But the ligature,,kerns correctly on its right side, but on its left side, it kerns as a comma. This may also be correct but it needn’t be always the case. <<and>>do not kern at all on their left side.6
Looking at thebabel commands, only \grqq and \grq surely work correct.
The others (\glqq, \glq, \flqq, \flq, \frqq, \frq) are defined differently and thus do not guarantee to kern correctly. On 2003/04/01, I have posted a bug report. Let’s see what happens.
Thebabel shortcuts "‘, "’, "<, and "> work as good as the corresponding commands.
If you want a correct behaviour of all babel quotation marks, just copy the definition of \grqq (it contains of three command definitions!) from babel.def into your code and change it according to produce the other quotation marks.
5 An example of how to optimize a font
In this section, a very simple example is shown how to install a single font shape with fontinst [4] and how to change kernings for it. If you really want to understand what happens read the fontinst manual [4], “TEX Unbound” by Alan Hoenig [3], or “The Font Installation Guide” by Philipp Lehman [5].
Ghostscript contains the font “Century Schoolbook L Roman” which is shipped as filesc059013l.afmandc059013l.pfb. Please copy these files into a temporary directory.
According to Karl Berry’s scheme, the fontname isuncr8a. But this font is already prepared on most TEX systems. Thus we take the fontname9ncr8ahere.
This will be the name for the result file.
Then, run TEX (not LATEX) on the scriptschoolb1.texwhich does most work to install a new font:
\input fontinst.sty
\needsfontinstversion{1.914}
% input AFMs:
\transformfont{9ncr8r}{\reencodefont{8r}{\fromafm{c059013l}}}
\fromafm{9ncr8r}
% install fonts:
\installfonts
% declare the font familys for T1 and TS1 encoding:
\installfamily{T1}{9nc}{}
\installfamily{TS1}{9nc}{}
% install a raw font:
\installrawfont{9ncr8r}{9ncr8r,8r}{8r}{}{}{}{}{}
% install the fonts in T1 and TS1 encoding:
\installfont{9ncr8t}{9ncr8r,latin}{T1}{T1}{9nc}{m}{n}{}
\installfont{9ncr8c}{9ncr8r,textcomp}{TS1}{TS1}{9nc}{m}{n}{}
% ready:
\endinstallfonts
6I believe they kern as<reps.>. But these characters don’t have any kerning information in most cases.
Some problematic kernings
»V«, “A”, „VA“, „V˘ A“
›V‹, ‘A’, ‚VA‘, ‚V˘ A‘
Figure 3: Font example for Century Schoolbook L with original kerning
\bye
This run creates some files with the extensions.pl and .vpl. They have to be converted totfmandvffiles as follows:
pltotf 9ncr8r.pl vptovf 9ncr8c.vpl vptovf 9ncr8t.vpl
Now, you can delete the temporary files with the extensions.mtx,.pl, and.vpl.
The new font is ready for use with LATEX, now (only for T1 and TS1 encoding, OT1 encoding has been left out). Just run LATEX on the test filetestschoolb.tex.
But you are not yet able to use dvips orpdfLATEX because they need amapfile.
The corresponding one,schoolb.map looks like this:
9ncr8r CenturySchL-Roma "TeXBase1Encoding ReEncodeFont" <8r.enc <c059013l.pfb With help of this map file, the dvi file can be converted to Postscript using
dvips: dvips -u +./schoolb.map -o testeschoolb-1.ps testschoolbUnfor- tunately, you cannot use pdfLATEX without adding the contents ofschoolb.map to the globalmapfile.
When viewing the result in testschoolb-1.ps (Fig. 3), you see that this specific font already has most kernings that are missing in other fonts. The only really forgotten kernings are A“, A‘, Ă“, and ‚V.
Emagine that many kernings were unsatisfactory. Then, we generate a kerning table containing the glyph combinations we do not like:
\listfiles
\documentclass[family=9nc,footer=false]{kerntest}
\kernsetup{encoding=T1,series=m,shape=n,example=tst,extraname=1}
\kernsetup{size=14.40pt,baselineskip=16.5pt,papersize=a4paper}
\renewcommand\thepage{}
\newglyphclass{left}{A}{A,Abreve[500]}
\newglyphclass{right}{A}{A,Abreve[500]}
\begin{document}
\begin{kerntable}
\testkern{020}{-200}{086}{-200}{019} \\
\testkern{016}{-220}{065}{-220}{017} \\
\testkern{018}{-}{065}{-220}{016} \\
\testkern{018}{-220}{086}{-}{016} \\
\testkern{015}{-200}{086}{-200}{014} \\
\testkern{096}{-220}{065}{-220}{039} \\
\testkern{013}{-}{065}{-220}{096} \\
Font t1-9nc-m-n-1
slot name orig new both k. 1 k. 2 orig. new comment
086 V
»V« »V« »V« »V«
(–85)–200 (–85)–200»VtstV« »VtstV«
065 A
“A” “A” “A” “A”
(–65)–220 (–67)–220“AtstA” “AtstA”
065 A
„A“ „A“ „A“ „A“
+36 –220„AtstA“ „AtstA“
086 V
„V“ „V“ „V“ „V“
(–81)–220 0„VtstV“ „VtstV“
086 V
›V‹ ›V‹ ›V‹ ›V‹
(–85)–200 (–85)–200›VtstV‹ ›VtstV‹
065 A
‘A’ ‘A’ ‘A’ ‘A’
(–65)–220 (–66)–220‘AtstA’ ‘AtstA’
065 A
‚A‘ ‚A‘ ‚A‘ ‚A‘
0 –220‚AtstA‘ ‚AtstA‘
086 V
‚V‘ ‚V‘ ‚V‘ ‚V‘
–220 0‚VtstV‘ ‚VtstV‘
086 V
AVA AVA AVA AVA
(–101)–220 (–100)–220AVtstVA AVtstVA
086 V
AV˘ ˘ A ˘ AV˘ A AV˘ AV˘ ˘ ˘ A A
(–101)–110∗ (–100)–110∗AVtstV˘ ˘ A AVtstV˘ ˘ A
slot name orig new both k. 1 k. 2 orig. new comment
Figure 4: Kerning table for Century Schoolbook L
\testkern{013}{-220}{086}{-}{096} \\
\testkern{065}{-220}{086}{-220}{065} \\
\testkern{Abreve}{-}{086}{-}{Abreve} \\
\end{kerntable}
\end{document}
This leads to the output shown in Fig. 4 and to themtxfilet1-9nc-m-n-1.mtx:
%%
%% This is file ‘t1-9nc-m-n-1.mtx’,
%% generated on 2004/4/14 by kerntest.cls, (c) 2004 Harald Harders.
%%
%% The original source file was:
%%
%% t1-9nc-m-n-1 (.tex?) with these font options:
%% Encoding: T1
%% Family: 9nc
%% Series: m
%% Shape: n
%% User-defined name: -1
%%
\relax
\metrics
\needsfontinstversion{1.926}
%%
%% Kerning data for single characters and
%% the first members of the glyph classes.
%%
%% After each \setkern entry, the glyph classes
%% for both glyphs are given (./. means no class).
%%
\setkern{guillemotright}{V}{-200}% ./. -- ./.
\setkern{V}{guillemotleft}{-200}% ./. -- ./.
\setkern{quotedblleft}{A}{-220}% ./. -- left/A
\setkern{A}{quotedblright}{-220}% right/A -- ./.
\setkern{A}{quotedblleft}{-220}% right/A -- ./.
\setkern{quotedblbase}{V}{-220}% ./. -- ./.
\setkern{guilsinglright}{V}{-200}% ./. -- ./.
\setkern{V}{guilsinglleft}{-200}% ./. -- ./.
\setkern{quoteleft}{A}{-220}% ./. -- left/A
\setkern{A}{quoteright}{-220}% right/A -- ./.
\setkern{A}{quoteleft}{-220}% right/A -- ./.
\setkern{quotesinglbase}{V}{-220}% ./. -- ./.
\setkern{A}{V}{-220}% right/A -- ./.
\setkern{V}{A}{-220}% ./. -- left/A
%%
%% Kerning factors for the different glyph classes.
%%
\setleftkerning{Abreve}{A}{500}% left/A
%%
\setrightkerning{Abreve}{A}{500}% right/A
%%
\endmetrics
%%
%% End of file ‘t1-9nc-m-n-1.mtx’.
Using this file, you can repeat the fontinst run with a slightly changed script schoolb2.tex:
\input fontinst.sty
\needsfontinstversion{1.914}
% input AFMs:
\transformfont{9ncr8r}{\reencodefont{8r}{\fromafm{c059013l}}}
\fromafm{9ncr8r}
% install fonts:
\installfonts
% declare the font familys for T1 and TS1 encoding:
\installfamily{T1}{9nc}{}
\installfamily{TS1}{9nc}{}
% install a raw font:
\installrawfont{9ncr8r}{9ncr8r,8r}{8r}{}{}{}{}{}
% install the fonts in T1 and TS1 encoding:
\installfont{9ncr8t}{t1-9nc-m-n-1,9ncr8r,latin}{T1}{T1}{9nc}{m}{n}{}
\installfont{9ncr8c}{9ncr8r,textcomp}{TS1}{TS1}{9nc}{m}{n}{}
% ready:
\endinstallfonts
\bye
The only change amongst schoolb1.tex is the added entry t1-9nc-m-n-1, at the beginning of the second argument of the \installfont{9ncr8t}command.
This includes the new kernings into the generated font. After repeating also the pltotf and vptovfcalls, you can use the font with the new kernings. Running
Some problematic kernings
»V«, “A”, „VA“, „V˘ A“
›V‹, ‘A’, ‚VA‘, ‚V˘ A‘
Some problematic kernings
»V«, “A”, „VA“, „V˘ A“
›V‹, ‘A’, ‚VA‘, ‚V˘ A‘
Figure 5: Font example for Century Schoolbook L with original (top) and modified (bottom) kerning. The kerning is much too strong. Here, it only shows the effect of altering the kerning.
LATEX and dvips again ontestschoolb.texgives the output of Fig. 5. Here, the kerning values are much too strong. The only aim of this was to show a clear difference between original and modified kerning. Have a look at the Ă kernings.
They have been set to be half as large as the A kernings on both sides.
The last thing to do is to install the font files into the corresponding paths of your TEX distribution and to append the map information to the global map files (normally by usingupdmap).
References
[1] Karl Berry. Fontname, May 2003.ftp://ftp.dante.de/tex-archive/info/
fontname/.
[2] Friedrich Forssman, Ralf de Jong. Detailtypografie, Verlag Hermann Schmidt, Mainz, Germany, 2002.
[3] Alan Hoenig. TEX Unbound—LATEX & TEX Strategies for Fonts, Graphics, &
More, Oxford University Press, 1998.
[4] Alan Jeffry, Rowland McDonnell. fontinst—Font installation software for TEX, June 1998. ftp://ftp.dante.de/tex-archive/fonts/utilities/
fontinst/.
[5] Philipp Lehman. The Font Installation Guide, August 2003. ftp://ftp.
dante.de/tex-archive/info/Type1fonts/fontinstallationguide.pdf.
6 The implementation
Heading of all files.
1hclassi\ProvidesClass{kerntest}
2hmtx&t1i\ProvidesFile{t1mtx.clo}
3hmtx&ts1i\ProvidesFile{ts1mtx.clo}
4hmtx&ot1i\ProvidesFile{ot1mtx.clo}
5hmtx&t2ai\ProvidesFile{t2amtx.clo}
6hmtx&t2bi\ProvidesFile{t2bmtx.clo}
7hmtx&ly1i\ProvidesFile{ly1mtx.clo}
8hversioni\ProvidesFile{krntst-v.tex}
9hclass|mtx|versioni [2004/04/14 v1.32 Generate kerning tables]
6.1 Class file
Use a standard class as base.
10h∗classi
11\LoadClass[10pt]{article}
Use most of the space on the paper.
12\RequirePackage[top=18mm,left=15mm,right=15mm,bottom=20mm]{geometry}
Font for the legends.
13\renewcommand*\familydefault{\sfdefault}
14\RequirePackage{helvet}
More required packages.
15\RequirePackage{calc}
16\RequirePackage{longtable}
17\RequirePackage{array}
18\RequirePackage{color}
19\RequirePackage{ifthen}
20\RequirePackage{keyval}
Layout settings.
21\pagestyle{myheadings}
22\def\@oddfoot{Kerning data, marked with $\ast$, are automatically reused
23 from values given before.
24 Repeated values are marked by $\dagger$.\hfill}
25\def\@evenfoot{\@oddfoot}
26\setlength{\parindent}{0mm}
Declare lengths for the font size and the baselineskip.
27\newlength\krntst@size
28\newlength\krntst@baselineskip
Set the default values for the class options.
29\def\krntst@encoding{T1}
30\def\krntst@series{m}
31\def\krntst@shape{n}
32\setlength\krntst@size{17.28pt}
33\setlength\krntst@baselineskip{1.2\krntst@size}
34\def\krntst@example{example}
35\def\krntst@extraname{}
36\definecolor{oldcolor}{gray}{0.5}
37\definecolor{newcolor}{gray}{0}
38\newboolean{krntst@writeall}
The design size is given as command rather than as length because it shall not be calculated to a real length (in pt), but it shall scale with the chosen font.
39\newcommand\krntst@designsize{1em}
Process the class options using thekeyvalpackage.
40\def\ProcessOptionsWithKV#1{%
41 \let\@tempc\relax
42 \let\KVo@tempa\@empty
43 \edef\KVo@tempa{%
44 \noexpand\setkeys{#1}{%
45 \@ptionlist{\@currname.\@currext}%
46 }%
47 }%
48 \KVo@tempa
49 \let\CurrentOption\@empty
50}
Define the keys for the class options and the\kernsetupcommand.
51\define@key{krntst}{encoding}{\def\krntst@encoding{#1}}
52\define@key{krntst}{family}{\def\krntst@family{#1}}
53\define@key{krntst}{series}{\def\krntst@series{#1}}
54\define@key{krntst}{shape}{\def\krntst@shape{#1}}
55\define@key{krntst}{size}{%
56 \setlength\krntst@size{#1}%
57 \setlength\krntst@baselineskip{1.2\krntst@size}%
58}
59\define@key{krntst}{baselineskip}{\setlength\krntst@baselineskip{#1}}
60\define@key{krntst}{designsize}{\def\krntst@designsize{#1}}%
61\define@key{krntst}{example}{\def\krntst@example{#1}}
62\define@key{krntst}{papersize}{\geometry{#1}}
63\define@key{krntst}{extraname}{\def\krntst@extraname{-#1}}
64\define@key{krntst}{color}[true]{%
65 \csname if#1\endcsname
66 \definecolor{oldcolor}{gray}{0}%
67 \definecolor{newcolor}{rgb}{1,0,0}%
68 \else
69 \definecolor{oldcolor}{gray}{0.5}%
70 \definecolor{newcolor}{gray}{0}%
71 \fi
72}
Do the copying of quotation marks by introducing glyph classes.
73\define@key{krntst}{copyquotation}[true]{%
74 \csname if#1\endcsname
75 \newglyphclass{left}{leftguillemots}{guillemotleft,guilsinglleft}%
76 \newglyphclass{right}{leftguillemots}{guillemotleft,guilsinglleft}%
77 \newglyphclass{left}{rightguillemots}{guillemotright,guilsinglright}%
78 \newglyphclass{right}{rightguillemots}{guillemotright,guilsinglright}%
79 \newglyphclass{left}{leftquotes}{quotedblleft,quoteleft}%
80 \newglyphclass{right}{leftquotes}{quotedblleft,quoteleft}%
81 \newglyphclass{left}{rightquotes}{quotedblright,quoteright}%
82 \newglyphclass{right}{rightquotes}{quotedblright,quoteright}%
83 \newglyphclass{left}{basequotes}{quotedblbase,quotesinglbase}%
84 \newglyphclass{right}{basequotes}{quotedblbase,quotesinglbase}%
85 \fi
86}
87\define@key{krntst}{writeall}[true]{%
88 \setboolean{krntst@writeall}{#1}%
89 \ClassWarningNoLine{kerntest}{You are writing the new and the
90 original kerning data\MessageBreak
91 to the mtx file (option ‘writeall’). Normally, it is\MessageBreak
92 not necessary to write original data}%
93}
94\define@key{krntst}{footer}[true]{%
95 \csname if#1\endcsname
96 \else
97 \def\@oddfoot{}%
98 \def\@evenfoot{\@oddfoot}%
99 \fi
100}
\kernsetup Define the macro\kernsetupand make it available only in the preamble.
101\newcommand\kernsetup{\setkeys{krntst}}
102\@onlypreamble\kernsetup
Read in the configuration file if available. Do it before processing the options to allow the options to overwrite the configuration file entries.
103\AtEndOfClass{%
104 \InputIfFileExists{kerntest.cfg}{%
105 \message{Configuration file ‘kerntest.cfg’ loaded.}%
106 }{%
107 \message{No configuration file ‘kerntest.cfg’ found.}%
108 }
Now, process the class options.
109 \ProcessOptionsWithKV{krntst}
This has to do something with a problem in keyval.sty. I do not really know what it does exactly.
110 \let\@unprocessedoptions\relax
111}
Generate an error message if the class option family has not been given in the
\documentclasscommand.
112\ifx\krntst@family\relax
113 \ClassError{kerntest}{Class option family not or incorrect
114 given\@gobble}{%
115 You have to specify the font family by using the
116 class\MessageBreak
117 option family=<fontfamily>}%
118 \stop
119\fi
Redefine thefamilyoption to be unusable in the\kernsetupcommand.
120\AtEndOfClass{%
121 \define@key{krntst}{family}{%
122 \ClassError{kerntest}{Option ‘family’ used outside
123 \string\documentclass\space command}{%
124 The option ‘family=<fontfamily>’ has to be specified in the
125 optional argument\MessageBreak
126 of the \string\documentclass\space command.}%
127 }
128}
\mtxcomment Define a command that writes a comment to themtxfile.
129\newcommand\mtxcomment[1]{%
130 \protected@write\mtxfile{}{\@percentchar\space #1}%
131}
Define a command that is used to access the font for the legends.
132\newcommand\krntst@helpfont{\normalfont\normalsize}
An internal counter that stores the slot of a glyph.
133\newcounter{@glyphslot}%
The following commands have to be done at\begin{document}to ensure that all
\kernsetup calls have been made before.
134\AtBeginDocument{%
Load all used encodings andT1for the legends. IfT1is used, it is loaded twice; it does not seem to be bad.
135 \RequirePackage[\krntst@encoding,T1]{fontenc}
Load the file that provides the Postscript glyph names. The trick to make it lowercase ist stolen from thefontencpackage.
136 \edef\reserved@f{%
137 \lowercase{\def\noexpand\reserved@f{\krntst@encoding mtx.clo}}}%
138 \reserved@f
139 \InputIfFileExists\reserved@f{}{%
140 \ClassWarningNoLine{kerntest}{Postscript name file ‘\reserved@f’
141 not found.\MessageBreak
142 The kerning table will be okay, but the generated mtx file will
143 not be usable}%
144 \newcommand\getpsname[1]{unknown character ‘##1’}%
145 }%
Generate macros of the form \slotnumber@glyph@hglyphnamei that return the slot number for each glyph. This is faster than parsing \getpsname for the searched glyph (on the cost of memory).
146 \setcounter{@glyphslot}{0}%
147 \whiledo{\the\c@@glyphslot<256}{%
148 \expandafter\edef
149 \csname slotnumber@glyph@\getpsname{\the\c@@glyphslot}\endcsname{%
150 \the\c@@glyphslot}%
151 \stepcounter{@glyphslot}%
152 }%
Initialise some font-specific things. This is done in a group to save the normal legend font outside the kerning table.
153 \begingroup
Switch to the font that shall be tested to see if the desired font size is possible etc.
154 \usefont{\krntst@encoding}{\krntst@family}{\krntst@series}{\krntst@shape}%
155 \fontsize{\krntst@size}{\krntst@baselineskip}\selectfont%
Set the Postscript font unit to 0.001 of the design size which is 1 em, normally.
156 \psunit=\krntst@designsize\relax
157 \global\psunit=0.001\psunit
Give some feedback.
158 \typeout{Requested: \krntst@encoding-\krntst@family-%
159 \krntst@series-\krntst@shape, size \the\krntst@size}%
160 \typeout{Using:\space\space\space\space\space \f@encoding-\f@family-%
161 \f@series-\f@shape, size \f@size pt}%
162 \expandafter\ifdim\the\krntst@size=\f@size pt\relax
163 \else
164 \ClassWarningNoLine{kerntest}{Using different font size than
165 requested}%
166 \fi
167 \setlength{\@tempdima}{\krntst@designsize}%
168 \typeout{Postscript font unit for design size \the\@tempdima:
169 \the\psunit}%
170 \expandafter\ifdim\the\@tempdima=\f@size pt\relax
171 \else
172 \ClassWarningNoLine{kerntest}{The design size (\the\@tempdima,
173 1em by default,\MessageBreak
174 or given value from option ‘designsize’) of the
175 font\MessageBreak
176 is not equal to the LaTeX font size (\f@size pt).\MessageBreak
177 This can have two reasons:\MessageBreak
178 1. The font does not define 1em to be the design
179 size\MessageBreak
180 \space\space\space (for example, Computer
181 Modern).\MessageBreak
182 2. The font is implicitely scaled by the fd-file\MessageBreak
183 \space\space\space (for example, when using
184 helvet.sty).\MessageBreak
185 This can cause the PostScript font unit length to
186 be\MessageBreak
187 incorrect.
188 You may set the design size for calculation\MessageBreak
189 of the font unit explicitely by using the class\MessageBreak
190 option ‘designsize’}%
191 \fi
Define the name for the headings and the mtx file (lowercase trick again taken fromfontenc.sty).
192 \edef\mtxfilename{%
193 \lowercase{\gdef\noexpand\mtxfilename{%
194 \f@encoding-\f@family-\f@series-\f@shape\krntst@extraname}}}%
195 \mtxfilename Set the page headings.
196 \markboth{\upshape Font \mtxfilename}{\upshape Font \mtxfilename}%
Don’t change the page headings by \sectionetc.
197% \global\def\markboth#1#2{}%
198% \global\def\markright#1{}%
Open themtxfile.
199 \typeout{^^JWriting mtx file ‘\mtxfilename.mtx’^^J}%
200 \immediate\openout\mtxfile\mtxfilename.mtx Write a nice header to themtxfile.
201 \protected@write\mtxfile{}{\@percentchar\@percentchar}%
202 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
203 This is file ‘\mtxfilename.mtx’,}%
204 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
205 generated on \number\year/\number\month/\number\day\space
206 by kerntest.cls, (c) 2004 Harald Harders.}%
207 \protected@write\mtxfile{}{\@percentchar\@percentchar}%
208 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
209 The original source file was:}%
210 \protected@write\mtxfile{}{\@percentchar\@percentchar}%
211 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
212 \jobname\space (.tex?) with these font options:}%
213 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
214 Encoding: \f@encoding}%
215 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
216 Family: \space\space\f@family}%
217 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
218 Series: \space\space\f@series}%
219 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
220 Shape: \space\space\space\f@shape}%
221 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
222 User-defined name: \krntst@extraname}%
223 \protected@write\mtxfile{}{\@percentchar\@percentchar}%
224 \protected@write\mtxfile{}{\string\relax}%
225 \protected@write\mtxfile{}{\string\metrics}%
226 \protected@write\mtxfile{}{\string\needsfontinstversion{1.926}}%
227 \protected@write\mtxfile{}{\@percentchar\@percentchar}%
228 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
229 Kerning data for single characters and}%
230 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
231 the first members of the glyph classes.}%
232 \protected@write\mtxfile{}{\@percentchar\@percentchar}%
233 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
234 After each \string\setkern\space entry, the glyph classes}%
235 \protected@write\mtxfile{}{\@percentchar\@percentchar\space
236 for both glyphs are given (./. means no class).}%
237 \protected@write\mtxfile{}{\@percentchar\@percentchar}%
238 \endgroup
239}
Declare the output handle for themtxfile.
240\newwrite\mtxfile
Round a length to an integer value. I am sure this can be done easier, but it works.
241\def\krntst@round#1.#2#3#4\@empty{%
242 \setlength\@tempdimc{#1pt}%
243 \if#2.%
244 \else
245 \ifnum#2>4
246 \ifnum#1#2<0
247 \addtolength\@tempdimc{-1.1pt}%
248 \else
249 \addtolength\@tempdimc{1.1pt}%
250 \fi
251 \fi
252 \fi
253 \edef\rnd@tempa{\strip@pt\@tempdimc}%
254 \expandafter\krntst@@round\[email protected]\@empty
255}
Calculate the rounded length.
256\def\krntst@@round#1.#2#3\@empty{\def\kernlen{#1}}
\round The user routine for rounding lengths. The rounded length is not returned but saved in the macro\kernlen.
257\newcommand*\round[1]{%
258 \setlength\@tempdimc{#1}%
259 \edef\rnd@tempa{\strip@pt\@tempdimc}%
260 \expandafter\krntst@round\[email protected]\@empty
261}
Define the Postscript font length.
262\newlength\psunit
\getpsunit Saves the rounded length of arbitrary unit in Postscript font units in the dimension
\@tempdima. It has to be used with\strip@ptto get rid of the unit “pt” which is wrong of course.
263\newcommand\getpsunit[1]{%
264 \setlength\@tempdima{1pt*\ratio{#1}{\psunit}}%
265}
\getkern Get the kerning between the arguments #1and #2. This is done by typesetting
#1#2with the natural kerning and with supressed kerning (#1\kern 0pt#2). The difference of the box widths is the kerning. Return an integer value in Postscript font units.
266\newcommand\getkern[2]{%
267 \settowidth\@tempdima{#1#2}%
268 \settowidth\@tempdimb{#1\kern0pt#2}%
The next line works better than deviding \@tempdima-\@tempdimb by 0.001em because rounding errors are avoided.
269 \setlength\@tempdima{1pt*\ratio{(\@tempdima-\@tempdimb)*1000}{1em}}%
270 \round{\@tempdima}%
271}
The internal routine for \saveslotnumber. Finds out if a slot number or the Postscript name is given and saves the slot number in the counter@glyphslot.
272\def\@saveslotnumber#1#2\@empty{%
273 \if#1"\relax
274 \setcounter{@glyphslot}{#1#2}%
275 \else
276 \if#1’\relax
277 \setcounter{@glyphslot}{#1#2}%
278 \else
279 \ifnum9<1#1\relax
280 \setcounter{@glyphslot}{#1#2}%
281 \else
282 \begingroup\expandafter\expandafter\expandafter\endgroup
283 \expandafter\ifx\csname slotnumber@glyph@#1#2\endcsname\relax
284 \setcounter{@glyphslot}{-1}%
285 \else
286 \setcounter{@glyphslot}{\csname slotnumber@glyph@#1#2\endcsname}%
287 \fi
288 \fi
289 \fi
290 \fi
291 \ifnum\the\c@@glyphslot>255\relax
292 \setcounter{@glyphslot}{-1}%
293 \fi
294}
\saveslotnumber Saves the slot number of a glyph given as second argument (by PostScript name or its slot number in decimals, octal, or hexadecimals) in the counter specified in the first argument.
295\DeclareRobustCommand*\saveslotnumber[2]{%
296 \expandafter\@saveslotnumber#2\@empty
297 \setcounter{#1}{\the\c@@glyphslot}%
298}
\getslotnumber Returns the slot number of a given glyph (by PostScript name or its slot number in decimals, octal, or hexadecimals) in a decimal number.
299\newcommand\getslotnumber[1]{%
300 \expandafter\@saveslotnumber#1\@empty
301 \ifnum\the\c@@glyphslot<0\relax
302 \textbf{???}%
303 \else
304 \ifnum\c@@glyphslot<100\relax0\fi
305 \ifnum\c@@glyphslot<10\relax0\fi
306 \the\c@@glyphslot
307 \fi
308}
\printglyph Print the glyph with the given PostScript name or slot number (in decimals, octal, or hexadecimals; as usual in LATEX). Unfortunately, no kerning appears on the left side of the printed glyph. For example, \printglyph{A}V is kerned, but A\printglyph{V}isn’t. You can solve this by saving the slot number first and by using it later, for example:
%\newcounter{slotV}%
%\saveslotnumber{slotV}{V}%
%A\char\arabic{slotV}
%
309\newcommand*\printglyph[1]{%
310 \expandafter\@saveslotnumber#1\@empty
311 \char\the\c@@glyphslot
312}
A help macro for comparing arguments with “-”.
313\edef\@minussign{-}%
Counters storing the slot numbers for the three glyphs used within one line of the kerntableenvironment.
314\newcounter{@slota}
315\newcounter{@slotb}
316\newcounter{@slotc}
\testkern The main macro of the class. It takes 5 arguments:
{hglyph 1i}{hkerning 1–2i}{hglyph 2i}{hkerning 2–3i}{hglyph 3i}.
The glyphs are given by their number, not the glyphs itself.
317\newcommand\testkern[5]{%
Save the kerning arguments globally because otherwise they got lost from tabular cell to tabular cell.
318 \xdef\@kernlena{#2}%
319 \xdef\@kernlenb{#4}%
Get the slot numbers for the three characters and save them in the counters
@slota,@slotb, and @slotc.
320 \saveslotnumber{@slota}{#1}%
321 \ifnum\the\c@@slota<0%
322 \ClassError{kerntest}{Used unknown glyph ‘#1’}{%
323 You may have misspelled the glyph or you have taken an invalid
324 number.}%
325 \setcounter{@slota}{0}%
326 \fi
327 \saveslotnumber{@slotb}{#3}%
328 \ifnum\the\c@@slotb<0%
329 \ClassError{kerntest}{Used unknown glyph ‘#3’}{%
330 You may have misspelled the glyph or you have taken an invalid
331 number.}%
332 \setcounter{@slotb}{0}%
333 \fi
334 \saveslotnumber{@slotc}{#5}%
335 \ifnum\the\c@@slotc<0%
336 \ClassError{kerntest}{Used unknown glyph ‘#5’}{%
337 You may have misspelled the glyph or you have taken an invalid
338 number.}%
339 \setcounter{@slotc}{0}%
340 \fi
Find out if there are old kerning data for one of the two glyph pairs.
First pair.
The better form of\@ifundefinedthat does not define its argument as side- effect.
341 \begingroup\expandafter\expandafter\expandafter\endgroup
342 \expandafter\ifx\csname kt@kerning@\getpsname{\the\c@@slota}@%
343 \getpsname{\the\c@@slotb}\endcsname\relax No old kerning. Thus don’t do any kerning later.
344 \gdef\oldkerna{}%
345 \else
Old kerning exists. Save the old kerning to apply it later.
346 \gdef\oldkerna{%
347 \kern
348 \csname kt@kerning@\getpsname{\the\c@@slota}@%
349 \getpsname{\the\c@@slotb}\endcsname
350 \psunit
351 }%
If no new kerning ist given just tell the user that he reuses a kerning.
352 \ifx\@kernlena\@minussign
353 \typeout{Kerning pair for \getpsname{\the\c@@slota}-%
354 \getpsname{\the\c@@slotb} reused (value
355 \csname kt@kerning@\getpsname{\the\c@@slota}@%
356 \getpsname{\the\c@@slotb}\endcsname).}%
357 \else
Old kerning exists and new kerning, too. Test if the old and new kernings are identical.
358 \ifnum\@kernlena=\csname kt@kerning@\getpsname{\the\c@@slota}@%
359 \getpsname{\the\c@@slotb}\endcsname\relax Yes. Nevertheless, generate a warning.
360 \ClassWarning{kerntest}{Kerning for
361 \getpsname{\the\c@@slota}-\getpsname{\the\c@@slotb}\MessageBreak
362 repeated (value #2)}%
363 \else
No. Produce an erroe message.
364 \ClassError{kerntest}{Conflicting kerning for
365 \getpsname{\the\c@@slota}-\getpsname{\the\c@@slotb}\MessageBreak
366 (new value #2 != old value
367 \csname kt@kerning@\getpsname{\the\c@@slota}@%
368 \getpsname{\the\c@@slotb}\endcsname)%
369 }{%
370 You have given the kerning for the specified glyph pair
371 twice with different\MessageBreak
372 values. This may also appear when using glyph classes.
373 You have to give the\MessageBreak
374 kerning only once per glyph class.\MessageBreak
375 You may leave out the second kerning pair, or you may
376 give\MessageBreak
377 the kerning ‘-’. Then, the old value is reused.
378 }%
379 \fi
380 \fi
381 \fi Second pair.
382 \begingroup\expandafter\expandafter\expandafter\endgroup
383 \expandafter\ifx\csname kt@kerning@\getpsname{\the\c@@slotb}@%
384 \getpsname{\the\c@@slotc}\endcsname\relax
385 \gdef\oldkernb{}%
386 \else
387 \gdef\oldkernb{%
388 \kern
389 \csname kt@kerning@\getpsname{\the\c@@slotb}@%
390 \getpsname{\the\c@@slotc}\endcsname
391 \psunit
392 }%
393%
394 \ifx\@kernlenb\@minussign
395 \typeout{Kerning pair for \getpsname{\the\c@@slotb}-%
396 \getpsname{\the\c@@slotc} reused (value
397 \csname kt@kerning@\getpsname{\the\c@@slotb}@%
398 \getpsname{\the\c@@slotc}\endcsname).}%
399 \else
400 \ifnum\@kernlenb=\csname kt@kerning@\getpsname{\the\c@@slotb}@%
401 \getpsname{\the\c@@slotc}\endcsname\relax
402 \ClassWarning{kerntest}{Kerning for
403 \getpsname{\the\c@@slotb}-\getpsname{\the\c@@slotc}\MessageBreak
404 repeated (value #4)}%
405 \else
406 \ClassError{kerntest}{Conflicting kerning for
407 \getpsname{\the\c@@slotb}-\getpsname{\the\c@@slotc}\MessageBreak
408 (new value #4 != old value
409 \csname kt@kerning@\getpsname{\the\c@@slotb}@%
410 \getpsname{\the\c@@slotc}\endcsname)%
411 }{%
412 You have given the kerning for the specified glyph pair
413 twice with different\MessageBreak
414 values. This may also appear when using glyph classes.
415 You have to give the\MessageBreak
416 kerning only once per glyph class.\MessageBreak
417 You may leave out the second kerning pair, or you may
418 give\MessageBreak
419 the kerning ‘-’. Then, the old value is reused.
420 }%
421 \fi
422 \fi
423 \fi
First, type the slot number of glyph 2.
424 \krntst@helpfont\getslotnumber{#3}%
425 &
Type the postscript name of glyph 2.
426 \krntst@helpfont\getpsname{\the\c@@slotb}%
427 &
Print the three glyphs with original kerning.
428 \char\the\c@@slota\char\c@@slotb\char\c@@slotc%
429 &
Print glyph 1.
430 \char\the\c@@slota%
If a kerning is given, apply it; otherwise do nothing.
431 \ifx\@kernlena\@minussign
432 \oldkerna
433 \else
434 \kern#2\psunit
435 \fi Print glyph 2.
436 \char\the\c@@slotb%