2 % feta-bolletjes.mf -- implement noteheads
4 % source file of LilyPond's pretty-but-neat music font
6 % (c) 1997--2002 Jan Nieuwenhuizen <janneke@gnu.org>
7 % & Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 % & Juergen Reuter <reuter@ipd.uka.de>
12 % most beautiful noteheads are pronounced, not circular,
13 % and not even symmetric.
14 % These examples are inspired by [Wanske], see literature list
17 save black_notehead_width;
18 numeric black_notehead_width;
20 fet_begingroup("noteheads");
22 noteheight#:=staff_space#+ (1 + overdone_heads) *stafflinethickness#;
23 define_pixels(noteheight);
27 %%% TODO: Document these!
31 def setup_notehead_vars =
32 save a_b,err_y_a,tilt,superness;
33 save ai_a,ai_bi,err_y_ai,err_x_bi,inner_tilt,inner_superness;
37 % setup addititional vars and calc them
39 save a,beta,ai,bi, ht, wd;
46 define_pixels(a,beta);
48 set_char_box(0, wd#, .5 ht#, .5 ht#);
52 % draw the outer and inner ellipse.
55 black=distorted_ellipse(a,beta,a*err_y_a,0,superness);
56 white=distorted_ellipse(ai,bi,ai*err_y_ai,bi*err_x_bi,inner_superness);
59 x1=-x3=a; x2=x4=0; y1=y3=0; y2=-y4=b;
63 black:=black rotated tilt;
64 black:=black shifted (w/2,0);
65 white:=white rotated inner_tilt;
66 white:=white shifted (w/2,0);
78 err_y_a:=0; % no slant
89 inner_tilt:=125; % jcn
90 % inner_superness:=0.69;
91 inner_superness:=0.68; % jcn
92 b_h:=1; %no rotate-> no height correction
93 a_w:=1; % no rotate-> no width correction
96 whole_notehead_width# := wd#;
102 % dimensions aren't entirely right.
104 fet_beginchar ("Brevis notehead", "-1", "brevishead");
105 save stemthick, fudge;
106 define_pixels (stemthick);
107 fudge = blot_diameter /2;
108 stemthick# = 2 stafflinethickness#;
112 pickup pencircle scaled stemthick;
124 draw_gridline(z1,z2,stemthick);
125 draw_gridline(z3,z4,stemthick);
130 fet_beginchar("Whole notehead", "0", "wholehead")
138 fet_beginchar("Half notehead", "1",
141 % a_b:=1.49; % after text
142 a_b:=1.50; % after drawing
146 superness:=0.67; % jcn
154 inner_superness:=0.80;
159 half_notehead_width# := wd#;
167 fet_beginchar("Quart notehead", "2", "quarthead")
169 % a_b:=1.57; % after text
170 a_b:=1.54; % after drawing
179 inner_superness:=0.707;
184 black_notehead_width# := wd#;
191 fet_beginchar("Whole diamondhead", "0diamond", "wholediamondhead")
195 err_y_a:=0; % no slant
206 inner_tilt:=125; % jcn
207 % inner_superness:=0.69;
208 inner_superness:=0.6; % jcn
209 b_h:=1; %no rotate-> no height correction
210 a_w:=1; % no rotate-> no width correction
213 whole_notehead_width# := wd#;
220 fet_beginchar("Half diamondhead", "1diamond",
224 a_b := 1.50; % after drawing
228 superness:=0.49; % jcn
235 inner_superness:=0.80;
241 half_notehead_width# := wd#;
248 fet_beginchar("Quart diamondhead", "2diamond", "diamondhead")
249 set_char_box(0, black_notehead_width#, noteheight#/2, noteheight#/2);
250 save a_b,err_y_a,tilt,superness;
252 save a,beta,ai,bi, ht, wd;
265 define_pixels(a,beta);
267 black := distorted_ellipse(.72 noteheight, .45 noteheight, -.2 noteheight , 0, superness)
269 % beta,a*err_y_a,0,superness);
271 black:=black rotated tilt;
272 black:=black shifted (w/2,0);
280 save triangle,kern; path triangle;
284 z12 = caveness[.5[z1,z2],z3];
285 z23 = z12 rotated 120;
286 z31 = z12 rotated 240;
287 triangle = z1 .. z12 .. z2 ..
291 triangle := triangle shifted (-x1+pent/2-kern,0) xscaled xs;
292 pickup pencircle scaled pent xscaled xs;
293 hei = max(y1,-y2)+pent/2;
294 %set_char_box(-kern*xs*fac, ((x3-x1)*fac+pent#)*xs,hei*fac,hei*fac);
295 set_char_box(0, ((x3-x1-kern)*fac+pent#)*xs,hei*fac,hei*fac);
298 fac = noteheight#/noteheight;
299 pent# = 2stafflinethickness#;
303 fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead")
305 z1 = dir(130)*3/4noteheight;
312 fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead")
314 z1 = dir(130)*2/3noteheight;
321 fet_beginchar("Quart trianglehead", "2triangle", "trianglehead")
323 z1 = dir(130)*2/3noteheight;
333 slope := 1.7; % slope of slash. From scm/grob-description.scm. How to auto-copy?
334 slt# := 2/3*0.48staff_space#; % thickness of lines. quarter notes get 1.5slt width.
335 slh# := 2staff_space#; % height of char.
337 %%% Calculated values:
338 sxa# := 0; % how much the char exceeds the boundingbox horizontally:
339 slxt# := sqrt(slt#*slt#+(slt#/slope)*(slt#/slope)); % Width of hor. pen - with thanks to Pythagoras
340 slw# := slh#/slope; % width of sloping part of slash:
342 define_pixels(slt,slh,sxa,slxt,slw);
344 def draw_slash(expr hwid_hash) =
345 wid# := slw#+2slxt#+hwid_hash;
346 set_char_box(0,wid#-2sxa#,slh#/2,slh#/2);
347 define_pixels (wid#);
348 pickup penrazor scaled slxt;
349 draw (-b+slxt/2-sxa,-d) -- (-b+slxt/2+slw-sxa,h);
350 draw (w-slxt/2-slw+sxa,-d) -- (w-slxt/2+sxa,h);
351 pickup penrazor scaled slt rotated 90;
352 draw (-b+slxt-sxa,-d+slt/2) -- (w-slw+sxa,-d+slt/2);
353 draw (-b+slw-sxa,h-slt/2) -- (w-slxt+sxa,h-slt/2);
356 fet_beginchar("Whole slashhead","0slash","wholeslashhead")
357 draw_slash(staff_space#);
360 fet_beginchar("Half slashhead","1slash","halfslashhead")
361 draw_slash(0.6staff_space#);
364 fet_beginchar("Quart slashhead","2slash","quartslashhead")
365 draw_slash(-slxt#/2);
368 % thick is the distance between the two parallel lines in the cross (distance between centres of lines)
369 def draw_cross(expr thick) =
370 pent := 1.2stafflinethickness;
371 pickup pencircle scaled pent;
372 % alfa is the slant of the lines (i.e. 1 means 45 degrees)
373 alfa := (2h-pent)/(w-pent);
374 % llen is the length of the little outer lines
375 % llen = thick / sin(2atan(alfa))
376 llen := thick/(ypart(dir(2angle(1,alfa))));
377 xa := llen/sqrt(1+alfa**2);
382 crz = (xa,0) -- (xa+xl,yl) -- (xl,yl+ya) -- (0,ya);
383 draw crz shifted(w/2,0);
384 draw crz xscaled -1 shifted(w/2,0);
385 draw crz yscaled -1 shifted(w/2,0);
386 draw crz scaled -1 shifted(w/2,0);
389 fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead")
390 wid# := black_notehead_width#+4stafflinethickness#;
391 hei# := noteheight#+stafflinethickness#;
392 set_char_box(0, wid#,hei#/2,hei#/2);
393 draw_cross(3.75stafflinethickness);
396 fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead")
397 wid# := black_notehead_width#+2stafflinethickness#;
398 hei# := noteheight#+stafflinethickness#/2;
399 set_char_box(0, wid#,hei#/2,hei#/2);
400 draw_cross(3stafflinethickness);
403 fet_beginchar("Crossed notehead", "2cross", "crossedhead")
404 wid# := black_notehead_width#;
406 set_char_box(0, wid#,hei#/2,hei#/2);
407 draw_cross(stafflinethickness/4);
410 fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead")
411 wid# := black_notehead_width#*sqrt(sqrt2);
412 hei# := noteheight#*sqrt(sqrt2);
413 set_char_box(0, wid#,hei#/2,hei#/2);
414 cthick := (1.2+1/4)*stafflinethickness;
417 pickup pencircle scaled cthick;
418 draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0);
421 draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
422 draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
429 % ledger (leger) lines
431 fet_beginchar("Ledger ending", "ledgerending", "ledgerending")
432 set_char_box (5/2 ledgerlinethickness#, 5/2 ledgerlinethickness#,
433 ledgerlinethickness#/2,ledgerlinethickness#/2);
434 draw_rounded_block((-b,-d),(w,h),1.3 blot_diameter);
438 fet_endgroup("noteheads");
439 define_pixels(black_notehead_width);