% -*- Fundamental -*- (emacs-20 mf mode mucks % feta-schrift.mf -- implement scripts % % source file of the Feta (defintively not an abbreviation for Font-En-Tja) % music font % % (c) 1997 Han-Wen Nienhuys % Jan Nieuwenhuizen % fet_begingroup("scripts") def draw_fermata = save alpha, radius, crook_thinness, crook_fatness, dot_radius; % [Wanske] and some Baerenreiter editions % suggest ca 80 degrees iso half-circle alpha := 10; radius# = 1.25 staff_space#; crook_thinness# = 1.5stafflinethickness#; crook_fatness# = 4 stafflinethickness#; radius# + crook_fatness#/2 = h#; radius# + crook_thinness#/2 = w#; set_char_box(w#, w#, crook_thinness#/2, h#); define_pixels(radius, crook_thinness, crook_fatness); dot_radius = round (4/6 crook_fatness); penpos1(crook_thinness, 0); penpos2(crook_fatness, -90); z1 = (-radius,0); z2 = (0, radius); fill z1l{dir (-alpha-90)}..{dir (90-alpha)}z1r.. {right}z2r -- z2l{left} .. cycle; addto currentpicture also currentpicture xscaled -1; pickup pencircle scaled 2dot_radius; x4 =0; bot y4 = - crook_thinness/2; drawdot z4; enddef; fet_beginchar("fermata up", "ufermata", "ufermata") draw_fermata; penlabels(1,2,4); fet_endchar; fet_beginchar("fermata down", "dfermata", "dfermata") draw_fermata; y_mirror_char; fet_endchar; % % Thumbs are used in cello music. % TODO : thumbs should look like the finger-font and should be placed in % the same way in the score. % fet_beginchar("Thumb", "thumb", "thumb") save thin, height, width, thick; height# = 5/4 width#; height# = staff_space#; thin = 1.2 stafflinethickness; thick = 2 thin; set_char_box(width#/2, width#/2, height#/2, height#/2); penpos1(thick, 0); penpos2(thin, 90); z1r = (w, 0); z2r = (0, h); penlabels(1,2); penstroke z1e{up} .. {left}z2e; addto currentpicture also currentpicture xscaled -1; addto currentpicture also currentpicture yscaled -1; z3 = (0, -h); z4 = (0, -1.5h); penlabels(3,4); draw_brush(z3,1.4*thin, z4,0.9*thick); fet_endchar; % % FIXME: rounded endings % % `\accent' is TeX reserved. fet_beginchar("> accent", "sforzato", "sforzatoaccent") set_char_box(.9 staff_space#, .9 staff_space#, .5 staff_space#, .5 staff_space#); save thickness, diminish; thickness = 3/2 stafflinethickness; pickup pencircle scaled thickness; % prevent blobs at crossing lines diminish = .75; top y1 = h; lft x1 = -b; rt x2 = w; y2 = .25 thickness* diminish; rt z4 = (w,0); x3 =0; z3 = whatever [z1, z4]; penpos2(thickness*(2 - diminish)/2 , 90); penpos1(thickness, 90); penpos3(thickness, 90); draw z1 .. z3; draw (z1 .. z3) yscaled -1; draw z4; penstroke z3e .. z2e; penstroke (z3e .. z2e) yscaled -1; penlabels(1,2,3); labels(4); fet_endchar; fet_beginchar("staccato dot", "staccato", "staccato") save radius; radius# = 0.20 * staff_space#; define_whole_pixels(radius); pickup pencircle scaled 2 radius; drawdot (0,0); set_char_box(radius#, radius#, radius#, radius#); fet_endchar; def draw_staccatissimo = save radius, height; height# = .8 staff_space#; radius# = 2 stafflinethickness#; define_whole_pixels(radius); define_pixels(height); draw_brush((0,0), stafflinethickness, (0, height),2 radius); set_char_box(radius#,radius#, blot_diameter#/2, height# + radius#); enddef; fet_beginchar("staccatissimo/martellato up", "ustaccatissimo", "ustaccatissimo") draw_staccatissimo; fet_endchar; fet_beginchar("staccatissimo/martellato down", "dstaccatissimo", "dstaccatissimo") draw_staccatissimo; y_mirror_char; fet_endchar; fet_beginchar("portato/single tenuto", "tenuto", "tenuto") save thick; thick# = 1.6 stafflinethickness#; define_whole_pixels(thick); set_char_box(.6 staff_space#, .6 staff_space#, thick#/2,thick#/2); pickup pencircle scaled thick; draw_rounded_block((-b,-thick/2),(w,thick/2),thick); fet_endchar; def draw_portato = save thick, radius; thick# = 1.4 stafflinethickness#; radius# = 1.4 stafflinethickness#; define_whole_pixels(thick,radius); set_char_box(.6 staff_space#, .6 staff_space#, thick#/2,.5 staff_space#+ radius#); draw_rounded_block((-b,-thick/2),(w,thick/2),thick); pickup pencircle scaled 2 radius; drawdot (0,h); enddef; fet_beginchar("portato/tenuto with staccato", "uportato", "uportato") draw_portato; fet_endchar; fet_beginchar("portato/tenuto with staccato", "dportato", "dportato") draw_portato; y_mirror_char fet_endchar; def draw_marcato = save fat_factor, thinness; set_char_box(staff_space#/2, staff_space#/2, 0, 1.1 staff_space#); fat_factor = .3; thinness = stafflinethickness; pickup pencircle scaled thinness; rt x2 = w; lft x5 = -b; bot y5 = 0; top y3 = h; y1 = y2 = y5; x3 =0; z1 - z4 = whatever * (charwd, -charht); z4 = fat_factor [z3, z5]; filldraw z1 -- z2 -- z3 -- z4 -- cycle; draw z3 .. z5; enddef; fet_beginchar("marcato up", "umarcato", "umarcato") draw_marcato; labels(1,2,3,4,5); fet_endchar; % % The down marcato char (not very much used). % Contrary to what some MF/TeX `gurus' believe % it is *point*-symmetric with the "up" version % fet_beginchar("marcato down", "dmarcato", "dmarcato") draw_marcato; xy_mirror_char; fet_endchar; % % used in french horn music todo % % TODO: too light at 20pt fet_beginchar("open (unstopped)", "open", "ouvert") save thin, height, width, thick; height# = 5/4 width#; height# = staff_space#; thin = 1.2 stafflinethickness; thick = 1.4 thin; set_char_box(width#/2, width#/2, height#/2, height#/2); penpos1(thick, 0); penpos2(thin, 90); z1r = (w, 0); z2r = (0, h); penlabels(1,2); penstroke z1e{up} .. {left}z2e; addto currentpicture also currentpicture xscaled -1; addto currentpicture also currentpicture yscaled -1; fet_endchar; fet_beginchar("plus (stopped)", "stopped", "plusstop") save thick, size; thick = 2 stafflinethickness; size# = 1.1 staff_space#; set_char_box(size#/2, size#/2, size#/2, size#/2); draw_rounded_block((-b,-thick/2),(w,thick/2),thick); addto currentpicture also currentpicture rotated 90; fet_endchar; % % A vee with tapered insides to prevent visual blotting % def draw_vee (expr width, height, thickness) = begingroup save diminish; diminish = 0.75; pickup pencircle scaled thickness; x1 = 0; bot y1 = 0; rt x2 = w; top y2 = h; z3 = 0.6 [z2, z1]; penpos3(thickness, 0); penpos4(thickness * diminish, 0); x4r = thickness/2; y4 = thickness/2; labels(1,2); penlabels(3,4); draw z1; draw z3 -- z2; penstroke z3e .. z4e; addto currentpicture also currentpicture xscaled -1; endgroup; enddef; fet_beginchar("Upbow", "upbow", "upbow") save ht, wd, thick, diminish; thick = 1.4 stafflinethickness; wd# = 1.3 staff_space#; ht# = 1.6 wd#; set_char_box(wd#/2, wd#/2, 0, ht#); draw_vee (wd, ht, thick); fet_endchar; fet_beginchar("Downbow", "downbow", "downbow") save stemthick, beamheight; save wd,round; define_pixels(wd) wd# = 1.5 staff_space#; stemthick = 1.2 stafflinethickness; set_char_box(wd#/2, wd#/2, 0, 4/3 staff_space#); beamheight = 4/10 h; draw_rounded_block((-b,h-beamheight),(w,h),blot_diameter); draw_rounded_block((-b,-d),(-b+stemthick,h-stemthick),stemthick); addto currentpicture also currentpicture xscaled -1; fet_endchar; % % Inspired by a computer-set version of Auf dem Strom by Baerenreiter. % def draw_turn = save thin, thick, ball_diam, darkness; save wd, ht, thick_nibangle, ball_nib_thick; save turndir; pair turndir; wd# = 35/16 staff_space#; ht# = 18/17 staff_space#; darkness = 1.20 stafflinethickness; set_char_box(wd#/2, wd#/2, ht#/2, ht#/2); thick_nibangle = 60; thick = 3 darkness; thin = darkness; ball_nib_thick = 2.7 darkness; ball_diam = ball_nib_thick + (h - ball_nib_thick) / 10; x3l = w; y3 = 0; y4l = h; x4 = x2; x2l = w/2; y2l = -d; z1 = (0,0); penpos1(1.1 thick, thick_nibangle); penpos2(thick, thick_nibangle); penpos3(thin, 180); penpos4(ball_nib_thick, -90); path swoosh, ploop; swoosh := z1l{curl 0} .. z2l .. z3l{up} .. {left}z4l -- z4r .. z3r{down} .. z2r{left} ; fill swoosh .. (swoosh scaled -1) .. cycle; x5r = x4; y5r = y4l - ball_diam /2; z6r = z5r; penpos5(1.6 ball_diam/2, 10); penpos6(ball_diam/2, 150); ploop := z4l{left} .. z5l .. z6l -- cycle; fill ploop; fill ploop scaled -1; enddef; fet_beginchar("Reverse turn","reverseturn","reverseturn") draw_turn; currentpicture := currentpicture yscaled -1; penlabels(5,6,7); penlabels(2,3,4); fet_endchar; fet_beginchar("Turn","turn","turn") draw_turn; penlabels(5,6,7); penlabels(1,2,3,4); fet_endchar; % % Inspired by a (by now) PD edition of Durand & C'ie edition of % Saint-Saens' Celloconcerto no. 1 % % FIXME take out hardcoded vars. % FIXME the two loops on the `t' should be smoother (and the left one bigger). % FIXME generic macros for serifs: top of the t and bottom of r % % fet_beginchar("Trill (`tr')","trill","trill") save start_nib_angle, ascender_extra, ex, hair_thick, fatness, slant_angle, slant, t_fatness, r_fatness, kerning, t_overshoot, uitschieter, bulb_size; ; pair slant_vec; ascender_extra# = 1/2 ex#; ascender# = ascender_extra# + ex#; ex# = 1.4 staff_space#; kerning# = .60 ex#; start_nib_angle = 20; bulb_size = 0.70; define_pixels(ex, ascender_extra, ascender, kerning); t_overshoot = 0.03 ex; fatness = 12/40 ex; t_fatness = 0.78 fatness; t_width = 1.9 t_fatness; r_fatness = 0.78 fatness; uitschieter = 0.48 ex; hair_thick = blot_diameter; r_flare = 0.45 r_fatness; r_width = 2 r_fatness + 0.25 kerning; slant = .2; % slant = .0; local_copy(transform)(currenttransform); currenttransform := currenttransform slanted slant shifted (- staff_space, 0) ; y1 = ascender; % try to position in such a way that the center is the visual % center x1l = 0.2 staff_space; x1r - x1l = t_fatness; penpos1(start_nib_wid, start_nib_angle); z2 = (x1, 7/18 ex); penpos2(start_nib_wid, start_nib_angle); z3l = (x2l + 0.5 t_width, - t_overshoot); z4l = (x2l + t_width, 0.23 ex); penpos4(whatever, 200); x4l - x4r = hair_thick; x3r = 0.5 [x4r, x2r]; % 1.7 [x3l, x3r] = x4r; y3r - y3l = 0.6 t_fatness; save t_p, krul_p; path t_p, krul_p, r_p; z5 = (x2l + t_fatness/2, 2/3 ex); % penpos5(hair_thick, ); t_p := z1r{dir (angle(z1l-z1r) + 30)} .. z1l{-dir (angle(z1r-z1l) - 45)} -- z2l {down} .. tension (1 + .5 slant) .. z3l{right} .. z4l{up} -- z4r{down} .. z3r{left} .. tension (1.5 + .7 slant) .. z2r{up} .. z1r -- cycle; fill t_p ; krul_ang = 32; pickup pencircle scaled hair_thick; lft x6 = x2l - uitschieter; y6 = y5 ; % - 1/20 ex; z7 = z5 + whatever*dir krul_ang; up_angle = krul_ang; % angle (z7-z5) x7 = 5/10 kerning + x5; penpos7(hair_thick, up_angle + 90); y9 = 3/4 ex; x9 = x1 + kerning; penpos9(r_fatness, 0); x10 = x9; y10 = -0.3 stafflinethickness; penpos10(r_fatness, 0); krul_p := z4{up} .. tension 0.98 .. z5 .. z6 .. z5 --- z7; draw krul_p; r_p := z7l{z7-z5} .. z9l{down} --- simple_serif (z10l, z10r, -30) --- z9r{up} .. z7r{z5-z7} -- cycle; fill r_p; set_char_box(.85 staff_space# , .85 staff_space#, 0,ascender#); penpos11(1/4 r_fatness, -4); z11r = z9r; z13l = (x9l + r_width, y11 - stafflinethickness ); penpos13(r_flare, 180); z15 = z13r - (bulb_size * r_fatness,0); z14 = 0.5 [z13l, z15] - (0,bulb_size* r_fatness); z16 = 0.5 [z13l, z15] + (0,bulb_size* r_fatness); fill z11r{up} .. tension 0.94 .. z13r{down} -- z15{down} .. tension 1.0 .. z13l{up} .. z11l{down} -- cycle; fill z15{up} .. tension 1.06 .. z13l{down} .. z14 .. cycle; penlabels(range 1 thru 15); fet_endchar; def draw_heel = save radius, thickness, wall; radius# := .5 staff_space#; define_pixels(radius); set_char_box(radius#, radius#, radius#, 2/3 staff_space#); thickness := 1.5 stafflinethickness; pickup pencircle scaled thickness; rt x1 = b; top y1 = h; x2 =x1; y2 = 0; x3 = 0; bot y3 = -d; draw z1{down} .. z2{down} .. z3{left}; addto currentpicture also currentpicture xscaled -1; enddef; fet_beginchar("left heel", "upedalheel", "upedalheel") draw_heel; labels(1,2,3); fet_endchar; fet_beginchar("right heel", "dpedalheel", "dpedalheel") draw_heel; y_mirror_char; fet_endchar; def draw_toe = save ht,wd; thickness := 1.5 stafflinethickness; ht# := 1.5 staff_space#; wd# := 1/3 ht#; define_pixels(ht,wd); set_char_box(wd#, wd#, 0, ht#); draw_vee (wd, ht, thickness); enddef; fet_beginchar("left toe", "upedaltoe", "upedaltoe") draw_toe; labels(1,2,3); fet_endchar; fet_beginchar("right toe", "dpedaltoe", "dpedaltoe") draw_toe; y_mirror_char; fet_endchar; fet_beginchar("Flageolet", "flageolet", "flageolet") save height,width,thickness; height#=4/15 staffsize#; width#=height#; thickness#=blot_diameter#; define_pixels(height,width,thickness); set_char_box(width#/2,width#/2,height#/2,height#/2); pickup pencircle scaled thickness; x1= .5 [x2, x4]; x1 = 0; top y1=height/2; rt x4 - lft x2 =width; y2 = 0; y4=y2; x3=x1; bot y3=-height/2; penlabels(1,2,3,4); draw z1..z2..z3..z4..cycle; fet_endchar; fet_beginchar("Segno", "segno", "segno") save thin, thick, ball_diam, darkness, pointheight; save wd, ht, thick_nibangle, ball_nib_thick; save turndir; pair turndir; ht# = 3 staff_space#; wd# = 2 staff_space#; darkness = 1.20 stafflinethickness; set_char_box(wd#/2, wd#/2, ht#/2, ht#/2); thick_nibangle = 30; thick = 3 darkness; thin = darkness; ball_nib_thick = 2.7 darkness; ball_diam = ball_nib_thick + (w - ball_nib_thick) / 10; pointheight = 2 stafflinethickness; y3l = h; 2 x3 = x2 + x4; x4 = 0; y4 = y2; y2l = .6 h; x2l = -b; z1 = (0,0); penpos1(thick, 2 thick_nibangle); penpos2(thick, thick_nibangle); penpos3(thin, -90); penpos4(ball_nib_thick, 180-thick_nibangle); path swoosh, ploop; swoosh := z1l{curl 0} .. z2l .. z3l{right} .. {down}z4l -- z4r .. z3r{left} .. z2r{down} ; fill swoosh .. (swoosh scaled -1) .. cycle; penlabels(1,2,3,4); y5r = y4; x5r = x4l - ball_diam /2; z6r = z5r; penpos5(1.6 ball_diam/2, 100); penpos6(ball_diam/2, 240); ploop := z4l{down} .. z5l .. z6l -- cycle; fill ploop; fill ploop scaled -1; penlabels(4,5,6); penpos7(2 thin,0); z7l=(-b,-d); penpos8(2 thin,0); z8r=(w,h); filldraw z7l--z8l{right}--z8r{down}--z7r{right}--cycle; pickup pencircle scaled 2 thin; draw (-x2r,pointheight); draw (x2r,-pointheight); fet_endchar; fet_beginchar("Coda", "coda", "coda") save thin, thick, codawidth, codaheight; thin# = 1.2 stafflinethickness#; thick# = 3.5 stafflinethickness#; codawidth# = 2/3 staff_space#; codaheight# = 1 staff_space#; define_pixels(thin, thick, codawidth, codaheight); set_char_box(codawidth#+thick#, codawidth#+thick#, codaheight#+thick#, codaheight#+thick#); penpos1(thick,0); penpos2(thin,-90); penpos3(thick,180); x1l=-codawidth; y2l=codaheight; y1=0; x2=0; z3 = - z1; penlabels(1,2,3); path halfcoda; halfcoda := z1l{up} .. z2l{right} .. z3l{down} -- z3r{up} .. z2r{left} .. z1r{down} .. cycle; fill halfcoda; fill (halfcoda scaled -1); draw_gridline((0,-h),(0,h),thin); draw_gridline((-w,0),(w,0),thin); fet_endchar; def draw_comma = save alpha, thick, thin, ht; alpha:=35; thin# = 1.2 stafflinethickness#; thick# = 3 stafflinethickness#; ht# = .6staff_space#; define_pixels(thin, thick,ht); set_char_box(0, .5staff_space#, ht#, ht#); penpos1(thick, alpha); penpos2(thick, alpha+90); penpos3(thin, 180-alpha); penpos4(thin, 90-alpha); x3r=0; x1l=x3l; y2r=-y4l=h; z1=z2; z3=z4; penlabels(1,2,3,4); fill z1l{dir (alpha+90)} .. z2r{dir alpha} .. z1r{dir (alpha-90)} .. z3l{dir (270-alpha)} .. z4l{dir (alpha+180)} .. z3r{dir (90-alpha)} .. cycle; enddef; fet_beginchar("Right Comma","rcomma","rcomma"); draw_comma; fet_endchar; fet_beginchar("Left Comma","lcomma","lcomma"); draw_comma; xy_mirror_char; fet_endchar; thick#:=1/24designsize; define_blacker_pixels(thick); rthin:=1/8*staff_space; rthick:=2thick+rthin; def draw_arpeggio = save alpha; alpha:=-40; save ne,nw,se,sw; pair ne,nw,se,sw; save x,y; se=dir alpha; nw=dir (alpha+180); ne=dir (alpha+90); sw=dir (alpha-90); penpos1(rthin,alpha+90); penpos2(5/4rthick,alpha); penpos4(5/4rthick,alpha); penpos5(rthin,alpha+90); penpos3(3/4rthick,alpha); z1=(width/2, height) - overshoot*se; z2=2[z4,(width/2,height/2)]; z3=1/2[z2,z4]; x4=2/8staff_space; y4=rthin; z5=2[z1,(width/2,height/2)]; z6=z2l+1/2rthin*sw; z7=z4l+1/2rthin*sw+1/2rthin*se; z8=2[z6,(width/2,height/2)]; z9=2[z7,(width/2,height/2)]; fill z1l{se}..{se}z6..z3l..z7{se}..{se}z5l..z5r{nw}..{nw}z8..z3r..z9{nw}..{nw}z1r.. cycle; penlabels(1,2,3,4,5,6,7,8,9); enddef; fet_beginchar("Arpeggio","arpeggio","arpeggio"); %draw_staff (-2, 2, 0.0); save height, overshoot, width; height# = staff_space#; width# = 0.8height#; overshoot# = 0.25 staff_space#; define_pixels (height,overshoot,width); set_char_box(0, width#, 0, height#); draw_arpeggio; fet_endchar; % Extendable Trill symbol. % Not yet used % Rename me to Trill, rename Trill to Tr? fet_beginchar("Trill-element","trill-element","trillelement"); save height, overshoot; height# = staff_space#; width# = 0.8height#; overshoot# = 0.25 staff_space#; define_pixels (height,overshoot,width); set_char_box(0, height#, 0, width#); draw_arpeggio; currentpicture := currentpicture shifted -(width/2, height/2); currentpicture := currentpicture rotated 90; currentpicture := currentpicture shifted (height/2, width/2); fet_endchar; % % Arpeggio arrow by Chris Jackson % def draw_arpeggio_arrow = save thinness, height, width, overshoot, se, sw, ne, nw, alpha; pair ne, nw, se, sw; height# = staff_space#; width# = 0.8height#; overshoot# = 0.25 staff_space#; define_pixels (height,overshoot,width); set_char_box(0, width#, 0, height#); alpha := -40; nw = dir (alpha+180); sw = dir (alpha-90); se = dir alpha; penpos1(rthin, alpha+90); penpos2(5/4 rthick, alpha); penpos3(5/4 rthick, 0); z1 = (width/2, height) - overshoot*se; % numbering is consistent with the arpeggio symbol z2 = 2[z4,(width/2,height/2)]; z3 = (0.5 width, 0.5 height); z4 = (0.25 staff_space, rthin); z6 = z2l + 1/2rthin*sw; z9 = (width/2, height) + overshoot*se; fill z1l {se}..{se} z6 .. z3l .. z3r.. z9{nw} ..{nw} z1r.. cycle; bot z10 = ( 0.5w, 0 ); lft z11 = (-0.3w, 0.8h); rt z12 = ( 1.3w, 0.8h); pickup pencircle scaled 0.5 rthin; filldraw z3 -- z12 {dir -130} .. {dir -110} z10 {dir 110} .. {dir 130} z11 -- cycle; enddef; fet_beginchar("Arpeggio arrow down", "arpeggio-arrow--1", "arpeggioarrowdown"); draw_arpeggio_arrow; fet_endchar; fet_beginchar("Arpeggio arrow up", "arpeggio-arrow-1", "arpeggioarrowup"); draw_arpeggio_arrow; currentpicture := currentpicture scaled -1 shifted (0.8staff_space, staff_space); fet_endchar; % Hmm input feta-slag; % railroad tracks. % % I actually have no clue how they should look, so we use a slightly curvy % and tapered shape. % fet_beginchar("Caesura", "caesura", "caesura"); save slant, space_between, clearance; save alpha, p; save botthick, topthick; save krom ; path p; botthick = 1.5 stafflinethickness; topthick = 2.5 stafflinethickness; pickup pencircle scaled botthick; slant = 3.5 ; space_between# = 0.6 staff_space#; clearance# = 0.2 staff_space#; height# = 1.2 staff_space#; set_char_box(0, 2.0 staff_space#, staff_space# - clearance#, height#); define_pixels (space_between, clearance, height); bot y1 = -d; top y2 = h; lft x1 = 0; x2 = (y2 - y1) / slant; krom = 10; alpha = angle (z2 - z1); penpos1 (botthick, alpha - krom); penpos3 (botthick, alpha - krom + 90); penpos2 (topthick, alpha + krom ); penpos4 (topthick, alpha + krom + 90); z3 = z1; z4 = z2; penlabels (1,2,3,4); p := z3r{(z1r - z1l)} .. z4r{z2r-z2l} .. z2r{z4l-z4r} .. z4l{z2l-z2r} .. z3l{z1l-z1r} .. z1l{z3r-z3l} .. cycle; fill p; fill p shifted (space_between , 0); fet_endchar; fet_endgroup("scripts");