2 % feta-bolletjes.mf -- implement noteheads
4 % source file of LilyPond's pretty-but-neat music font
6 % (c) 1997--2003 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);
70 pickup pencircle scaled 1;
85 err_y_a:=0; % no slant
96 inner_tilt:=125; % jcn
97 % inner_superness:=0.69;
98 inner_superness:=0.68; % jcn
99 b_h:=1; %no rotate-> no height correction
100 a_w:=1; % no rotate-> no width correction
103 whole_notehead_width# := wd#;
109 % dimensions aren't entirely right.
111 fet_beginchar ("Brevis notehead", "-1", "brevishead");
112 save stemthick, fudge;
113 define_pixels (stemthick);
114 fudge = blot_diameter /2;
115 stemthick# = 2 stafflinethickness#;
119 pickup pencircle scaled stemthick;
131 draw_gridline(z1,z2,stemthick);
132 draw_gridline(z3,z4,stemthick);
137 fet_beginchar("Whole notehead", "0", "wholehead")
145 fet_beginchar("Half notehead", "1",
148 % a_b:=1.49; % after text
149 a_b:=1.50; % after drawing
153 superness:=0.67; % jcn
156 % set to 0.83 to avoid stem entering white part.
163 inner_superness:=0.80;
168 half_notehead_width# := wd#;
173 pickup penrazor scaled stemthickness;
174 draw (.5 stemthickness, -2 staff_space) ..
175 (.5 stemthickness, - wd * (ypart dir (inner_tilt - 10)) /2);
183 fet_beginchar("Quart notehead", "2", "quarthead")
185 % a_b:=1.57; % after text
186 a_b:=1.54; % after drawing
195 inner_superness:=0.707;
200 black_notehead_width# := wd#;
207 fet_beginchar("Whole diamondhead", "0diamond", "wholediamondhead")
211 err_y_a:=0; % no slant
222 inner_tilt:=125; % jcn
223 % inner_superness:=0.69;
224 inner_superness:=0.6; % jcn
225 b_h:=1; %no rotate-> no height correction
226 a_w:=1; % no rotate-> no width correction
229 whole_notehead_width# := wd#;
236 fet_beginchar("Half diamondhead", "1diamond",
240 a_b := 1.50; % after drawing
244 superness:=0.49; % jcn
251 inner_superness:=0.80;
257 half_notehead_width# := wd#;
264 fet_beginchar("Quart diamondhead", "2diamond", "diamondhead")
265 set_char_box(0, black_notehead_width#, noteheight#/2, noteheight#/2);
266 save a_b,err_y_a,tilt,superness;
268 save a,beta,ai,bi, ht, wd;
281 define_pixels(a,beta);
283 black := distorted_ellipse(.72 noteheight, .45 noteheight, -.2 noteheight , 0, superness)
285 % beta,a*err_y_a,0,superness);
287 black:=black rotated tilt;
288 black:=black shifted (w/2,0);
294 pen_thick# = 2stafflinethickness#;
295 define_pixels(pen_thick);
301 def def_triangle_old =
302 save triangle,kern; path triangle;
306 z12 = caveness[.5[z1,z2],z3];
307 z23 = z12 rotated 120;
308 z31 = z12 rotated 240;
309 triangle = z1 .. z12 .. z2 ..
313 triangle := triangle shifted (-x1+pent/2-kern,0) xscaled xs;
314 pickup pencircle scaled pent xscaled xs;
315 hei = max(y1,-y2)+pent/2;
316 %set_char_box(-kern*xs*fac, ((x3-x1)*fac+pent#)*xs,hei*fac,hei*fac);
317 set_char_box(0, ((x3-x1-kern)*fac+pent#)*xs,hei*fac,hei*fac);
322 save triangle,kern; path triangle;
323 save left_point, height, width;
324 pair exact_left_point;
326 exact_left_point := llap# * dir (90 + tilt);
327 height# = max (ypart exact_left_point,
328 -ypart (exact_left_point rotated 120)) + pen_thick#/2;
330 kern# = 1/3 xpart (exact_left_point - (exact_left_point rotated 120));
331 width# = xpart (-exact_left_point + (exact_left_point rotated 240));
332 define_pixels (kern);
333 z1 = (hround_pixels (xpart exact_left_point), vround_pixels (ypart exact_left_point));
337 z12 = caveness[.5[z1,z2],z3];
338 z23 = z12 rotated 120;
339 z31 = z12 rotated 240;
340 triangle = z1 .. z12 .. z2 ..
344 triangle := triangle shifted (-x1+pen_thick/2-kern,0) xscaled xs;
345 pickup pencircle scaled pen_thick xscaled xs;
346 % labels(1,2,12,23,31,3);
347 set_char_box(0, width# - kern#+ pen_thick#, height#, height#);
350 fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead")
356 llap# = 3/4noteheight#;
364 fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead")
370 llap# = 2/3noteheight#;
377 fet_beginchar("Quart trianglehead", "2triangle", "trianglehead")
382 llap# = 2/3noteheight#;
393 slash_slope := 1.7; % slope of slash. From scm/grob-description.scm. How to auto-copy?
394 slt# := 2/3*0.48staff_space#; % thickness of lines. quarter notes get 1.5slt width.
395 slh# := 2staff_space#; % height of char.
397 %%% Calculated values:
398 sxa# := 0; % how much the char exceeds the boundingbox horizontally:
400 % Width of hor. pen - with thanks to Pythagoras
401 slxt# := sqrt(slt#*slt#+(slt#/slash_slope)*(slt#/slash_slope));
402 slw# := slh#/slash_slope; % width of sloping part of slash:
404 define_pixels(slt,slh,sxa,slxt,slw);
409 % UUGGGH! FIXME -- get rid of those sharp corners.
415 def draw_slash(expr hwid_hash) =
416 wid# := slw#+2slxt#+hwid_hash;
417 set_char_box(0,wid#-2sxa#,slh#/2,slh#/2);
418 define_pixels (wid#);
419 pickup penrazor scaled slxt;
420 draw (-b+slxt/2-sxa,-d) -- (-b+slxt/2+slw-sxa,h);
421 draw (w-slxt/2-slw+sxa,-d) -- (w-slxt/2+sxa,h);
422 pickup penrazor scaled slt rotated 90;
423 draw (-b+slxt-sxa,-d+slt/2) -- (w-slw+sxa,-d+slt/2);
424 draw (-b+slw-sxa,h-slt/2) -- (w-slxt+sxa,h-slt/2);
427 fet_beginchar("Whole slashhead","0slash","wholeslashhead")
428 draw_slash(staff_space#);
431 fet_beginchar("Half slashhead","1slash","halfslashhead")
432 draw_slash(0.6staff_space#);
435 fet_beginchar("Quart slashhead","2slash","quartslashhead")
436 draw_slash(-slxt#/2);
439 % thick is the distance between the two parallel lines in the cross (distance between centres of lines)
440 def draw_cross(expr thick) =
441 pent := 1.2stafflinethickness;
442 pickup pencircle scaled pent;
443 % alfa is the slant of the lines (i.e. 1 means 45 degrees)
444 alfa := (2h-pent)/(w-pent);
445 % llen is the length of the little outer lines
446 % llen = thick / sin(2atan(alfa))
447 llen := thick/(ypart(dir(2angle(1,alfa))));
448 xa := llen/sqrt(1+alfa**2);
453 crz = (xa,0) -- (xa+xl,yl) -- (xl,yl+ya) -- (0,ya);
454 draw crz shifted(w/2,0);
455 draw crz xscaled -1 shifted(w/2,0);
456 draw crz yscaled -1 shifted(w/2,0);
457 draw crz scaled -1 shifted(w/2,0);
460 fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead")
461 wid# := black_notehead_width#+4stafflinethickness#;
462 hei# := noteheight#+stafflinethickness#;
463 set_char_box(0, wid#,hei#/2,hei#/2);
464 draw_cross(3.75stafflinethickness);
467 fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead")
468 wid# := black_notehead_width#+2stafflinethickness#;
469 hei# := noteheight#+stafflinethickness#/2;
470 set_char_box(0, wid#,hei#/2,hei#/2);
471 draw_cross(3stafflinethickness);
474 fet_beginchar("Crossed notehead", "2cross", "crossedhead")
475 wid# := black_notehead_width#;
477 set_char_box(0, wid#,hei#/2,hei#/2);
478 draw_cross(stafflinethickness/4);
481 fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead")
482 wid# := black_notehead_width#*sqrt(sqrt2);
483 hei# := noteheight#*sqrt(sqrt2);
484 set_char_box(0, wid#,hei#/2,hei#/2);
485 cthick := (1.2+1/4)*stafflinethickness;
488 pickup pencircle scaled cthick;
489 draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0);
492 draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
493 draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
498 fet_endgroup("noteheads");
499 define_pixels(black_notehead_width);