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);
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);
278 pen_thick# = 2stafflinethickness#;
279 define_pixels(pen_thick);
285 def def_triangle_old =
286 save triangle,kern; path triangle;
290 z12 = caveness[.5[z1,z2],z3];
291 z23 = z12 rotated 120;
292 z31 = z12 rotated 240;
293 triangle = z1 .. z12 .. z2 ..
297 triangle := triangle shifted (-x1+pent/2-kern,0) xscaled xs;
298 pickup pencircle scaled pent xscaled xs;
299 hei = max(y1,-y2)+pent/2;
300 %set_char_box(-kern*xs*fac, ((x3-x1)*fac+pent#)*xs,hei*fac,hei*fac);
301 set_char_box(0, ((x3-x1-kern)*fac+pent#)*xs,hei*fac,hei*fac);
306 save triangle,kern; path triangle;
307 save left_point, height, width;
308 pair exact_left_point;
310 exact_left_point := llap# * dir (90 + tilt);
311 height# = max (ypart exact_left_point,
312 -ypart (exact_left_point rotated 120)) + pen_thick#/2;
314 kern# = 1/3 xpart (exact_left_point - (exact_left_point rotated 120));
315 width# = xpart (-exact_left_point + (exact_left_point rotated 240));
316 define_pixels (kern);
317 z1 = (hround_pixels (xpart exact_left_point), vround_pixels (ypart exact_left_point));
321 z12 = caveness[.5[z1,z2],z3];
322 z23 = z12 rotated 120;
323 z31 = z12 rotated 240;
324 triangle = z1 .. z12 .. z2 ..
328 triangle := triangle shifted (-x1+pen_thick/2-kern,0) xscaled xs;
329 pickup pencircle scaled pen_thick xscaled xs;
330 % labels(1,2,12,23,31,3);
331 set_char_box(0, width# - kern#+ pen_thick#, height#, height#);
334 fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead")
340 llap# = 3/4noteheight#;
348 fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead")
354 llap# = 2/3noteheight#;
361 fet_beginchar("Quart trianglehead", "2triangle", "trianglehead")
366 llap# = 2/3noteheight#;
377 slash_slope := 1.7; % slope of slash. From scm/grob-description.scm. How to auto-copy?
378 slt# := 2/3*0.48staff_space#; % thickness of lines. quarter notes get 1.5slt width.
379 slh# := 2staff_space#; % height of char.
381 %%% Calculated values:
382 sxa# := 0; % how much the char exceeds the boundingbox horizontally:
384 % Width of hor. pen - with thanks to Pythagoras
385 slxt# := sqrt(slt#*slt#+(slt#/slash_slope)*(slt#/slash_slope));
386 slw# := slh#/slash_slope; % width of sloping part of slash:
388 define_pixels(slt,slh,sxa,slxt,slw);
393 % UUGGGH! FIXME -- get rid of those sharp corners.
399 def draw_slash(expr hwid_hash) =
400 wid# := slw#+2slxt#+hwid_hash;
401 set_char_box(0,wid#-2sxa#,slh#/2,slh#/2);
402 define_pixels (wid#);
403 pickup penrazor scaled slxt;
404 draw (-b+slxt/2-sxa,-d) -- (-b+slxt/2+slw-sxa,h);
405 draw (w-slxt/2-slw+sxa,-d) -- (w-slxt/2+sxa,h);
406 pickup penrazor scaled slt rotated 90;
407 draw (-b+slxt-sxa,-d+slt/2) -- (w-slw+sxa,-d+slt/2);
408 draw (-b+slw-sxa,h-slt/2) -- (w-slxt+sxa,h-slt/2);
411 fet_beginchar("Whole slashhead","0slash","wholeslashhead")
412 draw_slash(staff_space#);
415 fet_beginchar("Half slashhead","1slash","halfslashhead")
416 draw_slash(0.6staff_space#);
419 fet_beginchar("Quart slashhead","2slash","quartslashhead")
420 draw_slash(-slxt#/2);
423 % thick is the distance between the two parallel lines in the cross (distance between centres of lines)
424 def draw_cross(expr thick) =
425 pent := 1.2stafflinethickness;
426 pickup pencircle scaled pent;
427 % alfa is the slant of the lines (i.e. 1 means 45 degrees)
428 alfa := (2h-pent)/(w-pent);
429 % llen is the length of the little outer lines
430 % llen = thick / sin(2atan(alfa))
431 llen := thick/(ypart(dir(2angle(1,alfa))));
432 xa := llen/sqrt(1+alfa**2);
437 crz = (xa,0) -- (xa+xl,yl) -- (xl,yl+ya) -- (0,ya);
438 draw crz shifted(w/2,0);
439 draw crz xscaled -1 shifted(w/2,0);
440 draw crz yscaled -1 shifted(w/2,0);
441 draw crz scaled -1 shifted(w/2,0);
444 fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead")
445 wid# := black_notehead_width#+4stafflinethickness#;
446 hei# := noteheight#+stafflinethickness#;
447 set_char_box(0, wid#,hei#/2,hei#/2);
448 draw_cross(3.75stafflinethickness);
451 fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead")
452 wid# := black_notehead_width#+2stafflinethickness#;
453 hei# := noteheight#+stafflinethickness#/2;
454 set_char_box(0, wid#,hei#/2,hei#/2);
455 draw_cross(3stafflinethickness);
458 fet_beginchar("Crossed notehead", "2cross", "crossedhead")
459 wid# := black_notehead_width#;
461 set_char_box(0, wid#,hei#/2,hei#/2);
462 draw_cross(stafflinethickness/4);
465 fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead")
466 wid# := black_notehead_width#*sqrt(sqrt2);
467 hei# := noteheight#*sqrt(sqrt2);
468 set_char_box(0, wid#,hei#/2,hei#/2);
469 cthick := (1.2+1/4)*stafflinethickness;
472 pickup pencircle scaled cthick;
473 draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0);
476 draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
477 draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
484 % ledger (leger) lines
486 fet_beginchar("Ledger ending", "ledgerending", "ledgerending")
487 set_char_box (5/2 ledgerlinethickness#, 5/2 ledgerlinethickness#,
488 ledgerlinethickness#/2,ledgerlinethickness#/2);
491 draw_rounded_block((-b,-d),(w,h), 0.8 ledgerlinethickness);
495 fet_endgroup("noteheads");
496 define_pixels(black_notehead_width);