% % ``Font Tricks'' borrowed from: % "The ABC's of Special Effects" by Georgia K.M. Tobin % TUGBoat 9 (1988) No 1 pp. 15--18 % "Outline Fonts with Metafont" by Doug Henderson % TUGBoat 10 (1989) No 1 pp. 36--38. % \def\MFF@writetrick#1{\MFF@write{\space\space\space #1}} % main trick subroutine (background + main char + shadow + transform) % z = empty (white), b = black, % v = vertical, h = horizontal, r = slanted(/), l - slanted (\) % d = dotted grig, g = rectangular grid, s - slanted grid % uppercase(*) = (*) + outline % transformations: % "z" - XY symmetry, "x" - symmetry OX, "y" - symmetry OY % "+" - rotate +90, "-" - rotate -90, "=" - rotate 180 \def\MFF@maketrick{% % initialization \if z\MFF@trickshadow\relax \else \MFF@shadowinit \fi \MFF@checktrick{\MFF@trickshadow}{vVhHrRlLdDgGsS}{\MFF@patterninit{SPen}}% \MFF@checktrick{\MFF@trickchar}{vVhHrRlLdDgGsS}{\MFF@patterninit{MPen}}% \MFF@checktrick{\MFF@trickbox}{ZvVhHrRlLdDgGsS}{\MFF@patterninit{HPen}}% \@negargtrue \MFF@checktrick{\MFF@trickchar}{ZBVHRLDGS}{}% \MFF@checktrick{\MFF@trickshadow}{ZBVHRLDGS}{}% \if@negarg\relax \else \MFF@outlineinit \fi % subroutine which repaces endchar \@negargtrue \if z\MFF@trickbox \@negargfalse \fi \MFF@trick@start{TrickChar}% \MFF@boxinit\MFF@trick@dochar{Normal}% \if z\MFF@trickshadow \else \MFF@trick@doshadow{Normal}{Shadow}\fi % make background \@negargtrue \MFF@checktrick{\MFF@trickbox}{zZ}{% \MFF@writetrick{clearit; picture BackChar; BackChar:=currentpicture;}% }% \if@negarg \if z\MFF@trickshadow \MFF@trick@helpdraw{Normal}{Back}{HPen}{\MFF@trickbox}% \else \MFF@trick@helpdraw{ShadowBox}{Back}{HPen}{\MFF@trickbox}% \fi \fi \MFF@checktrick{\MFF@trickbox}{ZBVHRLDGS}{% \MFF@writetrick{clearit; pickup HPen;} \MFF@writetrick{draw (rbXM,rbYM)--(rbXP,rbYM); draw (rbXP,rbYM)--(rbXP,rbYP);} \MFF@writetrick{draw (rbXP,rbYP)--(rbXM,rbYP); draw (rbXM,rbYP)--(rbXM,rbYM);} \MFF@writetrick{cullit; BackChar:=currentpicture + BackChar;} }% % make character \MFF@trick@trickhelp{\MFF@trickchar}{MPen}{Normal}{Main}% % make shadow \MFF@trick@trickhelp{\MFF@trickshadow}{SPen}{Shadow}{SMain}% % combine \MFF@writetrick{clearit; currentpicture:=BackChar+MainChar+SMainChar;}% \MFF@trick@end{TrickChar}% % correct char box % transformation \@negargfalse \@for\@temp:=\MFF@trick@transform\do {\csname MFF@help@transf@\@temp\endcsname}% % final box corrections \if z\MFF@trickbox \if@negarg \MFF@trick@makebox \fi \else \MFF@trick@shiftbox \@negargtrue \fi \if@negarg \MFF@trick@assignbox \fi } \def\MFF@help@transf@rr{\@negargtrue \MFF@trick@transf{FR}% {rotatedaround ((0,0),-90) shifted (0,tmpW)}% {tempI:=tmpW; tmpW:=tmpH; tmpH:=tempI+tmpP; tmpP:=tmpD; tmpD:=0;}% {tmptmp:=tmpwd; tmpwd:=tmpht; tmpht:=tmptmp+tmpwp; tmpwp:=tmpdp; tmpdp:=0pt\MFF@p;}% } \def\MFF@help@transf@rl{\@negargtrue \MFF@trick@transf{FL}% {rotatedaround ((0,0),+90) shifted (tmpH,0)}% {tempI:=tmpH; tmpH:=tmpW; tmpW:=tempI+tmpD; tmpD:=tmpP; tmpP:=0;}% {tmptmp:=tmpht; tmpht:=tmpwd; tmpwd:=tmptmp+tmpdp; tmpdp:=tmpwp; tmpwp:=0pt\MFF@p;}% } \def\MFF@help@transf@ro{\@negargtrue \MFF@trick@transf{FF}% {rotatedaround ((0,0),180) shifted (tmpW,tmpH)}% {tmpH:=tmpH+tmpD; tmpW:=tmpW+tmpP; tmpD:=0; tmpP:=0;}% {tmpht:=tmpht+tmpdp; tmpwd:=tmpwd+tmpwp; tmpdp:=0pt\MFF@p; tmpwp:=0pt\MFF@p;}% } \def\MFF@help@transf@sx{\@negargtrue \MFF@trick@transf{FY}% {reflectedabout ((0,0),(0,100)) shifted (tmpW,0)}% {tmpW:=tmpW+tmpP; tmpP:=0;}% {tmpwd:=tmpwd+tmpwp; tmpwp:=0pt\MFF@p;}% } \def\MFF@help@transf@sy{\@negargtrue \MFF@trick@transf{FX}% {reflectedabout ((0,0),(100,0)) shifted (0,tmpH)}% {tmpH:=tmpH+tmpD; tmpD:=0;}% {tmpht:=tmpht+tmpdp; tmpdp:=0pt\MFF@p;}% } \def\MFF@help@transf@sz{\@negargtrue \MFF@trick@transf{FZ}% {reflectedabout ((0,0),(100,100))}% {tempI:=tmpW; tmpW:=tmpH; tmpH:=tempI; tempI:=tmpP; tmpP:=tmpD; tmpD:=tempI;}% {tmptmp:=tmpwd; tmpwd:=tmpht; tmpht:=tmptmp; tmptmp:=tmpwp; tmpwp:=tmpdp; tmpdp:=tmptmp;}% } \def\MFF@help@transf@st{\@negargtrue \MFF@trick@transf{FT}% {reflectedabout ((0,0),(100,-100)) shifted (tmpH,tmpW)}% {tempI:=tmpW+tmpP; tmpW:=tmpH+tmpD; tmpH:=tempI; tmpP:=0; tmpD:=0;}% {tmptmp:=tmpwd+tmpwp; tmpwd:=tmpht+tmpdp; tmpht:=tmptmp; tmpwp:=0pt\MFF@p; tmpdp:=0pt\MFF@p;}% } % #1 - shift \def\MFF@boxinit{% \MFF@writetrick{if slant>0:} \MFF@writetrick{\space\space\space rbXM:=hround(slant*chardp*hppp);} \MFF@writetrick{\space\space\space rbXP:=hround(slant*charht*hppp);} \MFF@writetrick{else:} \MFF@writetrick{\space\space\space rbXM:=hround((-slant)*charht*hppp);} \MFF@writetrick{\space\space\space rbXP:=hround((-slant)*chardp*hppp);} \MFF@writetrick{fi;} \if@negarg % background=yes \MFF@writetrick{shiftX:=rbXM+curve; rbXM:=0;} \MFF@writetrick{rbXP:=w+curve+rbXP+shiftX+hround(charic*hppp);} \else % background=no \MFF@writetrick{rbXM:=-curve-rbXM; rbXP:=w+curve+rbXP;} \fi \MFF@writetrick{rbYP:=body_height+curve; rbYM:=-body_depth-curve;} \if z\MFF@trickshadow \relax \else \if A\MFF@shadowstyle \MFF@writetrick{rbYM:=rbYM-shadowstepV; rbXP:=rbXP+shadowstepH;} \fi \if B\MFF@shadowstyle \MFF@writetrick{rbYP:=rbYP+shadowstepV; rbXP:=rbXP+shadowstepH;} \fi \if C\MFF@shadowstyle \MFF@writetrick{rbYP:=rbYP+shadowstepV; rbXM:=rbXM-shadowstepH;} \fi \if D\MFF@shadowstyle \MFF@writetrick{rbYM:=rbYM-shadowstepV; rbXM:=rbXM-shadowstepH;} \fi \fi } \def\MFF@outlineinit{\MFF@write{}% \MFF@writetrick{HCntSize\MFF@p:=\MFF@contourstep*hair\MFF@p;} \MFF@writetrick{HCntX:=hround(HCntSize\MFF@p*hppp); if (HCntX<1): HCntX:=1; fi} \MFF@writetrick{HCntY:=vround(HCntSize\MFF@p*hppp); if (HCntY<1): HCntY:=1; fi} } % #1 - pen name (HPen for background, MPen for char, SPen for shadow) \def\MFF@patterninit#1{\MFF@write{}% \MFF@writetrick{#1Size\MFF@p:=\csname MFF@#1pen\endcsname *hair\MFF@p;} \MFF@writetrick{#1X:=hround(#1Size\MFF@p*hppp); if (#1X<1): #1X:=1; fi} \MFF@writetrick{#1Y:=vround(#1Size\MFF@p*hppp); if (#1Y<1): #1Y:=1; fi} \MFF@writetrick{path #1Path;} \MFF@writetrick{#1Path:=(-0.5#1X,-0.5#1Y)--(0.5#1X,-0.5#1Y)} \MFF@writetrick{\space\space\space --(0.5#1X,0.5#1Y)--(-0.5#1X,0.5#1Y)--cycle;} \MFF@writetrick{capsule_def(#1) makepen(#1Path);} \MFF@writetrick{#1Step\MFF@p:=\csname MFF@#1step\endcsname *hair\MFF@p;} \MFF@writetrick{#1StepH:=hround(#1Step\MFF@p*hppp); if (#1StepH<1): #1StepH:=1; fi} \MFF@writetrick{#1StepV:=vround(#1Step\MFF@p*hppp); if (#1StepV<1): #1StepV:=1; fi} } \def\MFF@shadowinit{\MFF@write{}% \def\@tempa{+}\def\@tempb{-}% \@tfor \@temp := \MFF@shadowstyle \do {% \if A\@temp \def\@tempa{+}\def\@tempb{-}\fi \if B\@temp \def\@tempa{+}\def\@tempb{+}\fi \if C\@temp \def\@tempa{-}\def\@tempb{+}\fi \if D\@temp \def\@tempa{-}\def\@tempb{-}\fi }% \MFF@writetrick{shadowstepH:=\@tempa hround(\MFF@shadowstep*hair\MFF@p*hppp);}% \MFF@writetrick{shadowstepV:=\@tempb vround(\MFF@shadowstep*hair\MFF@p*hppp);}% } % \@negarg = shift, #1 = picturename (Normal) \def\MFF@trick@dochar#1{% \MFF@writetrick{cullit; picture #1Char;} \if@negarg % background=yes \MFF@writetrick{#1Char:=currentpicture shifted (shiftX,0);} \else % background=no \MFF@writetrick{#1Char:=currentpicture;} \fi } % #1 - input char name, #2 - output char name \def\MFF@trick@docontour#1#2{% \MFF@writetrick{clearit;} \MFF@writetrick{currentpicture:=#1Char;} \MFF@writetrick{cull currentpicture keeping (1,infinity);} \MFF@writetrick{picture TempPict; TempPict:=currentpicture;} \MFF@writetrick{cull currentpicture keeping (1,1) withweight 3;} \MFF@writetrick{addto currentpicture also TempPict - TempPict shifted (-HCntX,0)} \MFF@writetrick{\space\space\space - TempPict shifted (+HCntX,0) - TempPict shifted (0,-HCntY) - TempPict shifted (0,+HCntY);} \MFF@writetrick{cull currentpicture keeping (1,4);} \MFF@writetrick{picture #2Char; #2Char:=currentpicture;} } % #1 - input char, #2 - output char \def\MFF@trick@doshadow#1#2{% \MFF@writetrick{clearit;} \MFF@writetrick{currentpicture:=#1Char shifted (shadowstepH, shadowstepV);} \MFF@writetrick{picture ShadowPict; ShadowPict:=currentpicture;} \MFF@writetrick{clearit; currentpicture:=ShadowPict-#1Char;} \MFF@writetrick{cullit; picture #2Char; #2Char:=currentpicture;} \MFF@writetrick{clearit; currentpicture:=#1Char+#2Char;} \MFF@writetrick{cullit; picture #2BoxChar; #2BoxChar:=currentpicture;} } % make charactyer or shadow: % #1 = draw subroutine, #2 - pen name, % #3 = input char, #4 - output char \def\MFF@trick@trickhelp#1#2#3#4{% \if z#1 \MFF@writetrick{clearit; picture #4Char; #4Char:=currentpicture;}% \else \if Z#1 \MFF@trick@docontour{#3}{#4}% \else \if b#1 \MFF@writetrick{picture #4Char; #4Char:=#3Char;}% \else \if B#1 \MFF@writetrick{picture #4Char; #4Char:=#3Char;}% \else \MFF@trick@helpdraw{#3}{R#3}{#2}{B}% \MFF@trick@helpdraw{R#3}{#4}{#2}{#1}% \MFF@checktrick{#1}{ZBVHRLDGS}{% \MFF@trick@docontour{#3}{OL#3}% \MFF@writetrick{#4Char:=#4Char + OL#3Char;}% }% \fi\fi\fi\fi } % black background: #1 - pen name (dummy) \def\MFF@trick@do@b#1{\MFF@trick@do@B{#1}} \def\MFF@trick@do@B#1{% \MFF@writetrick{fill (rbXM,rbYM)--(rbXP,rbYM)--(rbXP,rbYP)--(rbXM,rbYP)--cycle;} } % hor line background: #1 - pen name \def\MFF@trick@do@h#1{\MFF@trick@do@H{#1}} \def\MFF@trick@do@H#1{% \MFF@writetrick{for f=rbYM+0.5#1Y step #1StepV until rbYP-0.5#1Y:} \MFF@writetrick{\space\space\space draw (rbXM+0.5#1X,f)--(rbXP-0.5#1X,f);} \MFF@writetrick{endfor;} } % vert line background: #1 - pen name \def\MFF@trick@do@v#1{\MFF@trick@do@V{#1}} \def\MFF@trick@do@V#1{% \MFF@writetrick{for f=rbXM+0.5#1X step #1StepH until rbXP-0.5#1X:} \MFF@writetrick{\space\space\space draw (f,rbYM+0.5#1Y)--(f,rbYP-0.5#1Y);} \MFF@writetrick{endfor;} } % rect grid background: #1 - pen name \def\MFF@trick@do@g#1{\MFF@trick@do@G{#1}} \def\MFF@trick@do@G#1{\MFF@trick@do@H{#1}\MFF@trick@do@V{#1}} % dotted grid background: #1 - pen name \def\MFF@trick@do@d#1{\MFF@trick@do@D{#1}} \def\MFF@trick@do@D#1{% \MFF@writetrick{for f=rbYM+0.5#1Y step #1StepV until rbYP-0.5#1Y:} \MFF@writetrick{\space for g=rbXM+0.5#1X step #1StepH until rbXP-0.5#1X:} \MFF@writetrick{\space\space\space draw (g,f);} \MFF@writetrick{\space endfor;} \MFF@writetrick{endfor;} } % slant (\) background: #1 - pen name \def\MFF@trick@do@r#1{\MFF@trick@do@R{#1}} \def\MFF@trick@do@R#1{% \MFF@writetrick{levelX:=rbXP-rbXM-#1X; levelY:=rbYP-rbYM-#1Y; f:=0;} \MFF@writetrick{forever:} \MFF@writetrick{\space\space\space exitif f>(levelX+levelY);} \MFF@writetrick{\space\space\space if (f(levelX+levelY);} \MFF@writetrick{\space\space\space if (f0:} \MFF@writetrick{\space\space\space tmpwd:=tmpwd+slant*(tmpdp+tmpht);} \MFF@writetrick{else:} \MFF@writetrick{\space\space\space tmpwd:=tmpwd-slant*(tmpdp+tmpht);} \MFF@writetrick{fi;} \MFF@trick@dimen \MFF@write{enddef;} \MFF@write{extra_beginchar := "ABCbeginchar; " & extra_beginchar;} } \def\MFF@trick@makebox{% \MFF@write{} \MFF@write{body_depth\MFF@p:=desc_depth\MFF@p+body_height\MFF@p-asc_height\MFF@p;} \MFF@write{def PQRbeginchar = } \MFF@writetrick{tmpht:=body_height\MFF@p; tmpdp:=body_depth\MFF@p;} \MFF@writetrick{tmpwd:=charwd; tmpic:=charic;} \MFF@writetrick{if slant>0:} \MFF@writetrick{\space\space\space tmpwp:=curve\MFF@p+slant*tmpdp;} \MFF@writetrick{else:} \MFF@writetrick{\space\space\space tmpwp:=curve\MFF@p-slant*tmpht;} \MFF@writetrick{fi;} \MFF@trick@dimen \MFF@write{enddef;} \MFF@write{extra_beginchar := "PQRbeginchar; " & extra_beginchar;} } \def\MFF@trick@assignbox{% \MFF@write{} \MFF@write{def XYZbeginchar = } \MFF@writetrick{charht:=tmpht; chardp:=tmpdp;} \MFF@write{enddef;} \MFF@write{def XYZendchar = } \MFF@writetrick{charwd:=tmpwd; charic:=tmpic;} \MFF@write{enddef;} \MFF@write{extra_beginchar := extra_beginchar & "; XYZbeginchar";} \MFF@write{extra_endchar := extra_endchar & "; XYZendchar";} } %%%%%%% end MFF tricks %%%%%%%%%%%%%%%%%%%