% -*-Fundamental-*- % feta-bolletjes.mf -- implement noteheads % % source file of LilyPond's pretty-but-neat music font % % (c) 1997--2001 Jan Nieuwenhuizen % & Han-Wen Nienhuys % % most beautiful noteheads are pronounced, not circular, % and not even symmetric. % These examples are inspired by [Wanske], see literature list save black_notehead_width; numeric black_notehead_width; fet_begingroup("noteheads"); noteheight#:=staff_space#+ (1 + overdone_heads) *stafflinethickness#; define_pixels(noteheight); %%%%%%%% % % % % MENSURAL NOTATION % % % brevis_wid# := 2 staff_space#; def draw_brevis(expr brevwid) = save beamheight, head_width; save holeheight, stem_width; save serif_size, serif_protrude; head_width# = brevwid; holeheight = 3 stafflinethickness; stem_width = 1.4 stafflinethickness; define_pixels(head_width); set_char_box(0, head_width#, noteheight#/2, noteheight#/2); 2 beamheight + holeheight = noteheight; serif_size = (holeheight - stafflinethickness)/2; serif_protrude = 1.5 serif_size; penpos1(stem_width, 0); penpos2(stem_width, 0); penpos3(beamheight, 90); penpos4(beamheight, 90); penpos5(stem_width, 180); z1l = (0, 0); z2l = (0, -stafflinethickness/2); z3r = z2r + serif_size *(1,-1); y4r = y3r; x4r = head_width/2; z5l = z3l + (-serif_size, -serif_protrude); penlabels(1,2,3,4, 5); fill z1r -- z1l -- z5r{down} .. z5l{up} .. z3l{right} -- z4l -- z4r -- z3r{left} .. z2r{up} -- cycle; addto currentpicture also currentpicture yscaled -1; show z4r; show z4l; addto currentpicture also currentpicture shifted (-x4r,0) xscaled -1 shifted (x4l,0); enddef; % % Some sources (eg Musix/OpusTeX think that the appendage should be on % the left, some say right. Right wins democratically. % def draw_longa (expr wid) = draw_brevis(wid); save theta; x7r = head_width; y7 = y5; % z7 = z5; z6 - z7 = (stem_width/2, -staff_space); theta = angle(z6-z7)+ 90; penpos7(stem_width, theta); penpos6(1.2 stem_width, theta); fill z7r .. z6r{z6-z7} .. {z7-z6} z6l -- z7l -- cycle; penlabels(6,7); enddef; % % En wij presenteren U: de opvolgster van Emily % % (ze is wel breed) % fet_beginchar("Maxima notehead", "-3mensural", "mensuralmaximahead"); draw_longa (1.3 brevis_wid#) fet_endchar; fet_beginchar("Longa notehead", "-2mensural", "mensurallongahead"); draw_longa (brevis_wid#) fet_endchar; fet_beginchar("Brevis notehead", "-1mensural", "mensuralbrevishead") draw_brevis(brevis_wid#); fet_endchar; def draw_mensural_black_head (expr wid) = save head_width; head_width# = wid; set_char_box (0, head_width#, noteheight#/2, noteheight#/2); y3 = y1 =0; x2 = x4 = (x1 + x3) /2; define_pixels (head_width); pickup pencircle scaled blot_diameter; top y2 = h; bot y4 = -d; lft x1 = 0; rt x3 = w; filldraw z1 -- z2 -- z3 -- z4 -- cycle; enddef; def draw_mensural_open_head (expr wid)= draw_mensural_black_head (wid); save diamNW, diamSW; diamNW = length (z2 - z1) + blot_diameter; diamSW = length (z4 - z1) + blot_diameter; save hole_widthNW, hole_widthSW; hole_widthNW = 0.34 diamNW ; hole_widthSW + 2.6 stafflinethickness = diamSW; (z7 + z5)/2 = (w/2, 0); (z8 + z6)/2 = (w/2, 0); (z6 - z5) = hole_widthNW * unitvector (z2 - z1); (z7 - z6) = hole_widthSW * unitvector (z4 - z1); labels (1,2,3,4,5,6,7,8); unfill z5 -- z6 -- z7 -- z8 --cycle; enddef; fet_beginchar("Mensural open head","0mensural","mensuralminimhead") draw_mensural_open_head (staff_space#); fet_endchar; fet_beginchar("Mensural open head","1mensural","mensuralsemiminimhead") draw_mensural_open_head (staff_space#); fet_endchar; fet_beginchar("Mensural black head","2mensural","fusahead") draw_mensural_black_head (staff_space#); fet_endchar; %%%%%%%%%%%% % % % ledger (leger) lines % fet_beginchar("Ledger ending", "ledgerending", "ledgerending") set_char_box (5/2 ledgerlinethickness#, 5/2 ledgerlinethickness#, ledgerlinethickness#/2,ledgerlinethickness#/2); pickup pencircle scaled 1.3 blot_diameter; rt x2 = w; lft x1 = -b; x3 = x2; bot y1 = -d; y2 = y1; top y3 = h; y4 = y3; x4 = x1; filldraw z1 --- z2 --- z3 --- z4 --- cycle ; fet_endchar; %%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % TODO: Document these! % setup user vars def setup_notehead_vars = save a_b,err_y_a,tilt,superness; save ai_a,ai_bi,err_y_ai,err_x_bi,inner_tilt,inner_superness; save b_h,a_w; enddef; % setup addititional vars and calc them def notehead_calc = save a,beta,ai,bi, ht, wd; ht# =noteheight#; 2beta#=ht#*b_h; a# = beta#*a_b; wd# = 2a# / a_w; ai# = a# * ai_a; bi# = ai#/ai_bi; define_pixels(a,beta); define_pixels(ai,bi); set_char_box(0, wd#, .5 ht#, .5 ht#); enddef; % draw the outer and inner ellipse. def notehead_draw = path black,white; black=distorted_ellipse(a,beta,a*err_y_a,0,superness); white=distorted_ellipse(ai,bi,ai*err_y_ai,bi*err_x_bi,inner_superness); if test>1: %fixme save x; x1=-x3=a; x2=x4=0; y1=y3=0; y2=-y4=b; penlabels(1,2,3,4); test_grid; else: black:=black rotated tilt; black:=black shifted (w/2,0); white:=white rotated inner_tilt; white:=white shifted (w/2,0); fi fill black; unfill white; enddef; def draw_whole_head = setup_notehead_vars; a_b:=1.80; err_y_a:=0; % no slant tilt:=0; superness:=0.707; ai_a:=0.508; % ai_bi:=1.23; ai_bi:=1.30; % jcn % err_y_ai:=0.0938; % err_x_bi:=0; err_y_ai:=0; err_x_bi:=0.115; % inner_tilt:=135; inner_tilt:=125; % jcn % inner_superness:=0.69; inner_superness:=0.68; % jcn b_h:=1; %no rotate-> no height correction a_w:=1; % no rotate-> no width correction notehead_calc; whole_notehead_width# := wd#; notehead_draw; enddef; % % dimensions aren't entirely right. % fet_beginchar ("Brevis notehead", "-1", "brevishead"); save stemthick, fudge; define_pixels (stemthick); fudge = blot_diameter /2; stemthick# = 2 stafflinethickness#; draw_whole_head; pickup pencircle scaled stemthick; bot y1 = -d; top y2 = h; rt x1 - fudge = 0; x1 = x2; fudge + lft x3 = w; x4 = x3; y4 = y2; y3 = y1; draw z1 -- z2; draw z3 -- z4; fet_endchar; % whole note % Wanske, p.38 fet_beginchar("Whole notehead", "0", "wholehead") draw_whole_head; fet_endchar; % half note % Wanske, p.39 fet_beginchar("Half notehead", "1", "halfhead") setup_notehead_vars; % a_b:=1.49; % after text a_b:=1.50; % after drawing err_y_a:=0.157; tilt:=34; % superness:=0.66; superness:=0.67; % jcn % ai_a:=0.863; ai_a:=0.850; % jcn % ai_bi:=3.14; ai_bi:=3.30; % jcn err_y_ai:=0; err_x_bi:=-0.12; inner_tilt:=tilt; inner_superness:=0.80; b_h:=0.935; a_w:=1.12; notehead_calc; half_notehead_width# := wd#; notehead_draw; fet_endchar; % quarter note % Wanske p.38 fet_beginchar("Quart notehead", "2", "quarthead") setup_notehead_vars; % a_b:=1.57; % after text a_b:=1.54; % after drawing err_y_a:=0.044; tilt:=32; superness:=0.707; ai_a:=0; ai_bi:=1; err_y_ai:=0; err_x_bi:=0; inner_tilt:=0; inner_superness:=0.707; b_h:=0.85; a_w:=1.09; notehead_calc; black_notehead_width# := wd#; notehead_draw; fet_endchar; % whole note % Wanske, p.38 fet_beginchar("Whole diamondhead", "0diamond", "wholediamondhead") setup_notehead_vars; a_b:=1.80; err_y_a:=0; % no slant tilt:=0; superness:=0.495; ai_a:=0.350; % ai_bi:=1.23; ai_bi:=1.30; % jcn % err_y_ai:=0.0938; % err_x_bi:=0; err_y_ai:=0; err_x_bi:=0.115; % inner_tilt:=135; inner_tilt:=125; % jcn % inner_superness:=0.69; inner_superness:=0.6; % jcn b_h:=1; %no rotate-> no height correction a_w:=1; % no rotate-> no width correction notehead_calc; whole_notehead_width# := wd#; notehead_draw; fet_endchar; % half note % Wanske, p.39 fet_beginchar("Half diamondhead", "1diamond", "halfdiamondhead") setup_notehead_vars; a_b := 1.50; % after drawing err_y_a:=0.157; tilt:=34; superness:=0.49; % jcn ai_a:=0.550; % jcn ai_bi:=3.30; % jcn err_y_ai:=0; err_x_bi:=-0.12; inner_tilt:=tilt; inner_superness:=0.80; b_h:= 1.03; a_w:= 1.2; notehead_calc; half_notehead_width# := wd#; notehead_draw; fet_endchar; % quarter note % Wanske p.38 fet_beginchar("Quart diamondhead", "2diamond", "diamondhead") set_char_box(0, black_notehead_width#, noteheight#/2, noteheight#/2); save a_b,err_y_a,tilt,superness; save b_h,a_w; save a,beta,ai,bi, ht, wd; a_b:= 1.8; err_y_a:=-0.044; b_h:=0.90; a_w:=1.1; tilt:=35; superness:=0.495; ht# =noteheight#; 2beta#=ht#*b_h; a# = beta#*a_b; define_pixels(a,beta); black := distorted_ellipse(.72 noteheight, .45 noteheight, -.2 noteheight , 0, superness) % beta,a*err_y_a,0,superness); black:=black rotated tilt; black:=black shifted (w/2,0); fill black; fet_endchar; save triangle; path triangle; triangle = (-sqrt3/4,-1/2) -- (0,1) -- (sqrt3/4,-1/2) -- cycle; fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead") set_char_box(0, 2(noteheight#+stafflinethickness#)/sqrt3*7/8, (noteheight#+stafflinethickness#)/2,(noteheight#+stafflinethickness#)/2); fill triangle scaled (7h/6) shifted (w/2,-h/6); unfill triangle scaled 0.72h shifted (w/2,-h/6); fet_endchar; fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead") thick := 1.2stafflinethickness; set_char_box(0, 2noteheight#/sqrt3*7/8,noteheight#/2,noteheight#/2); fill triangle scaled (7h/6) shifted (w/2,-h/6); unfill triangle scaled 0.7h shifted (w/2,-h/6); fet_endchar; fet_beginchar("Quart trianglehead", "2triangle", "trianglehead") thick := 1.2stafflinethickness; set_char_box(0, 2noteheight#/sqrt3*7/8,noteheight#/2,noteheight#/2); fill triangle scaled (7h/6) shifted (w/2,-h/6); fet_endchar; %%% Editable values: slope := 1.7; % slope of slash. From scm/grob-description.scm. How to auto-copy? slt := 2/3*0.48staff_space; % thickness of lines. quarter notes get 1.5slt width. slh := 2staff_space; % height of char. %%% Calculated values: sxa := 0; % how much the char exceeds the boundingbox horizontally: slxt := sqrt(slt*slt+(slt/slope)*(slt/slope)); % Width of hor. pen - with thanks to Pythagoras slw := slh/slope; % width of sloping part of slash: % is this really nessesary? -rz fac# := staff_space#/staff_space; slt# := fac#*slt; slh# := fac#*slh; sxa# := fac#*sxa; slxt# := fac#*slxt; slw# := fac#*slw; def draw_slash(expr hwid) = wid# := slw#+2slxt#+hwid*fac#; set_char_box(0,wid#-2sxa#,slh#/2,slh#/2); define_pixels (wid#); pickup penrazor scaled slxt; draw (-b+slxt/2-sxa,-d) -- (-b+slxt/2+slw-sxa,h); draw (w-slxt/2-slw+sxa,-d) -- (w-slxt/2+sxa,h); pickup penrazor scaled slt rotated 90; draw (-b+slxt-sxa,-d+slt/2) -- (w-slw+sxa,-d+slt/2); draw (-b+slw-sxa,h-slt/2) -- (w-slxt+sxa,h-slt/2); enddef; fet_beginchar("Whole slashhead","0slash","wholeslashhead") draw_slash(staff_space); fet_endchar; fet_beginchar("Half slashhead","1slash","halfslashhead") draw_slash(0.6staff_space); fet_endchar; fet_beginchar("Quart slashhead","2slash","quartslashhead") draw_slash(-slxt/2); fet_endchar; % thick is the distance between the two parallel lines in the cross (distance between centres of lines) def draw_cross(expr thick) = pent := 1.2stafflinethickness; pickup pencircle scaled pent; % alfa is the slant of the lines (i.e. 1 means 45 degrees) alfa := (2h-pent)/(w-pent); % llen is the length of the little outer lines % llen = thick / sin(2atan(alfa)) llen := thick/(ypart(dir(2angle(1,alfa)))); xa := llen/sqrt(1+alfa**2); ya := xa*alfa; xl := w/2-xa-pent/2; yl := h-ya-pent/2; save crz; path crz; crz = (xa,0) -- (xa+xl,yl) -- (xl,yl+ya) -- (0,ya); draw crz shifted(w/2,0); draw crz xscaled -1 shifted(w/2,0); draw crz yscaled -1 shifted(w/2,0); draw crz scaled -1 shifted(w/2,0); enddef; fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead") wid# := black_notehead_width#+4stafflinethickness#; hei# := noteheight#+stafflinethickness#; set_char_box(0, wid#,hei#/2,hei#/2); draw_cross(3.75stafflinethickness); fet_endchar; fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead") wid# := black_notehead_width#+2stafflinethickness#; hei# := noteheight#+stafflinethickness#/2; set_char_box(0, wid#,hei#/2,hei#/2); draw_cross(3stafflinethickness); fet_endchar; fet_beginchar("Crossed notehead", "2cross", "crossedhead") wid# := black_notehead_width#; hei# := noteheight#; set_char_box(0, wid#,hei#/2,hei#/2); draw_cross(stafflinethickness/4); fet_endchar; fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead") set_char_box(0, noteheight#+stafflinethickness#, noteheight#/2+stafflinethickness#/2,noteheight#/2+stafflinethickness#/2); pickup pencircle scaled 1.2stafflinethickness; draw fullcircle scaled 2h shifted (h,0); pos := h/sqrt2; draw (-pos+h,-pos) -- (pos+h,pos); draw (-pos+h,pos) -- (pos+h,-pos); fet_endchar; fet_endgroup("noteheads"); define_pixels(black_notehead_width);