[comp.text.tex] Making fonts with Metafont -- the answer

dhosek@jarthur.Claremont.EDU (dhosek) (02/28/90)

Getting MF to do what is desired counts as one of the "frequently asked
questions". Here is the infrequently given answer (all you info compilers,
take note):

MF has one important difference from TeX: TeX needs no customization, MF
does. It is difficult, but not impossible to use MF without a working MF
and a customized plain.bas file.

The first thing to do is create a file containing all the mode_def's 
that you'll need. A good basis for this is the file waits.mf which should
be included with your MF distribution. If you can't find a mode_def for
your output device anywhere, listings of settings are published periodically
in TUGboat.

We will, at this point, assume that you have a file called local.mf which
has all the mode_def's that you need in it. The first step will be to
regenerate plain.mf with the following command:

inimf plain input local dump

(if your MF installation does not except command line arguments, type
everything beginning with "plain" at the ** prompt). You should now
have a file plain.bas. This should be moved to the directory containing
the base files on your system. If you are on a multi-user system and 
your system manager hasn't already done this, complain loudly until
it is done.

Now you are ready to use MF. The general syntax of MF is

mf \mode=<mode_name>; mag=<magnification>; input <filename>

where <mode_name> is the name of the mode_def that is relevant,
<magnification> is either a floating point number with 1 indicating
no magnification, 1.2 being 1.2 times magnification (TeX's 
\magnification 1200), etc. or magstep n which generates a font at
the magstep specified (if you are unfamiliar with magsteps, see
the appropriate pasages of the TeXbook and/or MFbook), and <filename>
being the name of the file to generate. Thus, to generate cmr10 at 12pt
for an epson printer you would type

mf \mode=epson; mag=1.2; input cmr10

-----

What if you don't have inimf? First, if you paid for your copy of MF
complain to whoever got your money. They should be shipping that as 
well. Once that is accomplished, you should create a file with the
information in it for the mode_def. Note that the mode_def command
and enddef are _not_ to be included. As an example, here is a 
file ln03.mf which contains a mode_def for the LN03 printer with a
Ricoh LP engine:

% This is ln03.mf as of 2/27/90
% mode_def courtesy of John Sauter
proofing:=0;
fontmaking:=1;
tracingtitles:=0;
pixels_per_inch:=300;
blacker:=0.65;
fillin:=-0.1;
o_correction:=.5;

to use this file, one would, rather than type \mode=<mode_name> on
the MF command, use \smode="ln03"; e.g.,

mf \smode="ln03"; input cmr17

to generate ln03.300gf for an LN03 printer.

-dh
-- 
Important note: The Anti-Social Committee will not be meeting this
                week.
                                   UUCP: uunet!jarthur!dhosek
                               Internet: dhosek@hmcvax.claremont.edu

rusty@garnet.berkeley.edu (rusty wright) (03/01/90)

For those that like to eyeball other people's local.mf here is what I
use.  This has mode def's that have been collected over the ages.
Some of the more recent mode def's (the ones before white_setup) are
from Doug Henderson.  white_setup.mf follows in a separate article.

% It is customary to input another file to supplement the PLAIN base.
% This supplementary file adds analogous modes, corresponding to
% local output devices, and it redefines `localfont' as appropriate.
% The values of screen_rows and screen_cols should also be updated.
% The auxiliary file should set base_version := base_version&"/localname".
% Remember that the present file PLAIN.MF should not be changed;
% all local changes should be confined to a separate file.

% this file can be loaded after PLAIN.MF.
% it introduces conventions that are commonly used at ucb css.
base_version := base_version&"/ucb css";
message "Updating to "&base_name&" version "&base_version&".";

% screen default dimensions for SUN workstations graphic windows
def sun_setup =
    screen_rows := 400;
    screen_cols := 480;
enddef;

% ibm color graphics (640x200)
def ibm_color_graphics_setup =
    screen_rows:=200;
    screen_cols:=640;
enddef;

% ibm enhanced color graphics (640x350)
% ibm enhanced mono graphics (640x350)
def ibm_enhanced_color_graphics_setup =
    screen_rows:=350;
    screen_cols:=640;
enddef;

% hercules graphics card (720x348)
def hercules_setup =
    screen_rows:=348;
    screen_cols:=720;
enddef;

% hp vectra pc (640x400)
% at&t pc-6300 (olivetti m24) (640x400)
% ncr pc6/pc4i (640x400)
% toshiba t3100 (640x400)
def hp_vectra_setup =
    screen_rows:=400;
    screen_cols:=640;
enddef;

% wyse wy-700 (1280x800)
def wyse_wysevenzerozero_setup =
    screen_rows:=800;
    screen_cols:=1280;
enddef;

% mds genius vhr (736x1008)
def mds_genius_vhr_setup =
    screen_rows:=1008;
    screen_cols:=736;
enddef;


% if a mode_def includes the statement:
%	let font_setup = white_setup
% it will replace the cmbase.mf font_setup with this corrected version.
input white_setup               


% what modes exist in this preload?
mode_def help =
    for i=1 upto number_of_modes:
	message mode_name[i];
    endfor; 
    save ?; % only use this once.  it doesn't make sense to repeat
enddef;

let ? = help_;

% Here are conventions for local output devices:

% copying aps mode: for the Linotype Linotronic 100
mode_def linoonezerozero =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% yes, show titles online
    pixels_per_inch := 1270;	% that's roughly 18 per pt
    blacker := .2;		% (this value is conjectural)
    fillin := .2;		% (ditto)
    o_correction := 1;		% (ditto)
enddef;

% copying aps mode: for the Linotype Linotronic 300
mode_def linothree =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 1;		% yes, show titles online
    pixels_per_inch := 2540;	% that's roughly 35 per pt
    blacker := .2;		% (this value is conjectural)
    fillin := .2;			% (ditto)
    o_correction := 1;		% (ditto)
enddef;

% Apple LaserWriter mode (Canon engine)
mode_def laserwriter =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles at all
    pixels_per_inch := 300;	% the new Canon engine at 300/inch
    blacker := 0.3;		% Canon engine isn't black enough
    fillin := 0.15;		% very small compensation for diagonal fillin
    o_correction := .4;		% but don't overshoot as much
enddef;

% sun mode: for the Sun Workstation for proofing
mode_def sun =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles
    pixels_per_inch := 120;	% really lowres
    blacker := 0.65;		% make the pens a bit blacker
    fillin := 0.2;		% compensate for diagonal fillin
    o_correction := 0.4;	% don't overshoot as much
enddef;

% realsun mode: for the Sun Workstation for windows
mode_def realsun =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles
    pixels_per_inch := 82;	% really lowres
    blacker := 0.65;		% make the pens a bit blacker
    fillin := 0.2;		% compensate for diagonal fillin
    o_correction := 0.4;	% don't overshoot as much
enddef;

% epson mode: for printers like the epson fx series
mode_def epson =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 240;	% lowres
    blacker := 0;		% don't make the pens any blacker
    fillin := 0;		% and don't compensate for fillin
    o_correction := 0.2;	% but suppress most overshoots
    aspect_ratio := 9/10;	% 216 dots/inch vertical
    enddef;

% lowest possible resolution recommended
mode_def lowest =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no don't show titles in the log
    pixels_per_inch := 101;	% lowest DEK recommends
    blacker := 0;			% no additional blackness
    fillin := 0;			% no compensation for fillin
    o_correction := 1;		% no reduction in overshoot
enddef;

% graphics mode
mode_def graphics =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 0;		% no, we are not making a font
    tracingtitles := 1;		% yes, show titles in the log
    pixels_per_inch := 1000;
    o_correction := 1;		% no reduction in overshoot
enddef;

% for onscreen viewing of CGA proofs (full screen)
mode_def cgaoneproof =
    proofing := 2;		% yes, we're making full proofs
    fontmaking := 0;		% no, we're not making a font
    tracingtitles := 0;		% no don't show titles online
    pixels_per_inch := 2602;	% make it easy to view one char on screen
    blacker := 0;			% no additional blackness
    fillin := 0;			% no compensation for fillin
    o_correction := 1;		% no reduction in overshoot
    aspect_ratio := 265/640;	% adjust for screen skewing also
enddef;

% for onscreen viewing of CGA proofs (full screen)
mode_def cgaomniproof =
    cgaoneproof_;		% same as cgaoneproof except...
    pixels_per_inch := 1301;	% make it easy to see 3 or 6 chars on screen
enddef;

% for onscreen viewing of CGA smoke proofs (tick marks)
mode_def cgasmoke =
    cgaoneproof_;		% same as cgaproof mode, except:
    proofing := 1;		% yes, we're making unlabeled proofs
    extra_setup := extra_setup&"grayfont black"; % with solid black pixels
    let makebox=maketicks;	% make the boxes less obtrusive
enddef;

% for onscreen viewing of EGA ?test proofs (full screen)
mode_def egaoneproof =
    proofing := 2;		% yes, we're making full proofs
    fontmaking := 0;		% no, we're not making a font
    tracingtitles := 0;		% no don't show titles online
    pixels_per_inch := 2602;	% change to 1300 for use with 3test or 6test
    blacker := 0;		% no additional blackness
    fillin := 0;		% no compensation for fillin
    o_correction := 1;		% no reduction in overshoot
    aspect_ratio := 500/640;	% adjust for screen skewing also
enddef;

% for onscreen viewing of EGA 3test+6test proofs
mode_def egaomniproof =
    egaoneproof_;		% same as egaoneproof mode, except:
    pixels_per_inch := 1301;	% make it easy to view on the screen
enddef;

% for onscreen viewing of EGA smoke proofs (tick marks)
mode_def egasmoke =
    egaoneproof_;		% same as egaoneproof mode, except:
    proofing := 1;		% yes, we're making unlabeled proofs
    extra_setup := extra_setup&"grayfont black"; % with solid black pixels
    let makebox=maketicks;	% make the boxes less obtrusive
enddef;

% for onscreen viewing of HGC proofs (full box)
mode_def hgconeproof =
    proofing := 2;		% yes, we're making full proofs
    fontmaking := 0;		% no, we're not making a font
    tracingtitles := 0;		% no don't show titles online
    pixels_per_inch := 2602;	% make it easy to view one char on screen
    blacker := 0;		% no additional blackness
    fillin := 0;		% no compensation for fillin
    o_correction := 1;		% no reduction in overshoot
    aspect_ratio := 520/720;	% adjust for screen skewing also
enddef;

% for onscreen viewing of HGC proofs (full box)
mode_def hgcomniproof =
    hgconeproof_;		% same as hgconeproof, except...
    pixels_per_inch := 1301;	% make it easy to view 3 or 6 chars on screen
enddef;

% for onscreen viewing of HGC smoke proofs (tick marks)
mode_def hgcsmoke =
    hgconeproof_;		% same as hgconeproof mode, except:
    proofing := 1;		% yes, we're making unlabeled proofs
    extra_setup := extra_setup&"grayfont black";	% with solid black pixels
    let makebox=maketicks;	% make the boxes less obtrusive
enddef;

% previewlow mode: for Textset previewer at lowest resolution
mode_def previewlow =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles
    pixels_per_inch := 80;	% really REALLY lowres
    blacker := 0.65;		% make the pens a bit blacker
    fillin := 0.2;		% compensate for diagonal fillin
    o_correction := 0.4;	% don't overshoot as much
enddef;

% previewmed mode: for Textset previewer at medium resolution
mode_def previewmed =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles
    pixels_per_inch := 118;	% really lowres
    blacker := 0.65;		% make the pens a bit blacker
    fillin := 0.2;		% compensate for diagonal fillin
    o_correction := 0.4;	% don't overshoot as much
enddef;

% previewhigh mode: for Textset previewer at highest resolution
mode_def previewhigh =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles
    pixels_per_inch := 300;	% not so lowres
    blacker := 0.65;		% make the pens a bit blacker
    fillin := 0.2;		% compensate for diagonal fillin
    o_correction := 0.4;	% don't overshoot as much
enddef;

% mode for macintosh (72 dots per inch)
mode_def macintosh =
    pixels_per_inch := 72;	% ultra lowres
    blacker := 0;		% imagewriter is black enough
    o_correction := 0.2;	% don't overshoot too much
    fillin := 0;		% it fills in the diagonals
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles
enddef;

% mode for Imagewriter (144 dots per inch)
mode_def imagewriter =
    pixels_per_inch := 144;	% lowres
    blacker := 0;		% imagewriter is black enough
    o_correction := 0.2;	% don't overshoot too much
    fillin := 0;		% it fills in the diagonals
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles
enddef;

% Ricoh 4080: for the TI Omnilaser (Stan Osborne's values TUGboat 8,2,134)
mode_def RicohFortyEighty =
    let font_setup = white_setup;	% use the write-white font_setup
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles at all
    pixels_per_inch := 300;	% Ricoh write-white engine.
    blacker := 0.2;		% Don't overblack the small fonts
    fillin := -0.2;		% reverse comp. for diagonal fillin
    o_correction := 0.5;	% but don't overshoot as much
enddef;

% imagen mode: for the Imagen 8/300 (Canon engine)
mode_def imagen =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 300;
    blacker := 0;		% Canon engine is black enough
    fillin := 0.2;		% and it tends to fill in diagonals
    o_correction := 0.6;	%
enddef;

% canon mode: for the old Imagen (Canon LBP10)
mode_def canon =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 240;
    blacker := 0.2;		% make pens a wee bit blacker
    fillin := 0.2;		% and compensate for fillin
    o_correction := 0.4;	% but don't overshoot as much
enddef;

% for the QMS (Xerox engine)
mode_def qms =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 300;
    blacker := 0.3;		% (this value not yet tested)
    fillin := 0.2;		% (ditto)
    o_correction := 0.5;	% (ditto)
enddef;

% dover mode: for the Xerox Dover
mode_def dover =
    proofing := 0.0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 384;
    blacker := 1.2;		% make pens somewhat blacker
    fillin := 0.0;		% no compensation for fillin
    o_correction := 0.6;	% but don't overshoot as much
enddef;

% aps mode: for the Autologic APS-Micro5
mode_def aps =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 1;		% yes, show titles online
    pixels_per_inch := 722.909;	% that's roughly 10 per pt
    blacker := 0.2;		% make pens a teeny bit blacker
    fillin := 0.2;		% but compensate for diagonal fillin
    o_correction := 1;		% and keep the full overshoot
enddef;

% crs mode: for the Alphatype CRS
mode_def crs =
     proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 1;		% yes, show titles online
    begingroup
	interim warningcheck := 0;	% (we need to go past 4096)
	pixels_per_inch := 4000+4000/3	% HIGH res
    endgroup;
    blacker := 4.0;		% make pens a lot blacker
    fillin := 0.0;		% but don't compensate for fillin
    o_correction := 1.0;	% and keep the full overshoot
enddef;

% boise mode: for the HP 2680A
mode_def boise =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 180;
    blacker := 0.55;		% make pens a bit blacker
    fillin := 0.1;		% and compensate for diagonal fillin
    o_correction := 0.3;	% but don't overshoot much
enddef;

% DD mode: for the DataDisc (usually with mag=magstep 2=1.44)
mode_def DD =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 70;	% really lowres
    blacker := 0.0;		% don't make the pens any blacker
    fillin := 0.0;		% and don't compensate for fillin
    o_correction := 0.2;	% but suppress most overshoots
enddef;

% newDD mode: for DataDisc with special aspect ratio
mode_def newDD =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 70;	% really lowres
    blacker := 0;			% don't make the pens any blacker
    fillin := 0;			% and don't compensate for fillin
    o_correction := .2;		% but suppress most overshoots
    aspect_ratio := 4/3;		% this is the new feature...
enddef;

% cg mode: for the Compugraphic 8600
mode_def cg =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 1;		% yes, show titles online
    pixels_per_inch := 1301.5;	% a bit less than 20 per pt
    blacker := .2;		% make pens a teeny bit blacker
    fillin := .2;			% but compensate for diagonal fillin
    o_correction := 1;		% and keep the full overshoot
    aspect_ratio := 1569/1301.5;	% strange, no?
enddef;

% corona mode: for the Corona LP-300 (Canon engine)
mode_def corona =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are not making a font
    tracingtitles := 0;		% no titles in the log
    pixels_per_inch := 300;
    blacker := .3;		% (this value is conjectural)
    fillin := .2;			% (ditto)
    o_correction := .6;		% (ditto)
enddef;

% varityper mode: for the VT-600 version 42.5
mode_def varityper =
    proofing := 0;		% no, we're not making proofs
    fontmaking := 1;		% yes, we are making a font
    tracingtitles := 0;		% no, don't show titles in the log
    pixels_per_inch := 600;
    blacker := 0;			% (this value is conjectural)
    fillin := .2;			% (ditto)
    o_correction := .6;		% (ditto)
enddef;

% default ucb wssg output device
localfont := laserwriter;

% Macros to add mode information specials to fonts.

def mode_special(suffix $) =
    string s, d;
    s := str$;
    d := decimal scantokens s;
    special s&" := "&d&";"
enddef;

def font_mode_specials =
    p_p_i = pixels_per_inch/mag;
    if fontmaking > 0:
	begingroup;
	save d, s, p;
	save pixels_per_inch;
	string p;
	pixels_per_inch := p_p_i;
	special jobname;
	mode_special(mag);
	p := substring(0,length(mode_name[mode])-1) of mode_name[mode];
	special "mode := "&p&";";
	mode_special(pixels_per_inch);
	mode_special(blacker);
	mode_special(fillin);
	mode_special(o_correction);
	endgroup;
    fi
enddef;

inner end;
def bye =
    if fontmaking > 0:
	font_mode_specials;
    fi
    end
enddef;

outer bye, end;

% Finally, here are macros for Xerox-world font info:

% string s names the font family, e.g., "CMR"
def font_family expr s =
    headerbyte 49: BCPL_string(s, 20);
    special "identifier "&s 
enddef;

% string s names the scheme, e.g. "TEX TEXT"
def coding_scheme expr s =
    headerbyte 9: BCPL_string(s, 40);
    special "codingscheme "&s
enddef;
%
% integer x gives the family member number,
def font_face_byte expr x =
    headerbyte 72: x;	% which should be between 0 and 255
    special "fontfacebyte";
    numspecial x
enddef;

% string s becomes an n-byte BCPL string
def BCPL_string(expr s, n) =
    for l := if length(s) >= n : n-1 else: length(s) fi: l
	for k := 1 upto l: , substring (k-1, k) of s
	endfor
	for k := l+2 upto n: , 0
	endfor
    endfor
enddef;
--

--------------------------------------
	rusty c. wright
	rusty@violet.berkeley.edu ucbvax!violet!rusty

rusty@garnet.berkeley.edu (rusty wright) (03/01/90)

Here is white_setup.mf.

% The basic correction for write-white fonts occurs in the definition
%	font_setup.  This can be used to overwrite the write-black
% 	definition in cmbase.mf
%
def white_setup =
 if monospace: let adjust_fit=mono_adjust_fit;
  def mfudged=fudged enddef;
  mono_charic#:=body_height#*slant;
  if mono_charic#<0: mono_charic#:=0; fi
  mono_charwd#:=9u#; define_whole_pixels(mono_charwd);
 else: let adjust_fit=normal_adjust_fit;
  def mfudged= enddef; fi
 if math_fitting: let math_fit=do_math_fit
 else: let math_fit=ignore_math_fit fi;
 define_pixels(u,width_adj,serif_fit,cap_serif_fit,jut,cap_jut,beak,
  bar_height,dish,bracket,beak_jut,stem_corr,vair_corr,apex_corr);
 define_blacker_pixels(notch_cut,cap_notch_cut);
 forsuffixes $=notch_cut,cap_notch_cut: if $<3: $:=3; fi endfor
 define_whole_pixels(letter_fit,fine,crisp,tiny);
 define_whole_vertical_pixels(body_height,asc_height,
  cap_height,fig_height,x_height,comma_depth,desc_depth,serif_drop);
 define_whole_blacker_pixels(thin_join,hair,stem,curve,flare,
  dot_size,cap_hair,cap_stem,cap_curve);
 define_whole_vertical_blacker_pixels(vair,bar,slab,cap_bar,cap_band);
 define_corrected_pixels(o,apex_o);
 forsuffixes $=hair,stem,cap_stem:
  fudged$.#:=fudge*$.#; fudged$:=hround(fudged$.#*hppp+blacker);
  forever: exitif fudged$>.9fudge*$; fudged$:=fudged$+1; endfor endfor
 rule_thickness:=ceiling(rule_thickness#*hppp);
 heavy_rule_thickness:=ceiling(3rule_thickness#*hppp);
 oo:=vround(.5o#*hppp*o_correction)+eps;
 apex_oo:=vround(.5apex_o#*hppp*o_correction)+eps;
 lowres_fix(stem,curve,flare) 1.3;
 lowres_fix(stem,curve) 1.2;
 lowres_fix(cap_stem,cap_curve) 1.2;
 lowres_fix(hair,cap_hair) 1.2;
 lowres_fix(cap_band,cap_bar,bar,slab) 1.2;
 stem':=hround(stem-stem_corr); cap_stem':=hround(cap_stem-stem_corr);
 vair':=vround(vair+vair_corr);
 vstem:=vround .8[vair,stem]; cap_vstem:=vround .8[vair,cap_stem];
 ess:=(ess#/stem#)*stem; cap_ess:=(cap_ess#/cap_stem#)*cap_stem;
 dw:=(curve#-stem#)*hppp; bold:=curve#*hppp+blacker;
 dh#:=.6designsize;
 stem_shift#:=if serifs: 2stem_corr# else: 0 fi;
 more_super:=max(superness,sqrt .77superness);
 hein_super:=max(superness,sqrt .81225258superness); % that's $2^{-.3}$
 clear_pen_memory;
 if fine=0: fine:=1; fi
 forsuffixes $=fine,crisp,tiny:
%%% fine $ %%%% temporary formatting convention for MFT
  if $>fudged.hair: $:=fudged.hair; fi
  $.breadth:=$;
  pickup if $=0: nullpen else: pencircle scaled $; $:=$-eps fi;
  $.nib:=savepen; breadth_[$.nib]:=$;
  forsuffixes $$=lft,rt,top,bot: shiftdef($.$$,$$ 0); endfor endfor
%%% @ $ %%%% restore ordinary formatting for $
 min_Vround:=max(fine.breadth,crisp.breadth,tiny.breadth,2); % "WRITE WHITE" ONLY!
 if min_Vround<vround min_Vround: min_Vround:=vround min_Vround; fi
 if flare<vround flare: flare:=vround flare; fi
 forsuffixes $=vair,bar,slab,cap_bar,cap_band,vair',vstem,cap_vstem,bold:
  if $<min_Vround: $:=min_Vround; fi endfor
 pickup pencircle scaled rule_thickness; rule.nib:=savepen;
 math_axis:=good.y(math_axis#*hppp);
 pickup pencircle scaled if hefty:(.6[vair,fudged.hair]) else:fudged.hair fi;
 light_rule.nib:=savepen;
 pickup pencircle xscaled cap_curve yscaled cap_hair rotated 30;
 cal.nib:=savepen;
 pair cal.extension; cal.extension:=(.75cap_curve,0) rotated 30;
 pickup pencircle xscaled cap_curve yscaled cap_hair rotated 70;
 tilted.nib:=savepen;
 pickup pencircle xscaled curve yscaled cap_hair rotated 70;
 med_tilted.nib:=savepen;
 pickup pencircle xscaled cap_stem yscaled cap_hair rotated 30;
 med_cal.nib:=savepen;
 pickup pencircle xscaled stem yscaled cap_hair rotated 30;
 light_cal.nib:=savepen;
 pickup pencircle xscaled(cap_curve+dw) yscaled cap_hair rotated 30;
 heavy_cal.nib:=savepen;
 bot_flourish_line:=-.5u-o;
 pair bend; bend=(.5u,0);
 pair flourish_change; flourish_change=(4u,.2asc_height);
 join_radius:=u;
 currenttransform:=identity slanted slant
  yscaled aspect_ratio scaled granularity;
 if currenttransform=identity: let t_=relax
 else: def t_ = transformed currenttransform enddef fi;
 numeric paren_depth#; .5[body_height#,-paren_depth#]=math_axis#;
 numeric asc_depth#; .5[asc_height#,-asc_depth#]=math_axis#;
 body_depth:=desc_depth+body_height-asc_height;
 shrink_fit:=1+hround(2letter_fit#*hppp)-2letter_fit;
 if not string mode: if mode<=smoke: shrink_fit:=0; fi fi
forsuffixes $=thin_join,hair,curve,flare,dot_size,cap_hair,cap_curve,
 vair,bar,slab,cap_bar,cap_band,stem',cap_stem',vair',fudged.hair,
 fudged.stem,fudged.cap_stem: $:=max($,2); endfor % "WRITE WHITE" ONLY!
 enddef;

--

--------------------------------------
	rusty c. wright
	rusty@violet.berkeley.edu ucbvax!violet!rusty