% glutils.mf: general utilities for use with the gladiator (gl) fonts % Author: Bert Bos pair dirpentilt; dirpentilt=dir pentilt; % PENS uc_xscale#=uc_thick#/cosd pentilt; % Make pens wider if tilted lc_xscale#=lc_thick#/cosd pentilt; % Make pens wider if tilted uc_o_xscale#=uc_thick#/cosd o_pentilt; % Make pens wider if tilted lc_o_xscale#=lc_thick#/cosd o_pentilt; % Make pens wider if tilted define_whole_pixels(uc_xscale, lc_xscale, uc_o_xscale, lc_o_xscale); forever: pickup pencircle xscaled uc_xscale yscaled uc_thin rotated pentilt; ucpen:= savepen; exitunless pen_rt-pen_lft<>uc_thick; if pen_rt-pen_lft>uc_thick: uc_xscale:= uc_xscale-1; elseif pen_rt-pen_lftuc_thick; if pen_rt-pen_lft>uc_thick: uc_o_xscale:= uc_o_xscale-1; elseif pen_rt-pen_lftlc_thick; if pen_rt-pen_lft>lc_thick: lc_o_xscale:= lc_o_xscale-1; elseif pen_rt-pen_lftlc_thick; if pen_rt-pen_lft>lc_thick: lc_xscale:=lc_xscale-1; elseif pen_rt-pen_lft0, else it % points to the left, it will be a bottom serif if ht>0, else it will % be a top serif. The (wd>0, ht>0) serif looks like: % % f a % - *###*# % | ####|## % ht ####|#### % | ####|####### e % - *###*##########* % d c b % |----wd----| % vardef serif@#(expr wd, ht) = save a,b,c,d,e; pair a,b,c,d,e,f; % if ht<0: d=top z@# else: d=bot z@# fi; ypart d=if ht<0: top y@# else: bot y@# fi; xpart d=if wd<0: rt x@# else: lft x@# fi; b=c+(wd,0); a=c+(0,ht); f=(xpart d,ypart a); xpart c=if wd<0: lft x@# else: rt x@# fi; ypart c=ypart d; if ht<0: e=b+fine*down else: e=b+fine*up fi; if known sans: fill a--c--d--f--cycle else: fill a{if ht<0: up else: down fi}..tension tens.. {if wd<0:left else: right fi}e--b--d--f--cycle fi; enddef; % triangle$(wd,X,Y) defines three points, z$l, z$ and z$r, which % constitute the base of the triangle-shaped serif at the top end % of a vertical stem. wd is the width of the stem. % X is the x-coordinate of the left % edge of the stem, Y is the top of the stem. % % Y c # b % ^ ### % | ###### % | a ######### % | d ###### % | l ### r % | :$ : % | : : % -------> X % vardef triangle@#(expr wd,X,Y) = z@#l=(X,Y-triangleht); penpos@#(wd,0); z@#b=(x@#r,Y); z@#c=z@#b+fine*left; % z@#a=(X-trianglewd,Y-triangleht/2+fine/2); z@#a=(X,Y-triangleht/2+fine/2) - trianglewd*dir(seriftilt); z@#d=z@#a+fine*down; if known sans: fill z@#r--z@#b--z@#c--z@#a--z@#l--cycle else: fill z@#r--z@#b--z@#c{dir(angle(z@#a-z@#c)+10)}..tension tens..z@#a-- z@#d{z@#c-z@#a}..{down}z@#l--cycle fi; enddef; % % $l $ $r % a #######*#*#*##### b % f ########### c % ####### % ##### % e ##### d % / % / % / % /alpha % /___________ % vardef diag_tr@#(expr xx, yy, w, alpha) = save a, b, c, d, e, f, ww; pair a, b, c, d, e, f; numeric ww, sw; ww=w/abs(sind alpha); % penpos @#(ww,0); z@#r=(xx,yy); penpos @#(ww,seriftilt); x@#r=xx; y@#=yy; ypart d=yy-serifht; d=e+(ww,0); % b=(xx+serifwd*abs(sind alpha),yy)=a+(2serifwd+ww,0); sw=ww/2+serifwd*abs(sind alpha); b=z@# + sw*serifdir; a=z@# - sw*serifdir; f=a+fine*down; c=b+fine*down; e=z@#l+whatever*dir alpha; % show a, b, c, d, e, f; if known sans: fill z@#l--z@#r--d--e--cycle; else: % fill a--b--c{left}..tension tens..{-dir(alpha)}d--e{dir alpha} % ..tension tens..{left}f--cycle; fill a--b--c{a-b}..tension tens..{-dir(alpha)}d --e{dir alpha}..{a-b}f--cycle; fi enddef; vardef diag_br@#(expr xx, yy, w, alpha) = save a, b, c, d, e, f, ww; pair a, b, c, d, e, f; numeric ww, sw; ww=w/abs(sind alpha); % penpos @#(ww,0); z@#r=(xx,yy); penpos @#(ww,seriftilt); x@#r=xx; y@#=yy; ypart d=yy+serifht; d=e+(ww,0); % b=(xx+serifwd*abs(sind alpha),yy)=a+(2serifwd+ww,0); sw=ww/2+serifwd*abs(sind alpha); b=z@# + sw*serifdir; a=z@# - sw*serifdir; f=a+fine*up; c=b+fine*up; e=z@#l+whatever*dir alpha; if known sans: fill z@#l--z@#r--d--e--cycle; else: % fill a--b--c{left}..tension tens..{dir(alpha-180)}d--e{dir alpha} % ..tension tens..{left}f--cycle; fill a--b--c{-serifdir}..tension tens..{dir(alpha-180)}d--e{dir alpha} ..tension tens..{-serifdir}f--cycle; fi enddef; vardef diag_tl@#(expr xx, yy, w, alpha) = save a, b, c, d, e, f, ww; pair a, b, c, d, e, f; numeric ww, sw; ww=w/abs(sind alpha); % penpos @#(ww,0); z@#l=(xx,yy); penpos @#(ww,seriftilt); x@#l=xx; y@#=yy; ypart d=yy-serifht; d=e+(ww,0); % a=(xx-serifwd*abs(sind alpha),yy)=b-(ww+2serifwd,0); sw=ww/2+serifwd*abs(sind alpha); b=z@# + sw*serifdir; a=z@# - sw*serifdir; f=a+fine*down; c=b+fine*down; d=z@#r+whatever*dir alpha; if known sans: fill z@#l--z@#r--d--e--cycle; else: % fill a--b--c{left}..tension tens..{dir(alpha-180)}d--e{dir alpha} % ..tension tens..{left}f--cycle; fill a--b--c{-serifdir}..tension tens..{dir(alpha-180)}d--e{dir alpha} ..tension tens..{-serifdir}f--cycle; fi enddef; vardef diag_bl@#(expr xx, yy, w, alpha) = save a, b, c, d, e, f, ww; pair a, b, c, d, e, f; numeric ww, sw; ww=w/abs(sind alpha); % penpos @#(ww,0); z@#l=(xx,yy); penpos @#(ww,seriftilt); x@#l=xx; y@#=yy; ypart d=yy+serifht; d=e+(ww,0); % a=(xx-serifwd*abs(sind alpha),yy)=b-(ww+2serifwd,0); sw=ww/2+serifwd*abs(sind alpha); b=z@# + sw*serifdir; a=z@# - sw*serifdir; f=a+fine*up; c=b+fine*up; d=z@#r+whatever*dir alpha; if known sans: fill z@#l--z@#r--d--e--cycle; else: % fill a--b--c{left}..tension tens..{dir(alpha-180)}d--e{dir alpha} % ..tension tens..{left}f--cycle; fill a--b--c{-serifdir}..tension tens..{dir(alpha-180)}d --e{dir alpha}..tension tens..{-serifdir}f--cycle; fi enddef; % Tail for a and d % :: % l z@# r b % ####### ## % ::####### d##### c % ::: ########### % : ####### % ### a % %vardef tail@# = % save a, b, c, d, w; pair a, b, c, d; numeric w; % w=min(u,lc_thick); % xpart c=x@#r+w; % ypart b=serifht; % a=(1/2[x@#l,xpart c],0); % b=c+lc_thin*dir(135); % d=(1/3[x@#r,xpart b],lc_thin); % fill z@#l{down}..a{right}...{dir inclination}c-- % b{dir(inclination-180)}...{left}d...{up}z@#r--cycle; %enddef; % Tail for a, d and u % % ::::::: % l:z@#:r % ####### % ####### % ####### d % ######## % ########## % ############# c % ################## % a b vardef tail@# = save a, b, c, d; pair a, b, c, d; % a=(1/4[x@#l,x@#r],0); b=(x@#r+serifwd,0); a=(1/4[x@#l,x@#r],0); b=a+(3/4(x@#r-x@#l)+serifwd)*serifdir; c=b+fine*up; d=(x@#r,serifht); if known sans: fill a--b--z@#r--z@#l--cycle else: % fill a--b--c{left}..tension tens..{up}d---z@#r--z@#l--cycle fill a--b--c{-serifdir}..tension tens..{up}d---z@#r--z@#l--cycle fi; enddef; % solveangle(wd,X,Y) returns the angle of a stem of width wd with % lower left at (0,0) and upper right at (X,Y). % % a b % Y+--------------+ % | / /| % | / / | % | / / | % | /-_ / | % | /wd -/ | % | / / | % | / / | % | / / | % |/ /alpha | % +--------------+ % 0 X % vardef solve_angle(expr wd,X,Y)= vardef f(expr alpha) = save a,b; pair a,b; b=(X,Y); a=b-(wd/sind alpha,0); alpha