% simpsons.mf by Raymond Chen (rjc@math.princeton.edu) 
 
mode_setup; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Parameters (and typical values) 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Pen control 
% 
% u#            the basic unit. 
%               A choice of 1/16in# makes Lisa fit into a 1.5" square. 
% 
% thin#         The pen used for everything, unless otherwise noted. 
%               A value of 1/18u# produces a razor-sharp-ish pen, 
%               good for low resolution work (and which scales nicely). 
%               But a value of 1/9u# produces a slightly thicker line 
%               which might show up better. 
%               And a value of 1/5u# produces a heavy pen, more in keeping 
%               with MG's drawing style. 
% 
% fine#         For fine detail, like the atom logo on the SNPP cooling tower. 
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Physical attributes for everybody 
% 
% tau_top       Curviness of the top part of the little `t' that 
%               forms the ridges inside the ear.  Recommend 45. 
% 
% tau_side      Curviness of the side part of the little `t' that 
%               forms the ridges inside the ear.  Recommend 45. 
% 
% dimple_depth  Amount of curve (in degrees) to give the dimple. 
%               Positive value makes the cheeks puffier. 
%               Negative value makes the dimple deeper. 
%               Recommend -10. 
% 
% innocence#    Size of pupils.  Suggest 0.5u#. 
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Controls for the ladies 
% 
% lace#         The pen used for necklaces.  Recommend = thin#. 
% 
% pearl#        Size of pearls in the necklace.  Set pearl < 0 
%               to suppress the necklace altogether. 
%               Recommend 1.9u#. 
% 
% mascara       Thickness of the eyelashes, relative to thin#. 
%               1.5 means eyelashes are 1.5 times thicker than regular strokes. 
%               Recommend a value of 1.0. 
% 
% seductiveness Curliness of the eyelashes.  In degrees.  Suggest 5. 
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Controls for the kids 
% 
% spikiness     Controls spikiness (tension) of Lisa and Maggie's hair. 
%               Lower numbers make it wavier, 
%               higher numbers make it spikier.  5 seems about right. 
% 
% kemptness#    How uniform the spikes of Bart's hair are. 
%               Higher values make Bart's hair more erratic. 
%               A value of 0 makes them perfectly evenly spaced. 
%               I think 0.05u# looks about right. 
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Controls for Homer 
% 
% starch        How much Homer's collar points flare outwards. 
%               Larger values make Homer's collar stick out more. 
%               In degrees 0..90.  Recommend 30. 
% 
% machismo      How much the front of Homer's shirt opens. 
%               Larger values make it more open.  Degrees 0..90. Recommend 60. 
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Controls for Marge 
% 
% curlers       How large to make the `bumps' the make up Marge's hair. 
%               In degrees.  Suggest 30. 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
u# = 1/80in#; 
%thin# = 1/9 u#;         % heavy lines 
thin# = 1/5 u#;        % realistically heavy 
fine# = 1/9u#; 
 
tau_top := 45; 
tau_side := 45; 
dimple_depth = -10; 
innocence# := .5u#; 
 
lace# = thin#; 
pearl# = 1.9u#; 
mascara = 1.0; 
seductiveness := 7; 
 
spikiness := 5; 
kemptness# := 1/20u#; 
 
starch := 30; 
machismo := 60; 
 
curlers := 30; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Preparing to do business 
 
define_pixels(u, pearl, innocence, kemptness); 
define_whole_blacker_pixels(thin, fine, lace); 
 
pickup pencircle scaled thin; thinpen = savepen; 
pickup pencircle scaled fine; finepen = savepen; 
pickup pencircle scaled (thin * mascara); lashpen = savepen; 
pickup pencircle scaled lace; lacepen = savepen; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Private macros 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
def openit =                            % so screen previewing works better 
    openwindow currentwindow from origin to (screen_rows, screen_cols) 
    at (0, screen_rows-1) enddef; 
 
def :: = ..tension spikiness.. enddef;     % For drawing the kids' spiky hair. 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% preclip     -- clips the path p to start at q. 
% postclip    -- clips the path p to end at r. 
% prepostclip -- clips the path p to start at q and end at r. 
% hardjoin    -- start on p and end on q, transition when they intersect 
 
def preclip(expr p,q)= 
    subpath (xpart(p intersectiontimes q), infinity) of p enddef; 
def postclip(expr p, r) = reverse preclip(reverse p, r) enddef; 
def prepostclip(expr p, q, r) = postclip(preclip(p, q), r) enddef; 
 
secondarydef p hardjoin q = 
    begingroup dz_ := p intersectiontimes q; 
        subpath (0, xpart dz_) of p .. subpath(ypart dz_, infinity) of q 
    endgroup enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Drawing bent lines (i.e., shallowly curved).. Positive theta curves 
% to the left, negative to the right. 
 
vardef bend(expr theta, p, q) = 
    p{(q-p) rotated  theta}.. 
     {(q-p) rotated -theta}q enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Drawing opaquely 
def overdraw expr c = erase fill c; draw c enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Labelling shifted points 
vardef labelsoffset@#(expr offset)(text t) = 
    if proofing > 1: forsuffixes $=t: makelabel@#(str$, z$+offset); endfor 
    fi enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Facial features 
 
def dimplepath(expr p, q) =             % top coordinate first 
    if proofing>1: hide( makelabel("", p); makelabel("", q); ) fi 
%    p{(q-p) rotated  dimple_depth}.. 
%     {(q-p) rotated -dimple_depth}q 
    bend(dimple_depth, p, q) 
enddef; 
 
%   _s__q 
% p/ | 
%    | 
%     \r 
 
def drawtau(expr p, q, r, s) = 
    if proofing>1: makelabel("p", p); makelabel("q", q); 
                   makelabel("r", r); makelabel("s", s); fi 
    c_ := p{(q-p) rotated tau_top}..q; 
    draw c_; 
%    draw postclip( (r{(s-r) rotated tau_side}.. 
%                     {(s-r) rotated -tau_side}s), c_) enddef; 
    draw postclip( bend(tau_side, r, s), c_) enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Eyelashes either bend clockwise or counter-clockwise as they leave 
% the eye. 
% 
% p = starting point, q = ending point, d = delta 
%   d>0 = curves right, d<0 = curves left.  Bigger d means more curve. 
 
def makelash(expr ofs,p,q,d) = 
    if proofing>1: hide( makelabel("", ofs+p); makelabel("", ofs+q); ) fi 
    bend(d*seductiveness, ofs+p, ofs+q) enddef; 
 
% Right lashes clip to the right eye, left lashes to the left eye_ 
vardef rlash@#(expr p,q,d) = 
    lash@# := preclip(makelash( 
                      if known z.eye_right: z.eye_right else:origin fi, p,q,d), 
                      eye_right); 
    draw lash@# enddef; 
vardef llash@#(expr p,q,d) = 
    lash@# := preclip(makelash( 
                      if known z.eye_left: z.eye_left else:origin fi, p, q, d), 
                      eye_left); 
    draw lash@# enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Marge's hair contains little puffs. 
 
def puffhair(text t) =                  % t is a list of pairs 
    hide( n_ := 0; for z=t: z_[incr n_] := z; 
          if proofing>1: makelabel(decimal n_, z); fi endfor) 
    z_1 
        for k = 2 upto n_: 
            {(z_[k] - z_[k-1]) rotated -curlers} .. 
            {(z_[k] - z_[k-1]) rotated  curlers} z_[k] 
        endfor enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Character positions 
 
def simpdochar(expr c, ht, wd, dp, name) = 
    beginchar(c, ht, wd, dp); name enddef; 
 
string current_char_name; 
def pictureof(suffix c)(expr wd, ht, dp) = 
   beginchar(2c, wd, ht, dp); 
    current_char_name := str c; 
    current_char_name & " looking right, no pupils" enddef; 
 
def endpicture = 
    pic_ := currentpicture; 
    endchar; 
 
    beginchar(incr charcode, charwd, charht, chardp); 
    current_char_name & " looking left, no pupils"; 
    currentpicture := pic_ reflectedabout ((.5w, 0), (.5w, h)); 
    endchar; 
    pic_ := nullpicture enddef; 
 
def unreflectedpictureof(suffix c)(expr wd, ht, dp) = 
    beginchar(c, wd, ht, dp); str c enddef; 
 
let unreflectedendpicture = endchar; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Draw grid marks during proofing 
 
def makebox(text rule) = 
    for y = 0 step 4u.o_ until charht*hppp: 
        rule((0, y), (w, y)); 
    endfor 
    rule((0, charht*hppp), (w, charht*hppp)); 
    rule((0, chardp*hppp), (w, chardp*hppp)); 
 
    for x = 0 step 4u until charwd*hppp: 
        rule ((x, -d.o_), (x, h.o_)); 
    endfor 
    rule ((charwd*hppp, -d.o_), (charwd*hppp, h.o_)); 
enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Eye positions 
% 
% Eye positions are stored in the fontdimens. 
 
def eyepos(expr p, a, b, c, d) = fontdimen 4 + 4p: a, b, c, d enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% Local variables 
 
def local(text t, v) = 
    forsuffixes $=v: save v; t v; endfor enddef; 
 
def localpath text v = local(path)(v) enddef; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
Lisa = 1; 
Homer = 2; 
Bart = 3; 
Marge = 4; 
Maggie = 5; 
Burns = 6; 
 
proofing:=2; 
% screenstrokes; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
beginchar(0, 0, innocence#, 0); "A pupil (no width)"; 
    fill fullcircle scaled innocence; 
endchar; 
 
% and character 1 is SNPP. 
input snpp 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% The x-height is 1pt.  The purpose of this is so that pupil positioning 
% can be done in ex-units, which will therefore scale properly if the 
% font is loaded at nonstandard magnifications. 
 
fontdimen 5: 1pt#; 
 
input lisa 
input homer 
input bart 
input marge 
input maggie 
input burns 
end