% The Computer Modern Tengwar family of founts % Punctuation % (a derivation of punct.mf) cmchar "Squiggly dash"; beginchar("-",14u#,x_height#,0); italcorr h#*slant-u#; adjust_fit(0,0); if serifs: numeric theta; theta=angle(1/6(6u-vair),1/4(asc_height-x_height)); pickup crisp.nib; numeric mid_width; mid_width=.4[vair,stem]; pos1(vair,theta+90); pos2(vair,theta+90); pos3(vair,theta+90); pos4(vair,theta+90); z2-z1=z4-z3=(mid_width-crisp)*dir theta; lft x1r=w-rt x4l=hround 1.5u; y4-y1=.15h; .5[y1,y4]=.5h; pair delta; ypart delta=3(y3l-y1l); delta=whatever*dir theta; filldraw z1l..controls(z1l+delta)and(z3l-delta)..z3l..z4l --z4r..controls(z4r-delta)and(z2r+delta)..z2r..z1r--cycle; % stroke else: pickup fine.nib; pos1(vair,180); pos2(vair,90); pos3(.5[vair,slab],90); pos4(vair,90); pos5(vair,180); lft x1r=w-rt x5l=hround 1.5u; x2-x1=x3-x2=x4-x3=x5-x4; y5-y1=y2-y4=.15h; y3=.5[y2,y4]=.5[y1,y5]=.5h; filldraw stroke z1e{up}...z2e{right}..z3e..{right}z4e...{up}z5e; fi % stroke penlabels(1,2,3,4,5); endchar; cmchar "The question mark"; beginchar("?",4.5u#+max(4.5u#,.5stem#+flare#+curve#),fig_height#,desc_depth#); italcorr fig_height#*slant-u#; adjust_fit(serif_fit#,0); pickup tiny.nib; pos1(stem',0); pos2(stem',0); lft x1l=lft x2l=hround(2.5u-.5stem'); bot y1=-d; top y2=h; y4=.5[y5,y3]; penpos3(vair-fine,90); fine.top y3r=x_height+oo; filldraw stroke z1e--z2e; % stem numeric stem_edge,curve'; stem_edge=rt x1r; curve'=hround .5[stem',curve]; pickup fine.nib; pos4(curve',0); pos5(vair,-90); pos2'(stem',180); z2'=z2; x3=.6[x2,x4]; rt x4r=hround(w-u); y5=bar_height; lft x5=min(lft x4l,hround(stem_edge+u)); pos10(if hefty:thin_join else: hair fi,180); rt x10l=max(tiny.lft x1l+rt x10l-lft x10r,1/3[rt x1,edge]); y10=1/8[bar_height,x_height]; filldraw stroke pulled_super_arc.e(10,3)(.5superpull) & pulled_super_arc.e(3,4)(.5superpull) & pulled_super_arc.e(4,5)(.5superpull); % upper bowl pos5'(vair,90); z5'=z5; pos6(curve',0); pos7(vair,-90); rt x6r=hround(w-.5u)+3eps; y6=.5[y5,y7]; bot y7r=-oo; if serifs: pos8(hair,-180) else: pos8(vair,-110) fi; lft x8r=min(hround(stem_edge+.5u+1),lft x8r+x6r-2eps-x8l); x7=.5[lft x8r,x6]; filldraw stroke pulled_super_arc.e(5',6)(.5superpull) & pulled_super_arc.e(6,7)(.5superpull); % lower bowl if serifs: pos9(5/7[vair,flare],-180); y9-(x9-lft x9r)=vround .07x_height; bulb(7,8,9); % bulb sloped_serif.l(2,1,a,1/3,jut,serif_drop); % upper serif dish_serif(1,2,b,1/3,jut,c,1/3,jut); % lower serif else: bot y8r=vround .01h; x8l:=good.x x8l; y8l:=good.y(y8l+.5); filldraw stroke term.e(7,8,left,1,4); fi % terminal penlabels(1,2,3,4,5,6,7,8,9,10); endchar; cmchar "The exclamation mark"; beginchar("!",5u#,fig_height#,0); italcorr fig_height#*slant-.5u#; adjust_fit(0,0); numeric top_thickness,mid_thickness,bot_thickness,upper_side,lower_side,theta; top_thickness=max(fine.breadth,vround(slab-2vair_corr)); bot_thickness=max(fine.breadth,vround(slab-vair_corr)); x0=.5w; y0=.5[y1,y6]; %%% y0=.58h; if hefty: mid_thickness=vround 2/3vair; upper_side=hround(stem-3stem_corr); lower_side=hround min(.5[curve,cap_curve]-stem_corr,upper_side+.25u); penpos1(top_thickness,90); penpos2(upper_side,180); penpos3(mid_thickness,270); penpos8(upper_side,360); penpos4(mid_thickness,90); penpos7(lower_side,180); penpos6(bot_thickness,270); penpos5(lower_side,360); penpos0(vair,90); z3l=z0r; z4l=z0l; w-x1=x6=.4w; x2r=w-x8r=hround u; x7r=w-x5r=hround .75u; top y1r=h+o; y6r=.15h; y2=y8=.5[y1l,y3l]; y7=y5=.5[y4l,y6l]; filldraw stroke pulled_arc.e(1,2) & pulled_arc.e(2,3); % left half of upper bowl filldraw stroke pulled_arc.e(4,5) & pulled_arc.e(5,6); % right half of lower bowl else: pickup fine.nib; theta=90-angle(10u,h); slope=-h/10u; upper_side=max(fine.breadth,hround(.5[hair,stem]-stem_corr)); lower_side=hround(.5[hair,stem]+stem_corr); if lower_side>1.2upper_side: upper_side:=lower_side; fi pos1(top_thickness,-90); pos6(bot_thickness,-90); w-x1=x6=.4w; top y1l=h+o; y6r=.15h; pos0(cap_stem,theta); lft x2l=w-rt x8l=hround 1.25u; lft x7r=w-rt x5r=hround .75u; x2r-x2l=upper_side-fine; x5r-x5l=lower_side-fine; ellipse_set(1l,2l,3l,0l); ellipse_set(1r,2r,3r,0r); ellipse_set(6l,5l,4l,0l); ellipse_set(6r,5r,4r,0r); numeric tau; tau=max(.8,.20710678/(superness-.5)); filldraw stroke z1e..tension atleast tau..z2e{down} ..z3e---z4e..z5e{down}..tension atleast tau..z6e; fi % S stroke penlabels(0,1,2,3,4,5,6,9); endchar; cmchar "Hash mark (number sign)"; if monospace: compute_spread(.6x_height#,.7x_height#); else: compute_spread(.45x_height#,.55x_height#); fi beginchar("#",15u#,asc_height#,asc_depth#); italcorr (math_axis#+.5(spread#+rule_thickness#))*slant-.5u#; adjust_fit(0,0); pickup rule.nib; lft x1=hround u-eps; x3=x1; x2=x4=w-x1; y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis; draw z1--z2; % upper bar draw z3--z4; % lower bar lft x6=hround 3u; rt x7=hround(w-3u); x5-x6=x7-x8; x8=good.x if monospace: .6 else: .5 fi\\w; top y5=top y7=h+eps; bot y6=bot y8=-d-eps; y15=y1; z15=whatever[z5,z6]; y36=y3; z36=whatever[z5,z6]; y27=y2; z27=whatever[z7,z8]; y48=y4; z48=whatever[z7,z8]; draw z5--if x5>x6+1:(good.x(x15+.5),y1)--(good.x(x15-.5),y1) --(good.x(x36+.5),y3)--(good.x(x36-.5),y3)--fi\\z6; % left diagonal draw z7--if x7>x8+1:(good.x(x27+.5),y2)--(good.x(x27-.5),y2) --(good.x(x48+.5),y4)--(good.x(x48-.5),y4)--fi\\z8; % right diagonal labels(1,2,3,4,5,6,7,8,15,27,36,48); endchar; cmchar "Per cent sign"; beginchar("%",9u#+max(6u#,2fudge*(hair#+stem#)), body_height#,body_height#-asc_height#); italcorr if hefty: .4asc_height#*slant-.5u# else: h#*slant-u# fi; adjust_fit(0,0); pickup fine.nib; numeric left_curve,right_curve; left_curve=hround 5/6[fudged.hair,fudged.stem]; right_curve=max(fine.breadth,hround(fudged.hair if hefty:-2stem_corr fi)); pos1(vair,90); pos2(left_curve,180); pos3(vair,270); pos4(right_curve,360); top y1r=h; lft x2r=hround u; rt x4r=hround(.5w-1.5u); bot y3r=floor(if monospace: .7 else: .5 fi\\ asc_height); x1=x3=.5[x2,x4]; y2=y4=.5[y1,y3]; filldraw stroke pulled_super_arc.e(1,2)(superpull) & pulled_super_arc.e(2,3)(superpull); % left half of upper bowl filldraw stroke super_arc.e(3,4) & super_arc.e(4,1); % right half of upper bowl pos5(vair,90); pos6(left_curve,180); pos7(vair,270); pos8(right_curve,360); bot y7r=-d; rt x8r=hround(w-u); lft x6r=hround(.5w+1.5u); top y5r=vround(if monospace: .3 else: .5 fi\\ asc_height); x5=x7=.5[x6,x8]; y6=y8=.5[y5,y7]; filldraw stroke pulled_super_arc.e(5,6)(superpull) & pulled_super_arc.e(6,7)(superpull); % left half of lower bowl filldraw stroke super_arc.e(7,8) & super_arc.e(8,5); % right half of lower bowl pickup rule.nib; top y9=h; bot y10=-d; if hefty: x9=good.x(x5-eps); x10=good.x(x1+eps); draw z9--z10; % diagonal else: rt x9=hround(w-2.5u); lft x10=hround 2.5u; draw z9--z10; % diagonal pickup fine.nib; pos9(rule_thickness,angle(z9-z10)+90); pos11(vair,angle(z1r-z4r)-90); pos12(vair,angle(z9-z10)+90); path p; p=super_arc.r(1,4); z11r=point 2/3 of p; z12r=z9r; filldraw stroke z11e{direction 2/3 of p}...{z9-z10}z12e; fi % link penlabels(1,2,3,4,5,6,7,8,9,10,11,12); endchar; cmchar "Apostrophe"; beginchar("'",5u#,asc_height#,0); italcorr asc_height#*slant+.5dot_size#-2u#; adjust_fit(0,0); x1-.5dot_size=hround(.5w-.5dot_size); y1+.5dot_size=h; if monospace: comma(1,a,dot_size,.28u,vround 1.5comma_depth); % large comma else: comma(1,a,dot_size,.25u,comma_depth); fi % comma with increased jut penlabels(1); endchar; cmchar "Left parenthesis"; beginchar("(",7u# if monospace: -u# fi,body_height#,paren_depth#); italcorr body_height#*slant-.5u#; adjust_fit(0,0); pickup fine.nib; pos1(vair,0); pos2(.75[hair,stem],0); pos3(vair,0); rt x1r=rt x3r=hround(w-u); lft x2l=hround(x1-4u if monospace: +4/3u fi); top y1=h; y2=.5[y1,y3]=math_axis; filldraw stroke z1e{3(x2e-x1e),y2-y1}...z2e ...{3(x3e-x2e),y3-y2}z3e; % arc penlabels(1,2,3); endchar; cmchar "Right parenthesis"; beginchar(")",7u# if monospace: -u# fi,body_height#,paren_depth#); italcorr math_axis#*slant-.5u#; adjust_fit(0,0); pickup fine.nib; pos1(vair,0); pos2(.75[hair,stem],0); pos3(vair,0); lft x1l=lft x3l=hround u; rt x2r=hround(x1+4u if monospace: -4/3u fi); top y1=h; y2=.5[y1,y3]=math_axis; filldraw stroke z1e{3(x2e-x1e),y2-y1}...z2e ...{3(x3e-x2e),y3-y2}z3e; % arc penlabels(1,2,3); endchar; cmchar "Asterisk"; beginchar("*",9u#, if low_asterisk:math_axis#+.5x_height# else: body_height# fi,0); italcorr h#*slant-.75u#; adjust_fit(0,0); numeric ast_flare; ast_flare=hround .7[thin_join,stem]; x0=.5w; y0=h-.5x_height; for d=-150 step 60 until 150: z[d]=z0+.5dir d xscaled 7.5u yscaled x_height; numeric theta; theta=angle(z[d]-z0); fill z0+.5(0,-thin_join)rotated theta ---z[d]+.5(-ast_flare,-ast_flare)rotated theta ..z[d]..z[d]+.5(-ast_flare,ast_flare)rotated theta ---z0+.5(0,thin_join)rotated theta--cycle; endfor % diagonal at angle |d| labels(0,[-150],[-90],[-30],30,90,150); endchar; cmchar "Plus sign"; beginarithchar("+"); pickup rule.nib; x1=x2=good.x .5w; top y1=h+eps; .5[y1,y2]=math_axis; lft x3=hround u-eps; x4=w-x3; y3=y4=math_axis; draw z1--z2; % stem draw z3--z4; % crossbar labels(1,2,3,4); endchar; cmchar "Comma"; numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#; define_whole_blacker_pixels(dot_diam); beginchar(",",5u#,x_height#,0); adjust_fit(0,0); pickup fine.nib; pos1(dot_diam,0); pos2(dot_diam,90); lft x1l=hround(.5w-.5dot_diam); y2=.5h; z1=z2; dot(1,2); % dot penlabels(1,2); endchar; cmchar "Semicolon"; numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#; define_whole_blacker_pixels(dot_diam); beginchar(";",5u#,dot_diam#,0); adjust_fit(0,0); pickup fine.nib; pos1(dot_diam,0); pos2(dot_diam,90); lft x1l=hround(.5w-.5dot_diam); bot y2l=0; z1=z2; dot(1,2); % dot penlabels(1,2); endchar; cmchar "Virgule (slash)"; beginchar("/",9u#,body_height#,paren_depth#); italcorr body_height#*slant-.5u#; adjust_fit(0,0); pickup rule.nib; rt x1=hround(w-u)+eps; top y1=h+eps; lft x2=hround u-eps; bot y2=-d-eps; draw z1--z2; % diagonal penlabels(1,2); endchar; cmchar "Colon"; numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#; define_whole_blacker_pixels(dot_diam); beginchar(":",5u#,x_height#,0); italcorr x_height#*slant+.5dot_diam#-2u#; adjust_fit(0,0); pickup fine.nib; pos1(dot_diam,0); pos2(dot_diam,90); lft x1l=hround(.5w-.5dot_diam); top y2r=h; z1=z2; dot(1,2); % upper dot pos3(dot_diam,0); pos4(dot_diam,90); x3=x1; bot y4l=0; z3=z4; dot(3,4); % lower dot penlabels(1,2,3,4); endchar; cmchar "Full stop"; numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#; define_whole_blacker_pixels(dot_diam); beginchar(".",5u#,x_height#,0); italcorr x_height#*slant+.5dot_diam#-2u#; adjust_fit(0,0); pickup fine.nib; pos1(dot_diam,0); pos2(dot_diam,90); lft x1l=hround(.5w-.5dot_diam); top y2r=h; z1=z2; dot(1,2); % upper dot pos3(dot_diam,0); pos4(dot_diam,90); x3=x1; y4=.5h; z3=z4; dot(3,4); % lower dot pos5(dot_diam,0); pos6(dot_diam,90); x5=x1; bot y6l=0; z5=z6; dot(5,6); % lower dot penlabels(1,2,3,4,5,6); endchar; cmchar "Equals sign"; compute_spread(.45x_height#,.55x_height#); beginchar("=",14u#,v_center(spread#+rule_thickness#)); italcorr h#*slant-.5u#; adjust_fit(0,0); pickup rule.nib; lft x1=hround u-eps; x3=x1; x2=x4=w-x1; y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis; draw z1--z2; % upper bar draw z3--z4; % lower bar labels(1,2,3,4); endchar; cmchar "At sign"; beginchar("@",14u#,asc_height#,0); italcorr .7asc_height#*slant-.5u#; adjust_fit(0,if hefty or monospace:-2u# else: 0 fi); pickup fine.nib; pos0(fudged.hair,0); pos1(vair,90); pos2(fudged.stem,180); pos3(vair,270); pos4(fudged.stem,-180); pos5(fudged.stem,-180); pos6(vair,-90); pos7(fudged.hair,0); pos8(vair,90); pos9(fudged.hair,180); pos10(vair,270); pos11(.5[vair,flare],360); x1=x3=.5[x0,x2]; y0=y2=.5[y1,y3]; x8=x10=.5w; y7=y9=.5[y8,y10]; lft x9r=hround u; x7=w-x9; top y8r=h+oo; bot y10r=-oo; top y1r=vround(.8[y10,y8]+.5vair); bot y3r=vround(.2[y10,y8]-.5vair); x6l=1/3[x5l,x7l]; y6=y3; y11=good.y(.1[y10,y8]-.5); x0=x4=x5; y4=.8[y3,y1]; y5=2/3[y7,y6]; if hefty or monospace: lft x2r=hround(5u-.5fudged.stem); rt x0r=hround(w-3u); x11r=x0r; else: lft x2r=hround 3.4u; x0=w-x2; x11r=x7r; fi filldraw stroke super_arc.e(1,2) & super_arc.e(2,3); % left inner bowl filldraw stroke super_arc.e(3,0) & super_arc.e(0,1); % right inner bowl filldraw stroke super_arc.e(8,9) & super_arc.e(9,10) & term.e(10,11,right,1,4); % left outer bowl and terminal if hefty or monospace: {{interim superness:=hein_super; filldraw stroke super_arc.e(0,8)}}; % link else: (x,y6r)=whatever[z6l,z7l]; x6r:=x; filldraw stroke z4e---z5e...z6e{right}...{up}z7e & super_arc.e(7,8); fi % stem and link penlabels(0,1,2,3,4,5,6,7,8,9,10,11); endchar; cmchar "Left bracket"; numeric wd#; wd#=max(5u#,4.5u#+.5if hefty:stem# else:rule_thickness# fi); beginchar("[",wd#,body_height#,paren_depth#); italcorr body_height#*slant; adjust_fit(0,0); numeric top_thickness,side_thickness; if hefty: top_thickness=vair; side_thickness=max(crisp.breadth,stem-2stem_corr); else: top_thickness=side_thickness=rule_thickness; fi; pickup crisp.nib; pos1(side_thickness,0); pos2(side_thickness,0); top y1=h; bot y2=-d; lft x1l=lft x2l=hround(2.5u-.5side_thickness)-1-eps; filldraw stroke z1e--z2e; % stem pos3(top_thickness,90); pos4(top_thickness,90); pos5(top_thickness,90); pos6(top_thickness,90); x3=x5=x1l; rt x4=rt x6=ceiling(w-.4u)+eps; y3r=y4r=y1; y5l=y6l=y2; filldraw stroke z3e--z4e; % upper bar filldraw stroke z5e--z6e; % lower bar penlabels(1,2,3,4,5,6); endchar; cmchar "Right bracket"; numeric wd#; wd#=max(5u#,4.5u#+.5if hefty:stem# else:rule_thickness# fi); beginchar("]",wd#,body_height#,paren_depth#); italcorr body_height#*slant-2u#+.5if hefty:stem# else:rule_thickness# fi; adjust_fit(0,0); numeric top_thickness,side_thickness; if hefty: top_thickness=vair; side_thickness=max(crisp.breadth,stem-2stem_corr); else: top_thickness=side_thickness=rule_thickness; fi; pickup crisp.nib; pos1(side_thickness,0); pos2(side_thickness,0); top y1=h; bot y2=-d; rt x1r=rt x2r=hround(w-2.5u+.5side_thickness)+1+eps; filldraw stroke z1e--z2e; % stem pos3(top_thickness,90); pos4(top_thickness,90); pos5(top_thickness,90); pos6(top_thickness,90); x3=x5=x1r; lft x4=lft x6=floor .4u-eps; y3r=y4r=y1; y5l=y6l=y2; filldraw stroke z3e--z4e; % upper bar filldraw stroke z5e--z6e; % lower bar penlabels(1,2,3,4,5,6); endchar; cmchar "Reverse apostrophe"; beginchar("`",5u#,asc_height#,0); italcorr asc_height#*slant+.5dot_size#-2u#; adjust_fit(0,0); x1-.5dot_size=hround(.5w-.5dot_size); y1+.5dot_size=h-comma_depth; if monospace: ammoc(1,a,dot_size,.28u,vround 1.5comma_depth); % large ammoc else: ammoc(1,a,dot_size,.25u,comma_depth); fi % normal ammoc penlabels(1); endchar;