<< . .

. 5
( : 45)

. . >>

these made the information complete. There should be one x equation and one
y equation for each position; or you can use a z equation, which de¬nes both x
and y simultaneously.
It™s a nuisance to write long-winded ¬ll commands when broad-edge
pens are being simulated in this way, so provides a convenient ab-
breviation: You can write simply
penstroke z1e . . z2e {right } . . {right }z3e
instead of the command ˜ ¬ll z1l . . z2l {right } . . {right } z3l - - z3r {left } . .
{left } z2r . . z1r - - cycle™ that was stated earlier. The letter ˜e™ stands for the
pen™s edge. A penstroke command ¬lls the region ˜p.l - - reverse p.r - - cycle™,
where p.l and p.r are the left and right paths formed by changing each ˜e™ into
˜l™ or ˜r™, respectively.
The penstroke abbreviation can be used to draw cyclic paths as well as
ordinary ones. For example, the circle in exercise 4.8 was created by saying
simply ˜penstroke z1e . . z2e . . z3e . . z4e . . cycle™. This type of penstroke essentially
expands into
¬ll z1r . . z2r . . z3r . . z4r . . cycle;
un¬ll z1l . . z2l . . z3l . . z4l . . cycle;
or the operations ˜¬ll™ and ˜un¬ll™ are reversed, if points (z1r , z2r , z3r , z4r ) are on the
inside and (z1l , z2l , z3l , z4l ) are on the outside.
The circle of exercise 4.8 was actually drawn with a slightly more complicated
penstroke command than just claimed: The edges of the curve were forced to be
vertical at positions 1 and 3, horizontal at 2 and 4. How did the author do this?
28 Chapter 4: Pens

Here™s an example of how this new sort of pen can be used to draw a sans- I
serif letter ˜ ™. As usual, we assume that two variables, h and w, have been set up assignment
to give the height and width of the character in pixels. We :=
(0,h) (w,h) hex
shall also assume that there™s a stem parameter, which
speci¬es the nominal pen breadth. The breadth decreases
to .9stem in the middle of the stroke, and the pen angle
changes from 15—¦ to 10—¦ :
penpos1 (stem , 15); penpos2 (.9stem , 12); (Figure 4j will be
inserted here; too
penpos3 (stem , 10); x1 = x2 = x3 = .5w; bad you can™t see it
y1 = h; y2 = .55h; y3 = 0;
x2l := 1 [x2l , x2 ];
penstroke z1e . . z2e {down} . . z3e .
Setting x1 = x2 = x3 = .5w centers the stroke; setting
y1 = h and y3 = 0 makes it sit in the type box, protruding (0,0) (w,0)

just slightly at the top and bottom.
The second-last line of this program is something that we haven™t seen
before: It resets x2l to a value 1/6 of the way towards the center of the pen,
thereby making the stroke taper a bit at the left. The ˜:=™ operation is called an
assignment; we shall study the di¬erences between ˜:=™ and ˜=™ in Chapter 10.
It is important to note that these simulated pens have a serious limitation
compared to the way a real calligrapher™s pen works: The left and right edges
of a penpos -made pen must never cross, hence it is necessary to turn the pen when
going around a curve. Consider, for example, the following two curves:

(Figure 4k will be inserted here; too bad you can™t see it now.)

The left-hand circle was drawn with a broad-edge pen of ¬xed breadth, held at a ¬xed
angle; consequently the left edge of the pen was responsible for the outer boundary on
the left, but the inner boundary on the right. (This curve was produced by saying
˜pickup pencircle xscaled 0.8pt rotated 25; draw z1 . . z2 . . cycle™.) The right-hand
shape was produced by ˜penpos1 (0.8pt , 25); penpos2 (0.8pt , 25); penstroke z1e . . z2e . .
cycle™; important chunks of the shape are missing at the crossover points, because they
don™t lie on either of the circles z1l . . z2l . . cycle or z1r . . z2r . . cycle.

To conclude this chapter we shall improve the hex character of Chapter 2,
which is too dark in the middle because it has been drawn with a pen of
uniform thickness. The main trouble with unvarying pens is that they tend to produce
black blotches where two strokes meet, unless the pens are comparatively thin or unless
the strokes are nearly perpendicular. We want to thin out the lines at the center just
Chapter 4: Pens 29

enough to cure the darkness problem, without destroying the illusion that the lines still angle
seem (at ¬rst glance) to have uniform thickness.
It isn™t di¬cult to produce ˜ ™ instead of
˜ ™ when we work with dynamic pens:
pickup pencircle scaled b;
top z1 = (0, h); top z2 = (.5w, h); top z3 = (w, h);
bot z4 = (0, 0); bot z5 = (.5w, 0); bot z6 = (w, 0); draw z2 . . z5 ;
z1 = .25[z1 , z6 ]; z6 = .75[z1 , z6 ]; z3 = .25[z3 , z4 ]; z4 = .75[z3 , z4 ];
theta 1 := angle(z6 ’ z1 ) + 90;
(0,h) (w,h)
theta 3 := angle(z4 ’ z3 ) + 90;
penpos1 (b, theta 1 ); penpos6 (b, theta 1 );
penpos3 (b, theta 3 ); penpos4 (b, theta 3 ); (Figure 4l will be inserted here;
too bad you can™t see it now.)
penpos7 (.6b, theta 1 ); penpos8 (.6b, theta 3 );
z7 = z8 = .5[z1 , z6 ];
draw z1 . . z1 ; draw z6 . . z6 ; (0,0) (w,0)
draw z3 . . z3 ; draw z4 . . z4 ;
penstroke z1 e {z6 ’ z1 } . . z7e . . {z6 ’ z1 }z6 e ;
penstroke z3 e {z4 ’ z3 } . . z8e . . {z4 ’ z3 }z4 e .
Here b is the diameter of the pen at the terminal points; ˜angle™ computes the direction
angle of a given vector. Adding 90—¦ to a direction angle gives a perpendicular direction
(see the de¬nitions of theta 1 and theta 3 ). It isn™t necessary to take anything o¬ of the
vertical stroke z2 . . z5 , because the two diagonal strokes ¬ll more than the width of
the vertical stroke at the point where they intersect.
(0,h) (w,h)
Modify the hex character so that its ends are
(Figure 4m will be inserted
cut sharply and con¬ned to the bounding box, as shown. here; too bad you can™t see it

(0,0) (w,0)

It is very important that the nib be cut “sharp,”
and as often as its edge wears blunt it must be resharpened.
It is impossible to make “clean cut” strokes with a blunt pen.
” EDWARD JOHNSTON, Writing & Illuminating, & Lettering (1906)

I might compare the high-speed computing machine
to a remarkably large and awkward pencil
which takes a long time to sharpen and
cannot be held in the ¬ngers in the usual manner so that it
gives the illusion of responding to my thoughts,
but is ¬tted with a rather delicate engine
and will write like a mad thing
provided I am willing to let it dictate pretty much
the subjects on which it writes.
” R. H. BRUCK, Computational Aspects of Certain
Combinatorial Problems (1956)
(page 30)

Chapter 5: Running 31

It™s high time now for you to stop reading and to start playing with the computer, mf
since is an interactive system that is best learned by trial and error. backslash
(In fact, one of the nicest things about computer graphics is that errors are often return
more interesting and more fun than “successes.”) *
You probably will have to ask somebody how to deal with the idiosyn- showit
crasies of your particular version of the system, even though itself end
works in essentially the same way on all machines; di¬erent computer terminals mfput
and di¬erent hardcopy devices make it necessary to have somewhat di¬erent
interfaces. In this chapter we shall assume that you have a computer terminal
with a reasonably high-resolution graphics display; that you have access to a
(possibly low-resolution) output device; and that you can rather easily get that
device to work with newly created fonts.
OK, are you ready to run the program? First you need to log in, of
course; then start , which is usually called mf for short. Once you™ve
¬gured out how to do it, you™ll be welcomed by a message something like
This is METAFONT, Version 2.0 (preloaded base=plain 89.11.8)
The ˜**™ is ™s way of asking you for an input ¬le name.
Now type ˜\relax™”that™s backslash, r, e, l, a, x”and hit return
(or whatever stands for “end-of-line” on your keyboard). is all geared
up for action, ready to make a big font; but you™re saying that it™s all right to take
things easy, since this is going to be a real simple run. The backslash means that
should not read a ¬le, it should get instructions from the keyboard;
the ˜relax™ means “do nothing.”
The machine will respond by typing a single asterisk: ˜*™. This means
it™s ready to accept instructions (not the name of a ¬le). Type the following,
just for fun:
drawdot (35,70); showit;
and return ”don™t forget to type the semicolons along with the other stu¬. A
more-or-less circular dot should now appear on your screen! And you should also
be prompted with another asterisk. Type
drawdot (65,70); showit;
and return , to get another dot. (Henceforth we won™t keep mentioning the
necessity of return ing after each line of keyboard input.) Finally, type
draw (20,40)..(50,25)..(80,40); showit; shipit; end.
This draws a curve through three given points, displays the result, ships it to an
output ¬le, and stops. should respond with ˜[0]™, meaning that it
has shipped out a character whose number is zero, in the “font” just made; and
it should also tell you that it has created an output ¬le called ˜mfput.2602gf™.
(The name mfput is used when you haven™t speci¬ed any better name in response
32 Chapter 5: Running

to the ** at the beginning. The su¬x 2602gf stands for “generic font at 2602 **
pixels per inch.” The data in mfput.2602gf can be converted into fonts suitable generic font
for a wide assortment of typographical output devices; since it doesn™t match GFtoDVI
the font ¬le conventions of any name-brand manufacturer, we call it generic.) mode setup
This particular ¬le won™t make a very interesting font, because it con-
tains only one character, and because it probably doesn™t have the correct res-
olution for your output device. However, it does have the right resolution for
hardcopy proofs of characters; your next step should therefore be to convert the
data of mfput.2602gf into a picture, suitable for framing. There should be a
program called GFtoDVI on your computer. Apply it to mfput.2602gf, thereby
obtaining a ¬le called mfput.dvi that can be printed. Your friendly local com-
puter hackers will tell you how to run GFtoDVI and how to print mfput.dvi; then
you™ll have a marvelous souvenir of your very ¬rst encounter with .
Once you have made a complete test run as just described, you will know
how to get through the whole cycle, so you™ll be ready to tackle a more complex
project. Our next experiment will therefore be to work from a ¬le, instead of
typing the input online.
Use your favorite text editor to create a ¬le called io.mf that contains
the following 23 lines of text (no more, no less):
em#:=10pt#; cap#:=7pt#;
thin#:=1/3pt#; thick#:=5/6pt#;
curve_sidebar=round 1/18em;
beginchar("O",0.8em#,cap#,0); "The letter O";
penpos1(thick,10); penpos2(.1[thin,thick],90-10);
penpos3(thick,180+10); penpos4(thin,270-10);
x1l=w-x3l=curve_sidebar; x2=x4=.5w;
y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
penstroke z1e{down}..z2e{right}
penlabels(1,2,3,4); endchar;
def test_I(expr code,trial_stem,trial_width) =
stem#:=trial_stem*pt#; define_blacker_pixels(stem);
beginchar(code,trial_width*em#,cap#,0); "The letter I";
penpos1(stem,15); penpos2(stem,12); penpos3(stem,10);
x1=x2=x3=.5w; y1=h; y2=.55h; y3=0; x2l:=1/6[x2l,x2];
penstroke z1e..z2e{down}..z3e;
penlabels(1,2,3); endchar; enddef;

(But don™t type the numbers at the left of these lines; they™re only for reference.)
Chapter 5: Running 33

This example ¬le is dedicated to Io, the Greek goddess of input and Io
output. It™s a tri¬‚e long, but you™ll be able to get worthwhile experience by units of measure
typing it; so go ahead and type it now. For your own good. And think about pt
what you™re typing, as you go; the example introduces several important features de¬ne pixels
of that you can learn as you™re creating the ¬le. de¬ne blacker pixels
Here™s a brief explanation of what you™ve just typed: Line 1 contains a
command that usually appears near the beginning of every ¬le; it
tells the computer to get ready to work in whatever “mode” is currently desired.
(A ¬le like io.mf can be used to generate proofsheets as well as to make fonts
for a variety of devices at a variety of magni¬cations, and ˜mode setup™ is what
adapts to the task at hand.) Lines 2“8 de¬ne parameters that will
be used to draw the letters in the font. Lines 9“16 give a complete program for
the letter ˜O™; and lines 17“23 give a program that will draw the letter ˜I™ in a
number of related ways.
It all looks pretty frightening at ¬rst glance, but a closer look shows
that Io is not so mysterious once we penetrate her disguise. Let™s spend a few
minutes studying the ¬le in more detail.
Lines 2“4 de¬ne dimensions that are independent of the mode; the ˜#™
signs are meant to imply “sharp” or “true” units of measure, which remain the
same whether we are making a font at high or low resolution. For example, one
˜pt#™ is a true printer™s point, one 72.27th of an inch. This is quite di¬erent from
the ˜pt ™ we have discussed in previous chapters, because ˜pt ™ is the number of
pixels that happen to correspond to a printer™s point when the current resolu-
tion is taken into account. The value of ˜pt#™ never changes, but mode setup
establishes the appropriate value of ˜pt ™.
The assignments ˜em#:=10pt#™ and ˜cap#:=7pt#™ in line 2 mean that the
Io font has two parameters, called em and cap , whose mode-independent values
are 10 and 7 points, respectively. The statement ˜define_pixels(em,cap)™ on
line 5 converts these values into pixel units. For example, if we are working at
the comparatively low resolution of 3 pixels per pt, the values of em and cap
after the computer has performed the instructions on line 5 will be em = 30
and cap = 21. (We will see later that the widths of characters in this font are
expressed in terms of ems, and that cap is the height of the capital letters. A
change to line 2 will therefore a¬ect the widths and/or heights of all the letters.)
Similarly, the Io font has parameters called thin and thick , de¬ned on
line 3 and converted to pixel units in line 6. These are used to control the breadth
of a simulated pen when it draws the letter O. Experience has shown that -
produces better results on certain output devices if pixel-oriented pens are
made slightly broader than the true dimensions would imply, because black pixels
sometimes tend to “burn o¬” in the process of printing. The command on line 6,
˜define_blacker_pixels™, adds a correction based on the device for which the
font is being prepared. For example, if the resolution is 3 pixels per point, the
value of thin when converted from true units to pixels by de¬ne pixels would
be 1, but de¬ne blacker pixels might set thin to a value closer to 2.
34 Chapter 5: Running

The ˜o™ parameter on line 4 represents the amount by which curves will o
overshoot their boundaries. This is converted to pixels in yet another way on sidebar
line 7, so as to avoid yet another problem that arises in low-resolution printing. rounding
The author apologizes for letting such real-world considerations intrude into a TeX
textbook example; let™s not get bogged down in fussy details now, since these
re¬nements will be explained in Chapter 11 after we have mastered the basics.
For now, the important point is simply that a typeface design usually in-
volves parameters that represent physical lengths. The true, “sharped” forms of
these parameters need to be converted to “unsharped” pixel-oriented quantities,
and best results are obtained when such conversions are done carefully. After
has obeyed line 7 of the example, the pixel-oriented parameters em ,
cap , thin , thick , and o are ready to be used as we draw letters of the font.
Line 8 de¬nes a quantity called curve sidebar that will measure the
distance of the left and right edges of the ˜O™ from the bounding box. It is com-
puted by rounding 18 em to the nearest integer number of pixels. For example,
if em = 30 then 30 = 5 yields the rounded value curve sidebar = 2; there will
18 3
be two all-white columns of pixels at the left and right of the ˜O™, when we work
at this particular resolution.
Before we go any further, we ought to discuss the strange collection of
words and pseudo-words in the ¬le io.mf. Which of the terms ˜mode_setup™, ˜em™,
˜curve_sidebar™ and so forth are part of the language, and which of
them are made up speci¬cally for the Io example? Well, it turns out that almost
nothing in this example is written in the pure language that the
computer understands! is really a low-level language that has been
designed to allow easy adaptation to many di¬erent styles of programming, and
io.mf illustrates just one of countless ways to use it. Most of the terms in io.mf
are conventions of “plain ,” which is a collection of subroutines found
in Appendix B. ™s primitive capabilities are not meant to be used
directly, because that would force a particular style on all users. A “base ¬le” is
generally loaded into the computer at the beginning of a run, so that a standard
set of conventions is readily available. ™s welcoming message, quoted
at the beginning of this chapter, says ˜preloaded base=plain™; it means that
the primitive language has been extended to include the features
of the plain base ¬le. This book is not only about ; it also explains
how to use the conventions of ™s plain base. Similarly, The TEXbook
describes a standard extension of TEX called “plain TEX format”; the “plain”
extensions of TEX and are completely analogous to each other.
The notions of mode setup, de¬ne pixels, beginchar, penpos , and
many other things found in io.mf are aspects of plain but they are
not hardwired into itself. Appendix B de¬nes all of these things, as
well as the relations between “sharped” and “unsharped” variables. Even the
fact that z1 stands for (x1 , y1 ) is de¬ned in Appendix B; does not
have this built in. You are free to de¬ne even fancier bases as you gain more
experience, but the plain base is a suitable starting point for a novice.
Chapter 5: Running 35

If you have important applications that make use of a di¬erent base ¬le, it™s mf
possible to create a version of that has any desired base preloaded.
Computer Modern
Such a program is generally called by a special name, since the nickname ˜mf™ is reserved **
for the version that includes the standard plain base assumed in this book. For example, ampersand
the author has made a special version called ˜cmmf™ just for the Computer Modern bounding box
typefaces he has been developing, so that the Computer Modern base ¬le does not sharped
have to be loaded each time he makes a new experiment.
There™s a simple way to change the base ¬le from the one that has been rounded
preloaded: If the ¬rst character you type in response to ˜**™ is an ampersand
( ˜&™ ), will replace its memory with a speci¬ed base ¬le before proceeding.
If, for example, there is a base ¬le called ˜cm.base™ but not a special program called
˜cmmf™, you can substitute the Computer Modern base for the plain base in mf by
typing ˜&cm™ at the very beginning of a run. If you are working with a program that
doesn™t have the plain base preloaded, the ¬rst experiment in this chapter won™t work as
described, but you can do it by starting with ˜&plain \relax™ instead of just ˜\relax™.
These conventions are exactly the same as those of TEX.

Our Ionian example uses the following words that are not part of plain
: em , cap , thin , thick , o , curve sidebar , test I , code , trial stem ,
trial width , and stem . If you change these to some other words or symbols”for
example, if you replace ˜thin™ and ˜thick™ by ˜t™ and ˜T™ respectively, in lines
3, 6, 10, and 11”the results will be unchanged, unless your substitutions just
happen to clash with something that plain has already pre¨mpted.
In general, the best policy is to choose descriptive terms for the quantities in
your programs, since they are not likely to con¬‚ict with reserved pseudo-words
like penpos and endchar.
We have already noted that lines 9“16 of the ¬le represent a program
for the letter ˜O™. The main part of this program, in lines 10“15, uses the ideas
of Chapter 4, but we haven™t seen the stu¬ in lines 9 and 16 before. Plain
makes it convenient to de¬ne letters by starting each one with
beginchar ( code , width , height , depth );
here code is either a quoted single character like "O" or a number that rep-
resents the character™s position in the ¬nal font. The other three quantities
width , height , and depth say how big the bounding box is, so that typeset-
ting systems like TEX will be able to use the character. These three dimensions
must be given in device-independent units, i.e., in “sharped” form.

<< . .

. 5
( : 45)

. . >>