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");
24 noteheight#:=staff_space#+ (1 + overdone_heads) *stafflinethickness#;
28 % SLANT moves both extremes on the long axis (by SLANT * ELLIPSIDITY,
29 % so SLANT = -1, puts the extreme on the long axis next to the short axis one.)
32 def draw_outside_ellipse (expr ellipsidity, tilt, superness,
37 p := superellipse ((ellipsidity, 0), (-slant * ellipsidity, 1.0),
38 (- ellipsidity, 0), (slant * ellipsidity, -1.0), superness);
42 save top_point, right_point;
43 pair top_point, right_point;
45 top_point := directionpoint left of p;
46 right_point := directionpoint up of p;
48 save scaling, width, height;
50 scaling# = noteheight# /(2 ypart (top_point));
51 width# := 2 xpart (right_point) * scaling#;
53 define_pixels (width, scaling);
55 set_char_box (0, width#, noteheight#/2, noteheight#/2);
57 p := p scaled scaling shifted (width/2, 0) ;
59 pickup pencircle scaled 1 ; draw p;
66 def undraw_inside_ellipse (expr ellipsidity, tilt, superness, clearance,
72 p := superellipse ((ellipsidity, 0), (0, 1.0),
73 (- ellipsidity, 0), (0, -1.0), superness);
77 save top_point, right_point;
78 pair top_point, right_point;
80 top_point := directionpoint left of p;
81 right_point := directionpoint up of p;
85 height# = staff_space# + stafflinethickness# - clearance;
86 scaling# = height# /(2 ypart (top_point));
88 define_pixels (scaling);
89 p := (p scaled scaling) shifted center;
92 pickup pencircle scaled 1; draw p;
104 % dimensions aren't entirely right.
106 fet_beginchar ("Brevis notehead", "-1", "brevishead");
107 save stemthick, fudge;
108 define_pixels (stemthick);
109 fudge = blot_diameter /2;
110 stemthick# = 2 stafflinethickness#;
112 draw_outside_ellipse (1.80, 0, 0.707, 0);
113 undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#,
116 pickup pencircle scaled stemthick;
128 draw_gridline(z1,z2,stemthick);
129 draw_gridline(z3,z4,stemthick);
137 fet_beginchar("Whole notehead", "0", "wholehead")
138 draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0, 0.707, 0);
139 undraw_inside_ellipse (1.30, 125 - puff_up_factor *10,
140 0.68, 2 stafflinethickness#,
143 % draw_staff_outline (-2, 2, 0.5);
150 fet_beginchar("Half notehead", "1", "halfhead")
151 draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17);
152 undraw_inside_ellipse (3.25, 33, 0.81,
153 2.5 stafflinethickness#, (w/2, 0));
159 fet_beginchar("Quart notehead", "2", "quarthead")
160 draw_outside_ellipse (1.54 - puff_up_factor / 2.0, 32, 0.707, 0);
161 black_notehead_width# := charwd;
167 fet_beginchar("Whole diamondhead", "0diamond", "wholediamondhead")
168 draw_outside_ellipse (1.80, 0, 0.495, 0);
169 undraw_inside_ellipse (1.30, 125, 0.6,
170 .4 staff_space# + stafflinethickness#,
177 fet_beginchar("Half diamondhead", "1diamond",
180 draw_outside_ellipse (1.50, 34, 0.49, 0.17);
181 undraw_inside_ellipse (3.5, 33, 0.80,
182 .3 staff_space# + 1.5 stafflinethickness#, (w/2, 0));
188 fet_beginchar("Quart diamondheadh", "2diamondh", "diamondheadh")
189 draw_outside_ellipse (1.80, 35, 0.495, -0.25);
194 pen_thick# = stafflinethickness# + .1 staff_space#;
195 define_pixels(pen_thick);
201 def def_triangle_old =
202 save triangle,kern; path triangle;
206 z12 = caveness[.5[z1,z2],z3];
207 z23 = z12 rotated 120;
208 z31 = z12 rotated 240;
209 triangle = z1 .. z12 .. z2 ..
213 triangle := triangle shifted (-x1+pent/2-kern,0) xscaled xs;
214 pickup pencircle scaled pent xscaled xs;
215 hei = max(y1,-y2)+pent/2;
216 %set_char_box(-kern*xs*fac, ((x3-x1)*fac+pent#)*xs,hei*fac,hei*fac);
217 set_char_box(0, ((x3-x1-kern)*fac+pent#)*xs,hei*fac,hei*fac);
222 save triangle,kern; path triangle;
223 save left_point, height, width;
224 pair exact_left_point;
226 exact_left_point := llap# * dir (90 + tilt);
227 height# = max (ypart exact_left_point,
228 -ypart (exact_left_point rotated 120)) + pen_thick#/2;
230 kern# = 1/3 xpart (exact_left_point - (exact_left_point rotated 120));
231 width# = xpart (-exact_left_point + (exact_left_point rotated 240));
232 define_pixels (kern);
233 z1 = (hround_pixels (xpart exact_left_point), vround_pixels (ypart exact_left_point));
237 z12 = caveness[.5[z1,z2],z3];
238 z23 = z12 rotated 120;
239 z31 = z12 rotated 240;
240 triangle = z1 .. z12 .. z2 ..
244 triangle := triangle shifted (-x1+pen_thick/2-kern,0) xscaled xs;
245 pickup pencircle scaled pen_thick xscaled xs;
246 % labels(1,2,12,23,31,3);
247 set_char_box(0, width# - kern#+ pen_thick#, height#, height#);
250 fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead")
256 llap# = 3/4noteheight#;
264 fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead")
270 llap# = 2/3noteheight#;
277 fet_beginchar("Quart trianglehead", "2triangle", "trianglehead")
282 llap# = 2/3noteheight#;
294 % slope of slash. From scm/grob-description.scm. How to auto-copy?
297 % thickness of lines. quarter notes get 1.5slt width.
298 slash_thick# := 2/3*0.48staff_space#;
300 define_pixels(slash_thick);
302 def draw_slash(expr hwid_hash) =
303 set_char_box (0, staff_space# / slash_slope + hwid_hash,
304 staff_space#/2 + stafflinethickness#/2,
305 staff_space#/2 + stafflinethickness#/2);
308 pickup pencircle scaled blot_diameter;
313 lft x2 = staff_space / slash_slope;
320 filldraw z1 --- z2 --- z3 --- z4 --- cycle;
322 if hwid_hash > 2 slash_thick#:
325 th = slash_thick - blot_diameter;
330 z6 - z5 = whatever * (1, slash_slope);
331 z8 - z7 = whatever * (1, slash_slope);
333 z5 = z1 + whatever * (1, slash_slope) + (th, 0);
334 z8 = z4 + whatever * (1, slash_slope) + (-th, 0);
337 z5 -- z6 -- z7 -- z8 -- cycle;
339 labels (range 1 thru 10);
347 fet_beginchar("Whole slashhead","0slash","wholeslashhead")
348 draw_slash(2 slash_thick# + 0.5 staff_space#);
351 fet_beginchar("Half slashhead","1slash","halfslashhead")
352 draw_slash(2 slash_thick# + 0.15 staff_space#);
355 fet_beginchar("Quart slashhead","2slash","quartslashhead")
356 draw_slash(slash_thick#);
359 % thick is the distance between the two parallel lines in the cross (distance between centres of lines)
360 def draw_cross(expr thick) =
361 pent := 1.2stafflinethickness;
362 pickup pencircle scaled pent;
363 % alfa is the slant of the lines (i.e. 1 means 45 degrees)
364 alfa := (2h-pent)/(w-pent);
365 % llen is the length of the little outer lines
366 % llen = thick / sin(2atan(alfa))
367 llen := thick/(ypart(dir(2angle(1,alfa))));
368 xa := llen/sqrt(1+alfa**2);
373 crz = (xa,0) -- (xa+xl,yl) -- (xl,yl+ya) -- (0,ya);
374 draw crz shifted(w/2,0);
375 draw crz xscaled -1 shifted(w/2,0);
376 draw crz yscaled -1 shifted(w/2,0);
377 draw crz scaled -1 shifted(w/2,0);
380 fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead")
381 wid# := black_notehead_width#+4stafflinethickness#;
382 hei# := noteheight#+stafflinethickness#;
383 set_char_box(0, wid#,hei#/2,hei#/2);
384 draw_cross(3.75stafflinethickness);
387 fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead")
388 wid# := black_notehead_width#+2stafflinethickness#;
389 hei# := noteheight#+stafflinethickness#/2;
390 set_char_box(0, wid#,hei#/2,hei#/2);
391 draw_cross(3stafflinethickness);
394 fet_beginchar("Crossed notehead", "2cross", "crossedhead")
395 wid# := black_notehead_width#;
397 set_char_box(0, wid#,hei#/2,hei#/2);
398 draw_cross(stafflinethickness/4);
401 fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead")
402 wid# := black_notehead_width#*sqrt(sqrt2);
403 hei# := noteheight#*sqrt(sqrt2);
404 set_char_box(0, wid#,hei#/2,hei#/2);
405 cthick := (1.2+1/4)*stafflinethickness;
408 pickup pencircle scaled cthick;
409 draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0);
412 draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
413 draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
418 fet_endgroup("noteheads");
419 define_pixels(black_notehead_width);