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#);
54 % err_x: drift of y axis at top
55 % err_y: drift of x axis at right
56 def distorted_ellipse(expr a,b,err_y,err_x,super) =
57 superellipse((a,err_x),(-err_y,b),(-a,-err_x),(err_y,-b),super);
62 % draw the outer and inner ellipse.
65 black=distorted_ellipse(a,beta,a*err_y_a,0,superness);
66 white=distorted_ellipse(ai,bi,ai*err_y_ai,bi*err_x_bi,inner_superness);
69 x1=-x3=a; x2=x4=0; y1=y3=0; y2=-y4=b;
73 black:=black rotated tilt;
74 black:=black shifted (w/2,0);
75 white:=white rotated inner_tilt;
76 white:=white shifted (w/2,0);
80 pickup pencircle scaled 1;
95 err_y_a:=0; % no slant
106 inner_tilt:=125; % jcn
107 % inner_superness:=0.69;
108 inner_superness:=0.68; % jcn
109 b_h:=1; %no rotate-> no height correction
110 a_w:=1; % no rotate-> no width correction
113 whole_notehead_width# := wd#;
119 % dimensions aren't entirely right.
121 fet_beginchar ("Brevis notehead", "-1", "brevishead");
122 save stemthick, fudge;
123 define_pixels (stemthick);
124 fudge = blot_diameter /2;
125 stemthick# = 2 stafflinethickness#;
129 pickup pencircle scaled stemthick;
141 draw_gridline(z1,z2,stemthick);
142 draw_gridline(z3,z4,stemthick);
147 fet_beginchar("Whole notehead", "0", "wholehead")
155 fet_beginchar("Half notehead", "1",
158 % a_b:=1.49; % after text
159 a_b:=1.50; % after drawing
164 superness:=0.67; % jcn
168 % set to 0.83 to avoid stem entering white part.
175 inner_superness:=0.80;
180 half_notehead_width# := wd#;
185 pickup penrazor scaled stemthickness;
186 draw (.5 stemthickness, -2 staff_space) ..
187 (.5 stemthickness, - wd * (ypart dir (inner_tilt - 10)) /2);
195 fet_beginchar("Quart notehead", "2", "quarthead")
197 % a_b:=1.57; % after text
198 a_b:=1.54; % after drawing
207 inner_superness:=0.707;
212 black_notehead_width# := wd#;
219 fet_beginchar("Whole diamondhead", "0diamond", "wholediamondhead")
223 err_y_a:=0; % no slant
234 inner_tilt:=125; % jcn
235 % inner_superness:=0.69;
236 inner_superness:=0.6; % jcn
237 b_h:=1; %no rotate-> no height correction
238 a_w:=1; % no rotate-> no width correction
241 whole_notehead_width# := wd#;
248 fet_beginchar("Half diamondhead", "1diamond",
252 a_b := 1.50; % after drawing
256 superness:=0.49; % jcn
263 inner_superness:=0.80;
269 half_notehead_width# := wd#;
276 fet_beginchar("Quart diamondhead", "2diamond", "diamondhead")
277 set_char_box(0, black_notehead_width#, noteheight#/2, noteheight#/2);
278 save a_b,err_y_a,tilt,superness;
280 save a,beta,ai,bi, ht, wd;
293 define_pixels(a,beta);
295 black := distorted_ellipse(.72 noteheight, .45 noteheight, -.2 noteheight , 0, superness)
297 % beta,a*err_y_a,0,superness);
299 black:=black rotated tilt;
300 black:=black shifted (w/2,0);
306 pen_thick# = 2stafflinethickness#;
307 define_pixels(pen_thick);
313 def def_triangle_old =
314 save triangle,kern; path triangle;
318 z12 = caveness[.5[z1,z2],z3];
319 z23 = z12 rotated 120;
320 z31 = z12 rotated 240;
321 triangle = z1 .. z12 .. z2 ..
325 triangle := triangle shifted (-x1+pent/2-kern,0) xscaled xs;
326 pickup pencircle scaled pent xscaled xs;
327 hei = max(y1,-y2)+pent/2;
328 %set_char_box(-kern*xs*fac, ((x3-x1)*fac+pent#)*xs,hei*fac,hei*fac);
329 set_char_box(0, ((x3-x1-kern)*fac+pent#)*xs,hei*fac,hei*fac);
334 save triangle,kern; path triangle;
335 save left_point, height, width;
336 pair exact_left_point;
338 exact_left_point := llap# * dir (90 + tilt);
339 height# = max (ypart exact_left_point,
340 -ypart (exact_left_point rotated 120)) + pen_thick#/2;
342 kern# = 1/3 xpart (exact_left_point - (exact_left_point rotated 120));
343 width# = xpart (-exact_left_point + (exact_left_point rotated 240));
344 define_pixels (kern);
345 z1 = (hround_pixels (xpart exact_left_point), vround_pixels (ypart exact_left_point));
349 z12 = caveness[.5[z1,z2],z3];
350 z23 = z12 rotated 120;
351 z31 = z12 rotated 240;
352 triangle = z1 .. z12 .. z2 ..
356 triangle := triangle shifted (-x1+pen_thick/2-kern,0) xscaled xs;
357 pickup pencircle scaled pen_thick xscaled xs;
358 % labels(1,2,12,23,31,3);
359 set_char_box(0, width# - kern#+ pen_thick#, height#, height#);
362 fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead")
368 llap# = 3/4noteheight#;
376 fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead")
382 llap# = 2/3noteheight#;
389 fet_beginchar("Quart trianglehead", "2triangle", "trianglehead")
394 llap# = 2/3noteheight#;
405 slash_slope := 1.7; % slope of slash. From scm/grob-description.scm. How to auto-copy?
406 slt# := 2/3*0.48staff_space#; % thickness of lines. quarter notes get 1.5slt width.
407 slh# := 2staff_space#; % height of char.
409 %%% Calculated values:
410 sxa# := 0; % how much the char exceeds the boundingbox horizontally:
412 % Width of hor. pen - with thanks to Pythagoras
413 slxt# := sqrt(slt#*slt#+(slt#/slash_slope)*(slt#/slash_slope));
414 slw# := slh#/slash_slope; % width of sloping part of slash:
416 define_pixels(slt,slh,sxa,slxt,slw);
421 % UUGGGH! FIXME -- get rid of those sharp corners.
427 def draw_slash(expr hwid_hash) =
428 wid# := slw#+2slxt#+hwid_hash;
429 set_char_box(0,wid#-2sxa#,slh#/2,slh#/2);
430 define_pixels (wid#);
431 pickup penrazor scaled slxt;
432 draw (-b+slxt/2-sxa,-d) -- (-b+slxt/2+slw-sxa,h);
433 draw (w-slxt/2-slw+sxa,-d) -- (w-slxt/2+sxa,h);
434 pickup penrazor scaled slt rotated 90;
435 draw (-b+slxt-sxa,-d+slt/2) -- (w-slw+sxa,-d+slt/2);
436 draw (-b+slw-sxa,h-slt/2) -- (w-slxt+sxa,h-slt/2);
439 fet_beginchar("Whole slashhead","0slash","wholeslashhead")
440 draw_slash(staff_space#);
443 fet_beginchar("Half slashhead","1slash","halfslashhead")
444 draw_slash(0.6staff_space#);
447 fet_beginchar("Quart slashhead","2slash","quartslashhead")
448 draw_slash(-slxt#/2);
451 % thick is the distance between the two parallel lines in the cross (distance between centres of lines)
452 def draw_cross(expr thick) =
453 pent := 1.2stafflinethickness;
454 pickup pencircle scaled pent;
455 % alfa is the slant of the lines (i.e. 1 means 45 degrees)
456 alfa := (2h-pent)/(w-pent);
457 % llen is the length of the little outer lines
458 % llen = thick / sin(2atan(alfa))
459 llen := thick/(ypart(dir(2angle(1,alfa))));
460 xa := llen/sqrt(1+alfa**2);
465 crz = (xa,0) -- (xa+xl,yl) -- (xl,yl+ya) -- (0,ya);
466 draw crz shifted(w/2,0);
467 draw crz xscaled -1 shifted(w/2,0);
468 draw crz yscaled -1 shifted(w/2,0);
469 draw crz scaled -1 shifted(w/2,0);
472 fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead")
473 wid# := black_notehead_width#+4stafflinethickness#;
474 hei# := noteheight#+stafflinethickness#;
475 set_char_box(0, wid#,hei#/2,hei#/2);
476 draw_cross(3.75stafflinethickness);
479 fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead")
480 wid# := black_notehead_width#+2stafflinethickness#;
481 hei# := noteheight#+stafflinethickness#/2;
482 set_char_box(0, wid#,hei#/2,hei#/2);
483 draw_cross(3stafflinethickness);
486 fet_beginchar("Crossed notehead", "2cross", "crossedhead")
487 wid# := black_notehead_width#;
489 set_char_box(0, wid#,hei#/2,hei#/2);
490 draw_cross(stafflinethickness/4);
493 fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead")
494 wid# := black_notehead_width#*sqrt(sqrt2);
495 hei# := noteheight#*sqrt(sqrt2);
496 set_char_box(0, wid#,hei#/2,hei#/2);
497 cthick := (1.2+1/4)*stafflinethickness;
500 pickup pencircle scaled cthick;
501 draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0);
504 draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
505 draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
510 fet_endgroup("noteheads");
511 define_pixels(black_notehead_width);