07.10.2014 Views

Generating Type 1 Fonts from mEtaFoNt Sources - TUG

Generating Type 1 Fonts from mEtaFoNt Sources - TUG

Generating Type 1 Fonts from mEtaFoNt Sources - TUG

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Generating</strong> <strong>Type</strong> 1 <strong>Fonts</strong> <strong>from</strong> METAFONT <strong>Sources</strong><br />

Taco Hoekwater<br />

Kluwer Academic Publishers<br />

Dordrecht<br />

taco.hoekwater@wkap.nl<br />

Abstract<br />

This article makes a comparison between bitmapped and vector fonts, and presents some<br />

of the problems I encountered when I tried to convert METAFONT sources into PostScript<br />

<strong>Type</strong> 1 fonts.<br />

The second part of this article will focus more closely on some of the problems<br />

that I faced while trying to convert METAFONTs into PostScript <strong>Type</strong> 1 fonts, but first<br />

some explanation is in order as to why one might want to do this conversion, and<br />

precisely what this conversion entails. These topics are the subjects of the first couple<br />

of paragraphs.<br />

What are METAFONT <strong>Fonts</strong>?<br />

How characters are created<br />

I’ll assume the reader knows the following: every<br />

TEX distribution has a program called METAFONT,<br />

that compiles font sources more or less the same<br />

way that the TEX program compiles text sources.<br />

A major difference between the two programs is<br />

that METAFONT produces device--dependent output<br />

(called pk files), whereas TEX produces device--<br />

independent output (also known as dvi files).<br />

Let’s look into the font sources that METAFONT<br />

uses, and see what kind of information they contain.<br />

These are ordinary ASCII files just like TEX sources,<br />

so it was easy to insert a listing of one of these<br />

files. The file that contains the METAFONT logo<br />

font (logo10.mf) suits our purpose quite well, since<br />

it is a rather simple font that probably everybody<br />

has available:<br />

font_size:= 10pt# ;<br />

ht# :=6pt# ;<br />

xgap# :=0.6pt#;<br />

u# :=4/9pt#;<br />

s# :=0 ;<br />

o# :=1/9pt#;<br />

px# :=2/3pt#;<br />

input logo<br />

bye<br />

What do we see here? First there are a bunch of<br />

assignments (the lines that contain:=), then there is<br />

an input (this command functions the same way as<br />

TEX’s\input, so it will start reading the filelogo.mf<br />

next), and finally the last command is bye.<br />

The filelogo.mf contains the actual commands<br />

to create the characters. It helps to run METAFONT<br />

now to see what is going on. Just type the following<br />

to a system command prompt:<br />

mf logo10<br />

Probably you didn’t have to worry about where<br />

the logo10.mf file is on your hard disk, since<br />

most METAFONT implementations can do recursive<br />

directory searches just like TEX.<br />

Figure 1 METAFONT output window for modeless<br />

files<br />

You should have seen a window popping up that<br />

shows characters as they are being created (like the<br />

one in figure 1, but it might look a little different<br />

on your system). Also, there should have been some<br />

terminal output, like this:<br />

256 <strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting


<strong>Generating</strong> <strong>Type</strong> 1 <strong>Fonts</strong> <strong>from</strong> METAFONT <strong>Sources</strong><br />

This is METAFONT, Version 2.718 (Web2c<br />

7.2beta7) (logo10.mf (logo.mf [77] [69]<br />

[84] [65] [70] [80] [83] [79] [78]) )<br />

Output written on logo10.2602gf (9<br />

characters, 98 80 bytes).<br />

Transcript written on logo10.log.<br />

The numbers you see are the positions of the<br />

characters in the font. For the METAFONT logo font,<br />

these are the positions of the used characters in the<br />

ASCII table:M,E,T,A,F,P,S,O,N.Asyoucan<br />

see, they can appear in any order within the source<br />

files.<br />

The file METAFONT has written is not precisely<br />

the same as the output on your screen, instead it<br />

looks like figure 2. Not really usable when it comes<br />

to typesetting text, but it contains some pretty<br />

valuable information nevertheless.<br />

2<br />

1<br />

3<br />

Figure 2 Metafont output file for modeless files<br />

Have a look at the logo.mf file if you are interested<br />

in the nitty--gritty details. I will use only a small<br />

portion of that file to make some remarks about<br />

METAFONT. First, here is the edited program text<br />

I will use to explain things. (This is no longer valid<br />

METAFONT input, so don’t start keying it in):<br />

mode_setup;<br />

define_pixels(s,u);<br />

ygap#:=(ht#/13.5u#)*xgap#;<br />

define_whole_pixels(xgap);<br />

define_whole_vertical_pixels(ygap);<br />

py#:=.9px#;<br />

define_blacker_pixels(px,py);<br />

pickup pencircle xscaled px yscaled py;<br />

logo_pen:=savepen;<br />

4<br />

5<br />

leftstemloc#:=2.5u#+s#;<br />

define_good_x_pixels(leftstemloc);<br />

beginlogochar("M",18);<br />

x1 = x2 = leftstemloc;<br />

x4 = x5 = w - x1;<br />

x3 = w - x3;<br />

y1 = y5;<br />

y2 = y4;<br />

bot y1 = 0;<br />

top y2 = h;<br />

y3 = ygap;<br />

draw z1--z2--z3--z4--z5;<br />

labels(1,2,3,4,5);<br />

endchar;<br />

Let us first look at the line that begins with<br />

beginlogochar, because this is where the real work<br />

is done. This portion of the source defines the letter<br />

‘M’ in the font. What we see here is that characters<br />

are specified by first setting up a bunch of equations<br />

(the lines that have equal signs in them), followed<br />

by a draw command that connects those points,<br />

actually drawing the character.<br />

We won’t go deeply into METAFONT syntax,<br />

but it is vital to understand the following: a point<br />

is defined as a pair of x and y coordinates. In META-<br />

FONT syntax, points are sequentially numbered per<br />

character, starting <strong>from</strong> 1. z1 is the notation for<br />

point 1. Notations like x1 and y2 specify the x-<br />

component of point 1 and the y-component of point<br />

2, respectively.<br />

beginlogochar says that the ‘M’ is precisely<br />

18u (units) wide, andlogo10.mf has set up one u to<br />

be 4/9pt, so the actual character is 4/9×18pt = 8pt<br />

wide.<br />

TEX and METAFONT have the same author, and<br />

it shows: METAFONT can do macros just as easily as<br />

TEX can. Macros can have arguments, define other<br />

macros and assign values to things, just like in TEX.<br />

beginlogochar is in fact one of those macros, and<br />

it assigns some pretty important values when it gets<br />

expanded by METAFONT. For one, it defines w to<br />

be the width we calculated above, and it defines h<br />

to be the height of the character (calculated <strong>from</strong><br />

ht# in logo10.mf, which equals 6pt).<br />

From the values of u and s, it now follows that<br />

leftstemloc equals (2.5 × 4/9) + 0 = 10/9pt. The<br />

last value we have left is ygap = (ht/13.5u)*xgap.<br />

ht and xgap have been given in the ‘driver’ file<br />

logo10.mf, and after some small calculations ygap<br />

becomes (6pt ÷ (13.5 × 4/9pt × 0.6pt)) = 0.6pt.<br />

It should now be easy to come to the conclusion<br />

that the equations fix the precise x, y locations of the<br />

<strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting 257


Taco Hoekwater<br />

five points that denote the character ‘M’, albeit in a<br />

slightly indirect manner. If we fill in the values we<br />

derived above, we get the following:<br />

x1 = x2 = 10/9pt;<br />

x4 = x5 = 8pt - x1;<br />

x3 = 8pt - x3;<br />

y1 = y5;<br />

y2 = y4;<br />

bot y1 = 0pt;<br />

top y2 = 6pt;<br />

y3 = 0.6pt;<br />

After METAFONT has calculated these equalities for<br />

us, and with some minor reshuffling of the input, we<br />

get the following end-result:<br />

x1 = 10/9pt ; bot y1 = 0pt ;<br />

x2 = 10/9pt ; top y2 = 6pt ;<br />

x3 = 4pt ; y3 = 0.6pt;<br />

x4 = 62/9pt ; top y4 = 6pt ;<br />

x5 = 62/9pt ; bot y5 = 0pt ;<br />

2<br />

1<br />

3<br />

Figure 3 Metafont output file for modeless files,<br />

hand--calculated version<br />

We could have typed this in right away, and META-<br />

FONT would have been just as happy. The end<br />

result would have been the same, as can be seen<br />

in figure 3. 1 But why do the calculation yourself if<br />

the machine can do it for you?<br />

METAFONT’s ability to do the needed calculations<br />

all by itself is one of its most important strong<br />

points. Combined with macros and separate input<br />

files, it becomes possible to use various fonts with<br />

the same shared sources. In such a ‘font’, the only<br />

file that is different between various versions of the<br />

font is the ‘driver’ file, that assigns different values<br />

to the same parameters. METAFONT’s calculations<br />

will have different results, so that some of points will<br />

end up in slightly different locations. The resulting<br />

4<br />

5<br />

font will be similar in style but may still differ in<br />

lots of ways.<br />

Creating a full font<br />

Usually, fonts are not just a bunch of characters.<br />

There also is some other metric information included<br />

in almost every font. The final section of our<br />

example file (at the end, after all the characters have<br />

been defined) contains the following lines:<br />

ligtable "T": "A" kern -.5u#;<br />

ligtable "F": "O" kern -u#;<br />

ligtable "P": "O" kern u#;<br />

font_quad:=18u#+2s#;<br />

font_normal_space:=6u#+2s#;<br />

font_normal_stretch:=3u#;<br />

font_normal_shrink:=2u#;<br />

font_identifier:="MFLOGO" ;<br />

font_coding_scheme:="AEFMNOPST only";<br />

The first three lines belong to the ‘ligature table’.<br />

Usually it will contain both real ligatures and the<br />

kerning information for the font, but because this is<br />

a very simple font, there are only three really simple<br />

kerning pairs.<br />

The next lines define TEX’s \fontdimen values:<br />

how wide a space will be and how much it can stretch<br />

and shrink, and some other information that will<br />

appear in the created font but is generally not used<br />

by programs.<br />

Dealing with device dependence<br />

Now let’s have a look at the device dependent<br />

calculations that METAFONT does. Here is the<br />

relevant portion of the example again:<br />

mode_setup;<br />

define_pixels(s,u);<br />

ygap#:=(ht#/13.5u#)*xgap#;<br />

define_whole_pixels(xgap);<br />

define_whole_vertical_pixels(ygap);<br />

py#:=.9px#;<br />

define_blacker_pixels(px,py);<br />

There are, in fact, two kinds of device dependence<br />

that need to be dealt with. The mode_setup line<br />

takes care of the first kind of device dependence:<br />

the effects that the actual hardware of the printing<br />

engine can have on the printed font.<br />

The most obvious difference between any two<br />

printing devices is of course the resolution, but there<br />

1 Actually, figure 3 is not completely identical to figure 2,<br />

because in my example I cheated with the calculations a<br />

bit to keep the explanation simple.<br />

258 <strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting


<strong>Generating</strong> <strong>Type</strong> 1 <strong>Fonts</strong> <strong>from</strong> METAFONT <strong>Sources</strong><br />

are other problems as well. Since we prefer our<br />

output to look as close to our intended font as<br />

possible, usually a certain amount of correction is<br />

needed based on (i.e.) whether the device is going<br />

to be an inkjet printer or a laser typesetter.<br />

mode_setup cannot do this all by itself, and this<br />

is why you usually have to specify somewhere what<br />

printer you are using. Programs like dvips will call<br />

METAFONT with a command like:<br />

mf \mode=ljfour; mag=1; input logo10<br />

If we forget about that first backslash, we can<br />

see that there are two assignments and one input<br />

command on this line. The second assignment<br />

differs <strong>from</strong> 1 when a font is called within TEX using<br />

a command like<br />

\font\logohuge = logo10 at 20pt<br />

In that case, the assignment would be mag=2. The<br />

other assignment is far more interesting. META-<br />

FONT usually starts with a ‘format’ file similar to<br />

the fmt files TEX uses, and somewhere in the sources<br />

for those format files there are some definitions like<br />

this:<br />

mode_def cx =<br />

mode_param (pixels_per_inch, 300);<br />

mode_param (blacker, 0);<br />

mode_param (fillin,.2);<br />

mode_param (o_correction,.6);<br />

mode_common_setup_;<br />

enddef;<br />

Figure 4 An example of two different imaging<br />

models.<br />

All parameters besidespixels_per_inch are a little<br />

too technical to explain in detail in a short article<br />

like this one, but figure 4 tries to explain that these<br />

values really do depend on the printing engine. The<br />

drawing on the left shows a more or less standard<br />

inkjet, that shoots dots of (black) ink on the paper.<br />

The right drawing shows a (hypothetical) printing<br />

device with a radically different approach. This<br />

machine pours light on a photographic film through<br />

a raster, creating a negative image. There are still<br />

round dots, but they are inverted! It is easy to<br />

imagine that this radically different technique can<br />

have quite an impact on the resulting image.<br />

One effect that is very easy to see <strong>from</strong> the<br />

(admittedly very badly drawn) figure is that the<br />

inside corners in the right drawing are a lot blacker<br />

than in the left one. This sort of thing happens<br />

all the time in real life printing, but it often goes<br />

unnoticed because people tend to have only one<br />

printer.<br />

The second device dependency is not really related<br />

to printers at all, but is caused simply by the fact<br />

that METAFONT outputs a pixel bitmap. Although<br />

METAFONT does its calculations with a very high<br />

accuracy, this does not help at all if there are simply<br />

not enough pixels to display the character. The<br />

commands that look like define_xxx_pixels take<br />

care of this kind of dependency, whose effects can<br />

be seen in figure 5.<br />

Figure 5 The character on the right has been<br />

created with all the define xxx pixels commands<br />

removed <strong>from</strong> the source.<br />

The sub-optimal distribution of pixels in this example<br />

is caused by the underlying pixel grid that can<br />

not be changed.<br />

What are <strong>Type</strong> 1 fonts?<br />

How PostScript fonts are created<br />

PostScript <strong>Type</strong> 1 fonts are quite different <strong>from</strong><br />

METAFONT fonts. Usually, <strong>Type</strong> 1 fonts are created<br />

in a wysiwyg environment with a drawing program<br />

that is only suited for the creation of fonts. Figure 6<br />

shows the program I usually use.<br />

The graphical user interface nicely shields the<br />

designer <strong>from</strong> what is happening behind the scenes,<br />

so we need to look into the generated files themselves<br />

if we want to get more information. On Windows<br />

and Unix systems, the actual fonts are saved in<br />

a binary file with the extension pfb (short for<br />

PostScript Font Binary), and the metric information<br />

in an ascii file with extension afm (short for Adobe<br />

Font Metrics).<br />

<strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting 259


Taco Hoekwater<br />

Figure 6 An interactive font editor: Fontlab<br />

version 3<br />

What a <strong>Type</strong> 1 font looks like 2<br />

The binary representation of a <strong>Type</strong> 1 font is just<br />

a compressed version of the non-compressed ascii<br />

format, with extension pfa. So we need a program<br />

that will do the decompression for us. One of the<br />

programs that can do this is T1ascii <strong>from</strong> the<br />

T1Utils package. But running this programs leaves<br />

us with a hexadecimal encrypted file. In the early<br />

days, the encryption key was a trade secret of Adobe<br />

Incorporated. This key is now freely available, but<br />

the file format still reflects the past. Yet another<br />

program <strong>from</strong> the T1Utils can convert this form to<br />

real human-readable PostScript: T1disasm. Nowwe<br />

can look at the generated PostScript file to see how<br />

the ‘M’ is defined in <strong>Type</strong> 1 format:<br />

/M {<br />

78 800 hsbw<br />

611 -20 hstem<br />

-11 21 hstem<br />

0 66 vstem<br />

578 66 vstem<br />

581 595 rmoveto<br />

-259 -450 rlineto<br />

-259 450 rlineto<br />

-6 9 -12 7 -12 0 rrcurveto<br />

-16 -17 -12 -17 hvcurveto<br />

-563 vlineto<br />

-17 15 -13 18 vhcurveto<br />

19 14 13 17 hvcurveto<br />

439 vlineto<br />

76 -131 75 -131 75 -131 rrcurveto<br />

5 -10 12 -6 13 0 rrcurveto<br />

1408888rrcurveto<br />

75 131 75 131 76 131 rrcurveto<br />

-439 vlineto<br />

-17 14 -13 19 vhcurveto<br />

18 15 13 17 hvcurveto<br />

562 vlineto<br />

17 -17 13 -16 vhcurveto<br />

-12 0 -12 -5 -6 -11 rrcurveto<br />

closepath<br />

endchar<br />

}ND<br />

The code looks enough like normal PostScript to<br />

recognize it at first glance, but the commands<br />

themselves are not the same ones you would use in<br />

everyday graphics. The PostScript language uses<br />

reverse Polish notation for its commands, so you<br />

should read backwards, starting at the end of the<br />

line. 581 595 rmoveto means ‘move to the point<br />

with coordinates (581, 595).<br />

All values are given in a coordinate system<br />

that maps 1000 units to one em. The nullpoint<br />

lies at the lower left corner. When one uses a<br />

PostScript font in a PostScript language program,<br />

the coordinate system is initially scaled in a way<br />

such that 1000 units equal precisely 1bp. The<br />

values used to describe points and intermediate<br />

values can be negative, but never partial. This need<br />

for discrete values can be a major problem when<br />

converting METAFONT fonts, as we will see later on.<br />

Now let’s have a short look at the used commands.<br />

The command hsbw sets up the width<br />

information for this character (the first number is<br />

the left sidebearing distance, the second number the<br />

advance width). The commands that end in stem<br />

are used by the hinting system. The whole collection<br />

of commands that look likexlineto andxxcurveto<br />

are shortcuts for the ordinary PostScript commands<br />

lineto and curveto: these draw the actual outline.<br />

All of these drawing commands are always relative<br />

to the ‘current point’. The last couple of commands<br />

end the character: closepath to close the defined<br />

2 This section is loosely borrowed <strong>from</strong> Erik-Jan Vens’<br />

article “Incorporating PostScript fonts in TEX”, EuroTEX<br />

proceedings 1992, pp. 173–181.<br />

260 <strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting


<strong>Generating</strong> <strong>Type</strong> 1 <strong>Fonts</strong> <strong>from</strong> METAFONT <strong>Sources</strong><br />

path (like METAFONT’s cycle) andendchar to do<br />

the actual drawing. ND functions as def: it defines<br />

the command ‘M’ (<strong>from</strong> the first line) to mean ‘do<br />

everything between the braces’ (remember this is<br />

reverse Polish notation).<br />

/BlueValues [ -12 0 600 611 ] ND<br />

/BlueScale 0.04379 def<br />

/BlueShift 7 def<br />

/BlueFuzz 1 def<br />

/MinFeature { 16 16 } ND<br />

/StdHW [ 60 ] ND<br />

/StdVW [ 66 ] ND<br />

/ForceBold false def<br />

Alignment zones. First off, alignment zones are<br />

defined by the array called/BlueValues. The values<br />

in the array define vertical zones by specifying two<br />

y coordinates for each zone. In this case, there are<br />

only the two areas between [−12, 0] and [600, 611],<br />

but there may be more entries.<br />

Figure 7 How the character’s path is drawn.<br />

At first sight it is a little surprising to see that<br />

the PostScript representation is rather a lot longer<br />

than the METAFONT version. This is caused by<br />

another limitation of <strong>Type</strong> 1 format: every character<br />

has to define an outlined path that is filled by<br />

endchar. Thanks to this limitation, we cannot use<br />

four stroked lines to draw the ‘M’ the way we did<br />

in METAFONT, but instead are forced to trace the<br />

borders of filled shape.<br />

Dealing with device-dependencies<br />

Adobe’s <strong>Type</strong> 1 format does not supply a means of<br />

dealing with device differences directly, like META-<br />

FONT’s define_good_pixels. But of course there<br />

has to be some means of making sure that a font<br />

looks reasonable on low-resolution devices, and this<br />

is handled by a system called ‘hints’. The responsible<br />

commands are separated into two different levels:<br />

there are ‘font-level’ hints and ‘character-level’ hints.<br />

Font-level hints take care of three things:<br />

1. Alignment zones<br />

2. Standard stem widths<br />

3. Extra information to control the hinting<br />

The relevant portion of the font-file looks like this:<br />

Figure 8 An example of overshoot-suppression in<br />

PostScript: the top and bottom of the ‘O’ are<br />

adjusted so that the character becomes just as<br />

high as the ‘H’. (Figure borrowed <strong>from</strong> the Fontlab<br />

Manual.)<br />

The first entry in the array defines an area in which<br />

the y-coordinates of points (that lie within this area)<br />

are changed into the highest (second) number. For<br />

the following entry, the y-coordinate is changed into<br />

the lowest (first) number. Together, these two areas<br />

allow characters like the ‘O’ to be rendered at low<br />

resolution without sticking out unacceptably below<br />

the baseline if compared to characters like the ‘H’<br />

(see figure 8).<br />

Standard stem widths. Quite often, a vertical or<br />

horizontal line in a font will be just a little bit too<br />

large for one device pixel but not large enough for<br />

two pixels. Depending on the underlying pixel grid,<br />

the line may consequently be rendered as either one<br />

<strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting 261


Taco Hoekwater<br />

stems, and two ‘ghost’ horizontal stems. Figure 10<br />

shows the graphical representation of this character<br />

in the font editor.<br />

Figure 9 The desired result. (This figure is also<br />

borrowed <strong>from</strong> the Fontlab Manual.)<br />

or two pixels.<br />

In these problematic characters, we want to<br />

make sure at least that verticals and horizontals that<br />

are intended to have the same width throughout the<br />

font use the same number of pixels. This is done<br />

by pre-defining the widths that are supposed to be<br />

identical. The commands that pass this information<br />

to the renderer are StdVW and StdHW. The effect<br />

that a correct setting of these values has on the<br />

rendering of the font can be seen in figure 9 (Like<br />

all hinting information, these values are ignored if<br />

the stem widths are larger than three device pixels–<br />

approximating 1200 dpi for the average font. As a<br />

result, output at 1200 dpi on a new device sometimes<br />

looks inferior to the 600 dpi version for the trained<br />

eye.).<br />

Extra information to control the hinting.<br />

There are some extra commands in the example that<br />

we haven’t covered yet: the three Bluexxxx commands<br />

define (amongst other things) the pointsize<br />

below which overshoot suppression is turned on, and<br />

a fuzzy correction on the values of the alignment<br />

zones. ForceBold is used with bold fonts to make<br />

sure that they will stay at least two pixels wide at<br />

low resolutions (otherwise they would look identical<br />

to the non-bold version at small sizes).<br />

The character-level hints are handled by the commands<br />

<strong>from</strong> the top of the listing given previously:<br />

611 -20 hstem<br />

-11 21 hstem<br />

0 66 vstem<br />

578 66 vstem<br />

These define horizontal and vertical stem zones. The<br />

first number says at which coordinate to start, the<br />

second number the width to use <strong>from</strong> there. In this<br />

case (remember this is an ‘M’) there are two vertical<br />

Figure 10 The character ‘M’ <strong>from</strong> the META-<br />

FONT logo font, with PostScript hints added<br />

The ‘ghost’ stems are inserted because without them<br />

the overshoot suppression wouldn’t work.<br />

Whywewanttoconvertto<strong>Type</strong>1<br />

Now that we have looked briefly into both formats,<br />

it is obvious that conversion <strong>from</strong> METAFONT input<br />

syntax to PostScript definitions is not going to be<br />

easy. METAFONT is apparently a lot smarter than<br />

the <strong>Type</strong> 1 interpreter, much better suited to handle<br />

device dependencies, and more accurate.<br />

So, why bother at all? For practical reasons,<br />

of course. The most important incentive is the<br />

on-screen display of generated PDF files. Adobe’s<br />

Reader is very bad at displaying bitmapped fonts,<br />

so files with only <strong>Type</strong> 1 fonts look a lot better. As it<br />

is, there are quite a few METAFONT fonts that don’t<br />

(yet) have a <strong>Type</strong> 1 counterpart, so necessarily lots<br />

of TEX-generated PDF files use bitmaps.<br />

There also is another interesting motive: designing<br />

high quality fonts in METAFONT syntax is<br />

a lot easier than creating <strong>Type</strong> 1 fonts of the same<br />

quality in an interactive editor (not to mention the<br />

fact that interactive programs usually crash at every<br />

second mouse click).<br />

262 <strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting


<strong>Generating</strong> <strong>Type</strong> 1 <strong>Fonts</strong> <strong>from</strong> METAFONT <strong>Sources</strong><br />

Tasks to be handled by the<br />

conversion process<br />

Various things need to be taken care of by the<br />

conversion, but the three major parts are:<br />

1. Resolving the equations in the METAFONT<br />

sources.<br />

2. Converting stroked paths into outlined paths.<br />

3. Insertion of <strong>Type</strong> 1 style hinting information.<br />

Resolving the equations in the METAFONT<br />

sources<br />

The first item is easy to do with an already existing<br />

program: METAPOST. METAPOST is a program by<br />

John Hobby (co-author of METAFONT) that accepts<br />

METAPOST input syntax and outputs an Encapsulated<br />

PostScript picture. For example, running<br />

METAPOST on the logo fonts (using precisely the<br />

same syntax as for METAFONT) gives the following<br />

output:<br />

%!PS<br />

%%BoundingBox: 0 -1 8 7<br />

%%Creator: MetaPost<br />

%%CreationDate: 1998.05.10:1535<br />

%%Pages: 1<br />

%%EndProlog<br />

%%Page: 1 1<br />

0.66418 0 dtransform exch truncate<br />

exch idtransform pop setlinewidth<br />

[] 0 setdash<br />

1 setlinecap<br />

1 setlinejoin<br />

10 setmiterlimit<br />

gsave<br />

newpath<br />

1.10696 0.18819 moveto<br />

1.10696 5.78938 lineto<br />

3.98503 0.78595 lineto<br />

6.8631 5.78938 lineto<br />

6.8631 0.18819 lineto<br />

1 0.9 scale<br />

stroke<br />

grestore<br />

showpage<br />

%%EOF<br />

The PostScript code contained in this file is not that<br />

hard. The first few lines are just comments. The<br />

two lines that end with setlinewidth do nothing<br />

except setting the line width for strokes. It looks<br />

complex, but the code is always the same, the only<br />

things in these two lines that ever change are the<br />

two numbers.<br />

The next lines set up some values of the<br />

PostScript graphics state that do not always have<br />

a predefined value (this is just a security measure).<br />

These lines also never change. newpath is the first<br />

command that is interesting: starting <strong>from</strong> here<br />

the character is defined. Indeed, there is only one<br />

moveto, followed by four straight lines, and finally a<br />

stroke.<br />

It would be a little bit easier if the calculated<br />

values were given in units of a thousand per em,and<br />

this can be done by inserting a different mode_def.<br />

Basically, we ask METAPOST to generate a normal<br />

font file, but at a magnification of 100.375. This<br />

gives us an end result in PostScript big points, and<br />

the generated character will now look like this (some<br />

comments and irrelevant lines stripped):<br />

%!PS<br />

%%BoundingBox: 77 -12 723 612<br />

66.66722 0 dtransform exch truncate<br />

exch idtransform pop setlinewidth<br />

gsave newpath 111.1115 18.88889 moveto<br />

111.1115 581.11142 lineto<br />

399.99867 78.88953 lineto<br />

688.88585 581.11142 lineto<br />

688.88585 18.88889 lineto<br />

1 0.90001 scale stroke grestore<br />

showpage<br />

%%EOF<br />

Good. This is starting to look like something we<br />

could use. Ideally, we would prefer an output in<br />

rounded numbers, but that is not possible.<br />

Converting stroked paths into outlined<br />

paths<br />

Mr. Kinch (author of TrueTEX) has written a program<br />

called Metafog that converts METAPOST output<br />

as in the example above into the format required<br />

by the <strong>Type</strong> 1 specifications. At the moment, the<br />

program is only available as an optional extra with<br />

TrueTEX, but correspondence with Mr. Kinch indicate<br />

that it is very likely that this program will soon<br />

be available separately.<br />

Metafog reads the METAPOST EPS file, and<br />

converts this into another EPS file. It also displays<br />

some debugging information about the character on<br />

the terminal:<br />

interp: "scale" implies elliptical pen, \<br />

66.7 x 6 0.0<br />

o: scaffolded TRUE<br />

reduce: reducing shape 1 of 2<br />

reduce: reducing shape 2 of 2<br />

<strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting 263


Taco Hoekwater<br />

ie<br />

if<br />

id<br />

ic<br />

wj<br />

wk<br />

wi<br />

wh<br />

se<br />

sf<br />

sd<br />

sc<br />

wg<br />

sn<br />

wz<br />

wr<br />

sg<br />

ws<br />

sh<br />

sm<br />

wt<br />

wy<br />

si sl<br />

sj sk<br />

wu wx<br />

wv ww<br />

cl<br />

wn<br />

wm<br />

cm<br />

ig co ib<br />

ih ia<br />

wo<br />

wq<br />

cn<br />

wp<br />

Page 1--Initial Input Contour<br />

Figure 11 Metafog output file, page 1<br />

duplicate: scaffolded<br />

try_point: 0.01 value scaffold<br />

reduce: reducing shape 3 of 2<br />

.....<br />

reduce: reducing shape 5 of 4<br />

Plotting page 1 (Initial Input Contour) \<br />

... done plotting.<br />

reduce: reducing shape 1 of 1<br />

reduce: reducing shape 2 of 1<br />

Plotting page 2 (Final Result Contour) \<br />

... done plotting.<br />

Total knots used: 598 (a--wz), ~ 29% \<br />

indexable capacity<br />

The created files are pretty large, too large to<br />

include literally. This is because the file serves two<br />

purposes: it is the input format for another program<br />

(Makefont, also by Kinch) and it also shows the<br />

work that has been done by Metafog. The first page<br />

shows the result, the second page the initial input<br />

as Metafog saw it. (The output of one of these files<br />

is shown in figure 11 and figure 12.)<br />

All we have to do is run Metafog on all characters<br />

in the font. If everything went correctly, the<br />

next step in the process is running the Makefont<br />

Page 2--Final Result Contour<br />

Figure 12 Metafog output file, page 2<br />

program. But this is not always the case. Metafog<br />

has its flaws, and it is especially bad at handling<br />

complex characters. One of those trickier characters<br />

is given in figure 13.<br />

Figure 13 The character ‘X’ <strong>from</strong> Ralph Smith’s<br />

Formal Script<br />

In order to handle cases like this gracefully, Metafog<br />

has a special startup option that gives a half-way<br />

result: it cuts the supplied shape in pieces, but it<br />

does not try to remove parts that are not needed.<br />

264 <strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting


<strong>Generating</strong> <strong>Type</strong> 1 <strong>Fonts</strong> <strong>from</strong> METAFONT <strong>Sources</strong><br />

There is yet another program in the Metafog suite<br />

that helps for the problematic characters.<br />

original METAFONT sources, but these are ignored<br />

by METAPOST, and subsequent portions of the<br />

conversion do not have access to them. This is<br />

the major reason for the need of a commercial font<br />

editor. <strong>Type</strong> 1 hinting is too complicated a process<br />

to rely on any non-interactive program to make the<br />

right choices.<br />

Another thing that must be checked, especially<br />

for symbolic fonts, is the turning direction of the<br />

subpaths. In PostScript, whether a path will be<br />

black or white depends on how the path turns:<br />

clockwise or counterclockwise. Metafog sometimes<br />

gets confused, and outputs a character in which<br />

two concentric circles both turn leftward (like in<br />

an ‘O’ or the diameter symbol <strong>from</strong> the Waldi<br />

Symbol font). In those cases, the character will be<br />

completely filled, which is of course wrong.<br />

Figure 14 Screendump of the weeder’s window<br />

This program is called the ‘weeder’ (figure 14). It<br />

is an interactive program that reads the half-way<br />

result Metafog created. The human operator now<br />

has to select the partial lines that are supposed to<br />

belong to the shape, and the weeder will write a<br />

finished file for use by Makefont (just like Metafog<br />

itself would have done if things had gone right the<br />

first time).<br />

For some fonts, one has to do almost every<br />

character ‘by hand’, for other fonts none at all.<br />

The point of view the machine has on what precisely<br />

denotes a complicated character can be rather<br />

unexpected: sometimes a character can look very<br />

simple to you but be almost impossible to process<br />

by Metafog (usually characters that use draw and<br />

fill commands that intersect somewhere). And the<br />

other way around also happens: large portions of the<br />

nash14 (arabic) font looked exceedingly complex to<br />

me, but were in fact handled by Metafog without<br />

any problems.<br />

Either way, eventually there will be EPS files<br />

available for all characters in the font. Makefont<br />

combines all of the separate files into one PostScript<br />

file, and the last step of the actual conversion process<br />

is running the T1Utils to get a binary representation<br />

that can be fed into a commercial font editor.<br />

Insertion of <strong>Type</strong> 1 style hinting<br />

information<br />

The pfb file created at the end of step two still has<br />

a couple of major flaws that need to be fixed. First<br />

and foremost among these: there are absolutely no<br />

<strong>Type</strong> 1 hints included. There were hints in the<br />

Figure 15 Paths that turn the wrong way<br />

The absolutely final step (so far I’ve needed to do<br />

this for every commercial font program I could find)<br />

is disassembling the pfb file, running a perl script to<br />

fix some incompatibilies/bugs in the used font editor<br />

and to insert a couple of workarounds for bugs in<br />

software that uses the font, and reassembling.<br />

What I have done already and<br />

future plans<br />

So far, I have converted four METAFONT fonts that<br />

I needed myself. The files that are now available<br />

<strong>from</strong> CTAN are:<br />

<strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting 265


Taco Hoekwater<br />

logo wasy2 stmary rsfs<br />

All of these files reside in a subdirectory of the<br />

METAFONT sources, named ps-type1/hoekwater.<br />

Each directory also contains a README file that gives<br />

some detailed information about the font in question<br />

and its copyrights.<br />

Please take note of the fact that I only want<br />

to give support for problems that are intrinsically<br />

related to the .pfb files themselves. I don’t have<br />

enough spare time to help people with problems<br />

related to the integration of the fonts into their TEX<br />

distributions. If somebody wants to volunteer for<br />

this job, please let me know and I will add you to<br />

the readme.<br />

I plan to add other fonts in the near future<br />

(some of which may have been uploaded already by<br />

the time you read this). The original announcement<br />

of the availability of the files that are now on CTAN<br />

almost immediately resulted in a doubling of the<br />

length of my wish list.<br />

The following fonts are TODO and will definitely<br />

be done before the summer:<br />

• At least the most important fonts that are<br />

needed by the wsuipa package: tipaxx and<br />

xipaxx<br />

• The Nash font that is used by ArabTEX<br />

(Klaus Lagally says that he needs to fix<br />

and update the METAFONT sources first).<br />

• The Blackboard Bold font (actually,<br />

everything that is needed for the new<br />

math font encoding will be available<br />

in <strong>Type</strong> 1 before the end of the year).<br />

• At least one each of the Greek, Cyrillic and<br />

Hebrew text font families (could someone<br />

please point me to the ‘best’ font of those that<br />

are available?).<br />

• The manfnt (requested by Phil Taylor).<br />

Every font (presuming 256 characters) takes about<br />

one day to complete. This does not sound like too<br />

much time, but unfortunately I also have other work<br />

to do :-(<br />

I am still open for requests, but you may have<br />

to wait a couple of months.<br />

For further reading<br />

On the METAFONT language: Donald E. Knuth,<br />

“The METAFONTBook”. Addison-Wesley Publishing<br />

Company, June 1986, 361 pages.<br />

On using METAFONT to design real life fonts: Donald<br />

E. Knuth, “Computer Modern <strong>Type</strong>faces<br />

(Computers and <strong>Type</strong>setting, volume E)”. Addison-Wesley<br />

Publishing Company, June 1986,<br />

588 pages.<br />

On the PostScript Language: Adobe Systems Inc,<br />

“The PostScript Language Reference Manual”.<br />

Addison-Wesley Publishing Company, December<br />

1990, 764 pages.<br />

On METAPOST: John Hobby, “A User’s manual<br />

for METAPOST”, AT&T Bell Laboratories<br />

Computing Science Technical Report 162, 1992.<br />

Comes as part of the METAPOST distribution.<br />

On <strong>Type</strong> 1 fonts: Adobe Systems Inc, “Adobe<br />

<strong>Type</strong> 1 Font Format”. Addison-Wesley Publishing<br />

Company, June 1995.<br />

On the Metafog program: Richard J. Kinch, “Converting<br />

METAFONT Shapes to Outlines”. Paper<br />

presented at the 1995 <strong>TUG</strong> Conference in St<br />

Petersburg, Florida, USA. Appeared in print in<br />

<strong>TUG</strong>boat 16.3<br />

266 <strong>TUG</strong>boat, Volume 19 (1998), No. 3— Proceedings of the 1998 Annual Meeting

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!