% 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