\input mftmac
$\9intromf.mf\par
/book $>$ mf

This is METAFONT, Version 2.71 (C version d)

 **
\BL
The web2c implementation of \mf\ and \TeX\ we use adopts the
convention that the executables look for similarly named formats.
Thus, {\tt mf} (which is just a symlink to {\tt virmf}, the `virgin'
\mf\ binary) will try to load the {\tt mf.base} format.

To make a new format called pmf.base, creat a file called pmf.ini
containing: {\tt input plain; input modes; input plocal; dump}
and then run: {\tt inimf pmf.ini}. Both {\tt  inimf} and {\tt virmf}
will
try filename with an added default extension of {\tt .mf} first when
searching for files.
Here {\tt modes.mf} is Karl Berry's mode definition file for various
output devices and {\tt plocal.mf} contains some macros you want to
compile into the default base. To use this format, {\tt ln -s
/usr/TeX/bin/virtex /usr/TeX/pmf}; then running {\tt pmf} will load
the {\tt pmf.base} file (which should be in the {\tt
/usr/TeX/lib/mf/bases} directory.

Part of the plain.mf file that you may want to personalize is
\BL
{\tt \obeylines
newinternal screen\_rows, screen\_cols, currentwindow;
screen\_rows:=400;     \% these values are changed in
screen\_cols:=500;     \% the mode.mf file read in next
def openit = openwindow currentwindow
 from origin to (screen\_rows,screen\_cols) at (-50,300) enddef;\par}
\BL
The `at' coordinate is the position of the top left corner of the
\mf\ window (not the X window) with respect to the origin. Notice
that, unlike the Cartesian `at' coordinate, the `from' and `to' values
are in {\tt (row,column)} format in which the {\it first\/} coordinate
is the
number of rows {\it down\/} from the top (Knuth {\it claims\/} that
``they seem appropriate when applied to screens'' -- the two
conflicting
conventions in one statement seem confusing). You may
want to put different values into {\tt modes.mf} or some local
file, for example:
\hb local.mf;
{\tt\obeylines input modes;
screen\_rows:=500; screen\_cols:=700;
pair screen\_topleft;
screen\_topleft:=(-0.1screen\_cols,screen\_rows-100);
def openit = openwindow currentwindow from origin
 to (screen\_rows,screen\_cols) at screen\_topleft;
enddef;
localfont:=CanonCX;
base\_version := base\_version \& "mybase";}
\BL
{\bf NOTE:} Something similar to the {\tt screen\_topleft} variable is
necessary to do screen-oriented programming with \mf. Although the
base format includes the screen size, a program can not otherwise find
out the position of the origin within the screen window. The \mf\
programs in this text will assume that {\tt screen\_topleft} has been
assigned an appropriate value.
\hb \mf\ and X Windows;
You may want to run \mf\ itself with, say, {\tt xterm
-sb -geometry 80x25+0-0 -fn 9x15 -e mf \&}.
The {\tt -sb} instructs xterm to use a vertical
scrollbar.
You control the X window that \mf\ will open by entries in your
{\tt .Xdefaults} file:
\BL
{\tt \obeylines mf*geometry: -0+0
mf*height:      500
mf*width:       700 \par}
\BL
{\it Note:\/} one should have {\tt screen\_rows=mf*height,
screen\_cols=mf*width}.
Also, the mf resources specified above for X~Windows refer not to the
xterm window in which \mf\ is
running, but rather to the window it will open to display graphics.
See Appendix 4 for a sample .Xdefaults file and related information on
customizing X Windows (and fvwm, xterm, etc.); we will have little
else to say about X. {\bf Note:} in fact, to save time \& space,
currently {\tt fvwm} is the window manager and {\tt rxvt} is also
included as is the {\tt ksh (pd)} shell.
\BL
**$\backslash$relax;
\BL
Initially, \mf\ expects to read the name of a font file. The backslash
says that instead, you will be using \mf\ interactively and the {\tt
relax} just does nothing (any other command would do as well).
\BL
To setup for the current mode (i.e., whether {\tt proof} or
{\tt localfont}, etc. one uses:
\BL
$\5{mode\_setup};$\par
\BL
$\2{drawdot}(0,0);$\par
$\5{showit};$\par
\BL
{\bf Note:} Normally, \mf\ inserts a blank line and then prints an
asterick prompting for input. To make cut and paste operations in
Emacs or {\tt xterm} easier, the {\tt mf} binary in the milieu package
has been made from a modified {\tt mf.web}.\footnote{${}^1$}{Web is
Knuth's programming system. A web source file is {\tt tangled} to
produce the program and {\tt weaved} to produce its documentation.
The web system provides excellent support for true ``top-down''
writing of programs.} In section 679 ({\it see
METAFONT: The Program\/}), I've deleted {\tt print\_ln;} and use a
space, instead of an asterick, as {\tt prompt\_input}'s argument.
\BL
The first time that
{\tt showit} is executed, \mf\ will call the openit macro which will
cause the X server to open a window for the \mf\ drawings.
Note that drawn objects must be explicitly shown. To change this
default so that curves, etc. are shown immediately, one says:
\BL
$\5{screenstrokes};\ \9I usually use this to begin with\par
$\9instead of `relax'\par
$\5{clearit};$\par
$\5{showit};\ \2{drawdot}\\{origin}+(70,10);$\par
\BL
\hb First macro;
Since clearing isn't shown automatically,
we have to show the clear; then we draw another dot. The origin can be
referred to by name or value and one can do vector addition (and much
else) with the points. There isn't a way to have {\tt clearit} take
effect immediately; instead, let's write our first macro:
\BL
$\2{def}\5{cc}=\5{clearit};\ \5{showit};$\par
\quad\quad\quad\quad\quad\quad\quad$\!\3{enddef};$\par
\BL
Thus when we enter {\tt cc;} \mf\ translates it into {\tt clearit;
showit;;}  so the screen is erased. Statements
in \mf\ end with a `;' (extra semi-colons are fine since the empty
statement is a statement in \mf) and white space is ignored.
\hb Equations;
$x_{1}:=x_{2}:=50;\ y_{1}+y_{2}=100;\ y_{1}=60+y_{2};\ %
\2{drawdot}(x_{1},y_{1});$\par
\BL
In \mf\ only numeric variables need not be declared. Variables can be
{\it assigned\/} values with {\tt :=}, as in Pascal. However, one can
also declare systems of linear equations\footnote{${}^*$}{
Via it's {\tt solve} macro, \mf\ also has a limited ability to solve
nonlinear equations. Namely, if one can consider one of the
variables to have a fixed value so that  only one of the resulting
equations is nonlinear (in the remaining variables), then the original
$(N\times N)$ system can be solved.}
 and leave their solution to
\mf. This
declarative nature of \mf\ leads to a different style of programming
than in procedural languages such as {\tt C}.

Variables can have their
values {\it re\-assigned\/} with {\tt `:='}, we don't use equations to
do this since an inconsistent set of equations would result. Unlike
assignments, equations can have unknowns on both sides.
\BL
$\2{show}z_{2};\ \2{path}\\{tst},p[],p[]\\{line};\ \2{pair}w[];\
z_{3}=(20,40);$\par
\BL
Variable types such as {\tt path} or {\tt pair} (i.e., point) must be
declared. Other variable types are {\tt boolean, string, pen, picture,
transform}. Variable names consist of three parts: the essential part
is the {\tt tag}, then there may be a numeric subscript which may be
followed by another tag. The
subscript part, which we declare with {\tt []}, enables us to creat
arrays of related variables. The subscript (possibly empty!) together
with any following tag is called the {\tt suffix} of the original tag.

Why didn't the {\tt z3} variable above have to be declared? Well, z is
in fact a macro in \mf\ which converts z\$ into (x\$,y\$) for any
suffix \$. This is convenient since we will be working with points a
lot.
\hb Pens;
$\2{pickup}\5{pencircle}\6{scaled}.4\\{pt};\ \5{cc};\ \2{drawdot}\\{origin};$%
\par
\BL
One has a wide variety of pens available; we want a fine one now.
The dimensions that one gives are converted into pixel units for the
currently defined mode. By default, \mf\ is in `proof' mode which has
36 pixel `dots' per point.  If one wants a `real' point (i.e., one
72.27th of an inch), one uses pt\#. These `sharped' units are
interpreted in a device independent fashion and are usually used
during initial mode/font setup. If no units are
given, the number is interpreted directly as pixel units.
We will discuss mode setup, etc.~later. The units which \mf\ knows
about are the printer's point (pt), pica (pc=12pt), inch
(in=72.27pt), big point (bp=1.00375pt), centimeter (cm=28.45276pt),
millimeter (mm=2.84528pt), didot point (dd=1.07pt), and cicero
(cc=12.8401pt)--note that this last unit isn't available right now
since we have redefined {\tt cc} to be a clearscreen macro. The
printer's point is the basic unit, as you can see if you do a {\tt
show in\#;} command.
\BL
The following code is what I use in my customized version of modes.mf. It
is for writing the screen to a character in order to illustrate this code.
The {\tt charscreen} macro is basically just a {\tt beginchar} without the
default clearings. Don't worry about it for now.
\BL
$\2{picture}\\{picvar};\ \2{numeric}\\{charnr};\ \\{charnr}:=\1{ASCII}(%
\7"A")-1;$\par
\BL
$\2{def}\\{sscreen}(\2{expr}\\{w\_sharp},\\{h\_sharp},\\{d\_sharp},\\{c%
\_scale})=$\par
\quad$\\{picvar}:=\\{currentpicture};$\par
\quad$\\{charscreen}(\2{incr}\\{charnr},\\{w\_sharp},\\{h\_sharp},\\{d%
\_sharp})$\par
\quad\quad$\\{currentpicture}:=\\{currentpicture}\6{scaled}\\{c\_scale};$\par
\quad$\!\3{endchar};$\par
\quad$\\{currentpicture}:=\\{picvar};$\par
$\!\3{enddef};$\par
\BL
$\2{def}\\{charscreen}(\2{expr}c,\\{w\_sharp},\\{h\_sharp},\\{d\_sharp})=$\par
\quad$\2{begingroup}$\par
\quad$\\{charcode}:=\2{if}\1{known}c\?:\1{byte}c\2{else}\?:0\3{fi};$\par
\quad$\\{charwd}:=\\{w\_sharp};\ \\{charht}:=\\{h\_sharp};\ \\{chardp}:=\\{d%
\_sharp};$\par
\quad$w:=\1{hround}(\\{charwd}\ast \\{hppp});\ h:=\1{vround}(\\{charht}\ast %
\\{hppp});$\par
\quad$d:=\1{vround}(\\{chardp}\ast \\{hppp});$\par
\quad$\\{charic}:=0;\ \2{scantokens}\\{extra\_beginchar};$\par
$\!\3{enddef};$\par
\BL
\vfill\eject
\hb Watching loops;
Now to get back to our introduction: \mf\ has various commands that
enable one to repeat similar tasks. For example:
\BL
$\2{for}i=1\4{step}20\4{until}100\?:$\par
\quad$\2{for}j=i\4{step}20\4{until}100\?:$\par
\quad\quad$\2{drawdot}(j,i/2);\ \\{sscreen}(25\\{pt}\SH ,20\\{pt}\SH ,0,1);$\par
\quad$\!\3{endfor};$\par
\quad$\2{draw}(i,i/2)\8{..}(100,i/2);\ \\{sscreen}(25\\{pt}\SH ,20\\{pt}\SH
,0,1);$\par
$\!\3{endfor};$\par
\BL
The above code produces the following figures:
\font\intromf=intromf scaled\magstep4
\vglue -30pt\par{\hfill\intromf A B C D E F}
\par{\hfill\intromf G H I J K}
\par{\hfill\intromf L M N O}
\par{\hfill\intromf P Q R}
\par{\hfill\intromf S T}
\bigskip
Watching the picture as this code executes is more valuable than these
remarks.  In fact, that is one of the reasons I'm using \mf; the
visuals assist one's first encounter with programming.  If you want to
slow things down to look at what happens at each step of the loops,
put {\tt s:=readstring;} between the statements. This just sits and
waits for the enter key to be pressed. Note that a colon (not a ;)
ends the {\tt for} statement conditions.  The inner loop draws a row
of dots whose height and starting x coordinate are controlled by the
outer loop which also draws a line over the dots. Each row of
figures above shows one iteration through the outer loop.
\par \mf's {\tt for}
statement can execute 0 times if the condition is not initially true.
At first, you might think that's pointless; however, it enables one
to program for the general case and
not have to deal specially with certain cases in which the loop
shouldn't execute. For example, we might have a loop: {\tt for
i=curve[k] step -node\_step until limit[k]:} which applies to many
path nodes, and on only some of which do we want the loop to operate.
\BL
$\2{undrawdot}(41,\frac21/{2});\ \\{sscreen}(25\\{pt}\SH ,20\\{pt}\SH ,0,1);$%
\par
$\2{undrawdot}(41,\frac21/{2});\ \\{sscreen}(25\\{pt}\SH ,20\\{pt}\SH ,0,1);$%
\par
\BL
The undrawdot must be done twice, once for the drawdot and once for
the draw which drew a line on top of it.
\smallskip{\hfill\intromf U V}
\bigskip
\BL
Pixels in the current picture have integers associated with them; if
the pixel value is greater than zero, it is blackened. In the process
of drawing, and undrawing, pixel values may be increased or decreased
by more than one. The macro {\tt cullit} will change all negative
values to zero and all positive values to one. If you give the command
{\tt show currentpicture}, the log file will include the current
picture's definition. Note that only the places where pixel values
change are recorded.
\BL
$\5{cc};\ \2{draw}z_{2}\8{..}z_{3};\ z_{4}=.5[z_{3},z_{1}];$\par
\BL
We can draw lines through points and we can specify a point as being a
certain proportion of the way along a line segment ({\tt z2=0[z2,z1]}
and {\tt .99[z2,z1]} is close to z1) by using what is called  the
mediation (or: of-the-way) function.
\hb Declarations;
$z_{5}=\\{whatever}[z_{1},z_{2}];\ z_{4}-z_{5}=\\{whatever}\ast (z_{3}-z_{2});\
\2{draw}z_{4}\8{..}z_{5};$\par
\BL
An anonymous numeric variable, {\tt whatever}, which assumes a
different value with each use, can be used to define properties. The
first equation above says that z5 is on the line defined by z1 and z2
(note that {\tt 2[z1,z2]} is not in the segment {\tt[z1,z2]}). The
second equation specifies that the segment (ie, {\it vector\/}) from
z2 to z3 has the same
direction as the line from z5 to z4 (in \mf, one can't {\it multiply}
unknowns, so one can't use {\tt whatever*(z4-z5)}).
These two equations define the
point z5 so that we can then draw from z4 to z5. This style of
declaring equations which define the properties of what is to be drawn
is typical of \mf.
\bigskip
We've just covered a great deal of material that should be worked on.
If you read a certain piece of code and wonder---``What would $\ldots$
do?''---try it out! We're using \mf\ precisely because it encourages
such experimentation. If your code is invalid, has a {\it bug\/}, no
problem! Just press {\tt $<$enter$>$} until you get the prompt back,
press {\tt h} for help, or if all else fails, press {\tt x} to exit
\mf\ and start again.  If you are reading this on your own, I assume
this isn't your first
programming language so probably only the material in {\it The
METAFONTbook,\/} chapter 13 on
filling need be read now.\footnote{${}^1$}{See Donald Knuth's {\it The
METAFONTbook.\/} }
\hb Editing;
This is perhaps a good time to discuss entering code in
\mf.  As you may have learned by now, one uses the {\tt DEL} key
to erase the previous character when running {\tt mf} in an {\tt
xterm}. The {\tt \^h} character (i.e., the
control-h character) which {\tt
BACKSPACE} inserts confuses \mf. The standard {\tt xterm} cut and
paste operations can be used: use the left mouse button and drag over
a line of \mf\ code (either in the xterm mf window or in, say, emacs),
then move to the {\tt mf} prompt and click the middle mouse button (or
both buttons if you are using three button emulation) to paste the
line. This compensates a bit for \mf\ not having its own editor build
in. An even better solution, described later, is to use an Emacs
shell.

 One might start with {\tt
**$\backslash$screenstrokes; input mymacs;} or even load your macros
into a precompiled base.  If you set {\tt pausing:=1}, \mf\ will pause
after each  line of the input file; in addition, you can insert
statements, for example {\tt show} commands, after the line. {\bf
Pausing} is a very useful feature when writing a program.

Let's get back to our introductory overview to \mf. First, I declare x
and y as numeric arrays so that
later we can redefine {\tt z1}, say. Declarations erase (unbind)
previous values of their variables.
\BL
$\2{numeric}x[],y[];$\par
\hb Curves;
$\2{draw}(0,0)\8{..}(100,10)\8{..}(200,100)\8{..}(150,150);$\par
$\2{undraw}(0,0)\8{..}(100,10)\8{..}(200,100);$\par
$\\{sscreen}(30\\{pt}\SH ,30\\{pt}\SH ,1\\{pt}\SH ,2);$\par
\medskip\centerline{\intromf W}\medskip
\mf\ draws a smooth curve through the points. For now, pretend that
\mf\ takes three
adjacent points and replaces them by the unique circular arc through
them. When there are more than three points on the curve, the
resulting arcs are blended in a smooth fashion, keeping all the points
on the curve. To be more precise: \mf\ uses the control
points (some of which it may compute itself) as knots for cubic
spline approximations where special
attention is paid to minimizing discretization errors. The curvature
of the curve at any point depends on {\it all\/} the control points
in the
curve as the above code illustrates. However, as the knots step away
from a given point, their influence is roughly halved. Parts 18 and 19
of {\it METAFONT: The Program}, should be consulted for the exact
algorithms.
\BL
$\\{npen}:=\\{savepen};$\par
$\2{pickup}\\{penrazor}\6{scaled}2\\{pt};$\par
$\2{draw}(0,0)\8{..}(100,10)\8{..}(200,100)\8{..}(150,150);$\par
$\\{sscreen}(30\\{pt}\SH ,35\\{pt}\SH ,5\\{pt}\SH ,2);$\par
\medskip\centerline{\intromf X}\medskip
If desired, one can save the current pen to a variable (actually just
a reference number) before picking up another.
\BL
$\\{tst}:=(0,0)\8{..}(100,10)\8{--}(200,100)\8{..}(150,150);$\par
$\5{cc};\ \2{draw}\\{tst};$\par
$\2{draw}\\{tst}\8{---}\1{cycle};$\par
$\2{undraw}\\{tst}\8{--}\1{cycle};$\par
$\\{sscreen}(30\\{pt}\SH ,30\\{pt}\SH ,0\\{pt}\SH ,2);$\par
\medskip\centerline{\intromf Y}\medskip
It is convenient to assign curves to variables to save typing. In
actual font production, this isn't done so often.
\BL
When drawing curves, `-{}-' specifies a straight line segment and
`-{}-{}-' specifies a straight segment that smoothly connects at its
ends even though the radius of curvature may be tiny.
\BL
$\5{cc};\ \2{draw}(0,150);$\par
\BL
We can use {\tt
draw} to draw points; however, the special routine {\tt drawdot} is
designed to better cope with the rounding problems related to printing
with raster devices rather than analog devices such as an ink pen.
Of course if the discrete values of a digital device are fine enough,
it will seem continuous. However, \mf\ is designed to have a high
degree of device independence and to make the best of low resolution
devices.
\BL
$\2{pickup}\5{pencircle}\6{scaled}.4\\{pt};$\par
$\\{penpos}_{1}(30,110);\ \\{penpos}_{2}(20,90);\ \\{penpos}_{3}(50,70);$\par
\BL
The first argument to {\tt penpos} is a length and the second is a
direction (in degrees). This specifies the type of pen that we are
using at a given point. Actually, the number suffix to penpos is the
first argument, giving which point the penpos is for. For example,
{\tt penpos1(30,110)} says that at point (x1,y1), pickup
penrazor scaled 30 rotated 110.
\BL
$z_{1}=(50,100);\ z_{2}=(120,80);\ z_{3}=(200,130);$\par
$\5{cc};\ \2{penstroke}z_{1e}\8{..}z_{2e}\8{..}z_{3e};$\par
$\\{sscreen}(40\\{pt}\SH ,20\\{pt}\SH ,-10\\{pt}\SH ,2);$\par
\medskip\rightline{\intromf Z}\par
Once the pens and positions have been
specified, one can fill inside the edges of the resulting stroke with
{\tt penstroke}. This enables \mf\ to simulate broadnibbed pens.
\BL
$\5{cc};\ \2{draw}\1{flex}(z_{1},z_{2},(150,150),z_{3});$\par
$\\{charnr}:=\1{ASCII}(\7"a")-1;\ \\{sscreen}(40\\{pt}\SH ,15\\{pt}\SH ,0\\{pt}%
\SH ,2);$\par
\medskip\rightline{\intromf a}\par
\mf's {\tt plain} base predefines various functions especially for
drawing.  For example,
{\tt flex} takes three or more points where the curve has direction
{\tt z3-z1} (ie, from z1 to z3) at the specified points in the middle.
Speaking of directions, when defining a curve, you can put a direction
specification before or/and after a point. For example, one can
say {\tt draw origin..$\{$(2,1)$\}$(90,90)$\{$dir -30$\}$..(200,0)}.
If there is only one dir for a point,
\mf\ will put the same dir both before and after the point. Any pair
variable can be used to give the direction; the {\tt dir} function takes
a numeric argument which it considers as the number of degrees and
returns a unit vector in that direction. There is also an {\tt angle}
function which takes a point, i.e., a vector, (not necessarily of
length one) and returns its direction in degrees.
\BL
$\2{numeric}\\{ht},\\{wt};$\par
$\5{cc};\ \\{ht}=.7\\{wt};\ \\{wt}=200;$\par
$p_{1}:=\\{fullcircle}\6{xscaled}w\6{yscaled}h\6{shifted}(.5\\{wt},.5\\{ht});$%
\par
$\2{draw}p_{1};$\par
$p_{2}:=(.2\\{wt},.5\\{ht})\{\1{dir}-30\}\8{..}(.8\\{wt},.5\\{ht})\{\1{dir}30%
\};\ \2{draw}p_{2};$\par
\BL
\hb A Donut;
We want to draw a donut (where {\tt w} controls the size) and to
conclude this \mf\ overview with some
of the functions introduced in chapter 14 of Knuth's book.\par
\BL
$\9Various transforms are predefined.\par
$p_{3}:=p_{2}\1{reflectedabout}((0,.5\\{ht}),(100,.5\\{ht}));$\par
$\2{show}\2{directionpoint}\\{right}\2{of}p_{2};$\par
\BL
The numbers that \mf\ prints out in the xterm window tell us where
the curve p2 is horizontal. We use this so we can draw the upper part
of the donut's hole in a way that doesn't explicitly depend on the
dimensions of the donut.
\BL
$s:=\1{ypart}\2{directionpoint}\\{right}\2{of}p_{3}-\1{ypart}\2{directionpoint}%
\\{right}\2{of}p_{2};$\par
$p_{4}:=p_{3}\6{shifted}(0,-2s/5);\ \2{draw}p_{4};$\par
$\\{sscreen}(30\\{pt}\SH ,10\\{pt}\SH ,0\\{pt}\SH ,1);$\par
\medskip\centerline{\intromf b}\medskip
$\2{undraw}p_{4};\ z_{4}=p_{2}\6{intersectionpoint}p_{4};$\par
\BL
We draw p4 just to test out if it is ok. Then we use it to find the
point on p2 where we want the upper curve to start.
\BL
$z_{5}=z_{4}\1{reflectedabout}((.5\\{wt},0),(.5\\{wt},100));$\par
$p_{5}:=(.2\\{wt},.5\\{ht})\{\1{dir}-30\}\8{..}z_{4}\8{..}(.8\\{wt},.5\\{ht})\{%
\1{dir}30\};$\par
\BL
The curve p5 traces the same points as p2, the bottom curve of the
donut's hole. We just added a point to the curve so that we can get
the direction there:
\BL
$z_{6}=\2{direction}1\2{of}p_{5};$\par
\BL
The nodes of a curve are naturally numbered starting with zero;
consider a bug moving along the curve: the above {\tt direction}
macro gives the direction it is traveling at the second control
point. \par We could have gotten the above information in other
ways, of course. For example
{\tt \obeylines
\quad show p2 intersectiontimes p4;
>> (0.1127,0.1127)
\quad show point .1127 of p2;
>> (52.85632,63.56888)
\quad show z4;
>> (52.85632,63.56886)
\quad show direction .1127 of p2;
>> (38.85165,-16.60434)
\quad show direction 1 of p5;
>> (39.15742,-16.69167)
\quad show angle direction 1 of p5;
>> -23.08713
\quad show angle direction .1127 of p2;
>> -23.1408}\par As the above illustrates, due to rounding errors
one can get different answers if the computation is done
differently. Furthermore, the effect of small rounding errors may be
magnified later on.  At any rate, let's draw the top of the donut hole:
\BL
$\2{show}\1{angle}z_{6};$\par
$\2{draw}z_{4}\{\1{dir}-\1{angle}z_{6}\}\8{..}z_{5}\{z_{6}\};$\par
$\\{sscreen}(30\\{pt}\SH ,10\\{pt}\SH ,0\\{pt}\SH ,1);$\par
\BL
\medskip\centerline{\intromf c}\medskip
Usually, we consider {\tt pair} variables as points; however, they
can also
be considered as vectors which give directions, or even as complex
numbers
({\tt z1 zscaled z2} does complex multiplication).

Finally, we draw the upper curve which we have designed so that if
it were reflected across its end points, the resulting curve would
overlay the lower curve of the donut's hole.


As I hope this overview has shown, \mf\ is a high level language well
designed for doing two dimensional black and white glyphs. All
beginning programming concepts can be illustrated via \mf\ code, as
well as more advanced concepts. The following sections present a
through introduction to programming via \mf. But, for now, let's go
get some real donuts! To exit \mf\ enter:
\BL
$\!\3{end}$\par
