]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-bolletjes.mf
* mf/feta-params.mf (stafflines): fix stafflinethickness at 0.5 pt
[lilypond.git] / mf / feta-bolletjes.mf
1 %  -*-Fundamental-*-
2 % feta-bolletjes.mf --  implement noteheads
3
4 % source file of LilyPond's pretty-but-neat music font
5
6 % (c)  1997--2003 Jan Nieuwenhuizen <janneke@gnu.org>
7 % & Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 % & Juergen Reuter <reuter@ipd.uka.de>
9
10
11
12 % most beautiful noteheads are pronounced, not circular, 
13 % and not even symmetric.
14 % These examples are inspired by [Wanske], see literature list
15
16
17 save black_notehead_width;
18 numeric black_notehead_width;
19
20 fet_begingroup("noteheads");
21
22 noteheight#:=staff_space#+ (1 + overdone_heads) *stafflinethickness#;
23 define_pixels(noteheight);
24
25 %
26
27 %%% TODO: Document these!
28 %
29
30 % setup user vars
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;
34         save b_h,a_w;
35         enddef;
36
37 % setup addititional vars and calc them
38 def notehead_calc =
39         save a,beta,ai,bi, ht, wd;
40         ht# =noteheight#;
41         2beta#=ht#*b_h;
42         a# = beta#*a_b;
43         wd# = 2a# / a_w;
44         ai# = a# * ai_a;
45         bi# = ai#/ai_bi;
46         define_pixels(a,beta);
47         define_pixels(ai,bi);
48         set_char_box(0, wd#, .5 ht#, .5 ht#);
49         enddef;
50
51
52 % a: x diameter
53 % b: y diameter
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);
58         enddef;
59
60
61
62 % draw the outer and inner ellipse.
63 def notehead_draw =
64         path black,white;
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);
67 if test > 1: %fixme
68                 save x;
69                 x1=-x3=a; x2=x4=0; y1=y3=0; y2=-y4=b;
70                 penlabels(1,2,3,4);
71                 test_grid;
72 else:
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);
77 fi
78
79         if test = 1:
80                 pickup pencircle scaled 1;
81                 draw black;
82                 draw white;
83         else:
84                 fill black;
85                 unfill white;
86         fi      
87
88                 
89         enddef;
90
91 def draw_whole_head =
92         setup_notehead_vars;
93         
94         a_b:=1.80;
95         err_y_a:=0; % no slant
96         tilt:=0;
97         superness:=0.707;
98         ai_a:=0.508;
99         % ai_bi:=1.23;
100         ai_bi:=1.30; % jcn
101         % err_y_ai:=0.0938;
102         % err_x_bi:=0;
103         err_y_ai:=0;
104         err_x_bi:=0.115;
105         % inner_tilt:=135;
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
111
112         notehead_calc;
113         whole_notehead_width# := wd#;
114         notehead_draw;
115 enddef;
116
117
118 %
119 % dimensions aren't entirely right.
120 %
121 fet_beginchar ("Brevis notehead", "-1", "brevishead");
122         save stemthick, fudge;
123         define_pixels (stemthick);
124         fudge = blot_diameter /2;
125         stemthick# = 2 stafflinethickness#;
126
127         draw_whole_head;
128
129         pickup pencircle scaled stemthick;
130
131         bot y1 = -d;
132         top y2 = h;
133         rt x1 - fudge = 0;
134         x1 = x2;
135
136         fudge + lft x3 = w;
137         x4 = x3;
138         y4 = y2;
139         y3 = y1;
140
141         draw_gridline(z1,z2,stemthick);
142         draw_gridline(z3,z4,stemthick);
143 fet_endchar;
144
145 % whole note
146 % Wanske, p.38
147 fet_beginchar("Whole notehead", "0", "wholehead")
148         draw_whole_head;
149 fet_endchar;
150
151
152
153 % half note
154 % Wanske, p.39
155 fet_beginchar("Half notehead", "1", 
156         "halfhead")
157         setup_notehead_vars;
158         % a_b:=1.49; % after text
159         a_b:=1.50; % after drawing
160         err_y_a:=0.157;
161         tilt:=34;
162
163         % superness:=0.66;
164         superness:=0.67; % jcn
165
166         % ai_a:=0.863;
167         % was 0.85
168         % set to 0.83 to avoid stem entering white part.
169         ai_a:=0.830; 
170         % ai_bi:=3.14;
171         ai_bi:=3.25;
172         err_y_ai:=0;
173         err_x_bi:=-0.12;
174         inner_tilt:=tilt;
175         inner_superness:=0.80;
176         b_h:=0.935;
177         a_w:=1.12;
178
179         notehead_calc;
180         half_notehead_width# := wd#;
181         notehead_draw;
182
183         define_pixels (wd);
184         if test = 1:
185                 pickup penrazor scaled stemthickness;
186                 draw (.5 stemthickness, -2 staff_space) ..
187                     (.5 stemthickness, - wd * (ypart dir (inner_tilt - 10)) /2);
188         fi;
189 fet_endchar;
190
191
192
193 % quarter note
194 % Wanske p.38
195 fet_beginchar("Quart notehead", "2", "quarthead")
196         setup_notehead_vars;
197         % a_b:=1.57; % after text
198         a_b:=1.54; % after drawing
199         err_y_a:=0.044;
200         tilt:=32;
201         superness:=0.707;
202         ai_a:=0;
203         ai_bi:=1;
204         err_y_ai:=0;
205         err_x_bi:=0;
206         inner_tilt:=0;
207         inner_superness:=0.707;
208         b_h:=0.85;
209         a_w:=1.09;
210
211         notehead_calc;
212         black_notehead_width# := wd#;
213         notehead_draw;
214 fet_endchar;
215
216
217 % whole note
218 % Wanske, p.38
219 fet_beginchar("Whole diamondhead", "0diamond", "wholediamondhead")
220         setup_notehead_vars;
221         
222         a_b:=1.80;
223         err_y_a:=0; % no slant
224         tilt:=0;
225         superness:=0.495;
226         ai_a:=0.350;
227         % ai_bi:=1.23;
228         ai_bi:=1.30; % jcn
229         % err_y_ai:=0.0938;
230         % err_x_bi:=0;
231         err_y_ai:=0;
232         err_x_bi:=0.115;
233         % inner_tilt:=135;
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
239
240         notehead_calc;
241         whole_notehead_width# := wd#;
242         notehead_draw;
243 fet_endchar;
244
245
246 % half note
247 % Wanske, p.39
248 fet_beginchar("Half diamondhead", "1diamond", 
249         "halfdiamondhead")
250         setup_notehead_vars;
251
252         a_b := 1.50; % after drawing
253         err_y_a:=0.157;
254
255         tilt:=34;
256         superness:=0.49; % jcn
257         ai_a:=0.550; % jcn
258         ai_bi:=3.30; % jcn
259
260         err_y_ai:=0;
261         err_x_bi:=-0.12;
262         inner_tilt:=tilt;
263         inner_superness:=0.80;
264
265         b_h:= 1.03;
266         a_w:= 1.2;
267
268         notehead_calc;
269         half_notehead_width# := wd#;
270         notehead_draw;
271 fet_endchar;
272
273
274 % quarter note
275 % Wanske p.38
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;
279         save b_h,a_w;
280         save a,beta,ai,bi, ht, wd;
281
282         a_b:= 1.8;
283         err_y_a:=-0.044;
284         b_h:=0.90;
285         a_w:=1.1;
286         tilt:=35;
287         superness:=0.495;
288
289         ht# =noteheight#;
290         2beta#=ht#*b_h;
291         a# = beta#*a_b;
292
293         define_pixels(a,beta);
294
295         black := distorted_ellipse(.72 noteheight, .45 noteheight, -.2 noteheight ,   0, superness)
296                                 
297 %                       beta,a*err_y_a,0,superness);
298
299         black:=black rotated tilt;
300         black:=black shifted (w/2,0);
301         fill black;
302 fet_endchar;
303
304
305 save pent;
306 pen_thick# = 2stafflinethickness#;
307 define_pixels(pen_thick);
308
309
310 begingroup;
311
312
313 def def_triangle_old =
314         save triangle,kern; path triangle;
315         kern = 1/3(x2-x1);
316         z2 = z1 rotated 120;
317         z3 = z1 rotated 240;
318         z12 = caveness[.5[z1,z2],z3];
319         z23 = z12 rotated 120;
320         z31 = z12 rotated 240;
321         triangle = z1 .. z12 .. z2 ..
322                     z2 .. z23 .. z3 ..
323                     z3 .. z31 .. z1 ..
324                     cycle;
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);
330 enddef;
331
332
333 def def_triangle =
334         save triangle,kern; path triangle;
335         save left_point, height, width;
336         pair exact_left_point;
337
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;
341
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));
346         z2 = z1 rotated 120;
347         z3 = z1 rotated 240;
348
349         z12 = caveness[.5[z1,z2],z3];
350         z23 = z12 rotated 120;
351         z31 = z12 rotated 240;
352         triangle = z1 .. z12 .. z2 ..
353                     z2 .. z23 .. z3 ..
354                     z3 .. z31 .. z1 ..
355                     cycle;
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#);
360 enddef;
361
362 fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead")
363         save hei,xs;
364         save llap;
365         save tilt;
366
367         tilt = 40;
368         llap# = 3/4noteheight#;
369
370         xs = 1.5;
371         caveness:=0.1;
372         def_triangle;
373         draw triangle;
374 fet_endchar;
375
376 fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead")
377         save hei,xs;
378         save llap;
379         save tilt;
380
381         tilt = 40;
382         llap# = 2/3noteheight#;
383         xs = 1.2;
384         caveness:=0.1;
385         def_triangle;
386         draw triangle;
387 fet_endchar;
388
389 fet_beginchar("Quart trianglehead", "2triangle", "trianglehead")
390         save hei,xs;
391         save llap;
392         save tilt;
393         tilt = 40;
394         llap# = 2/3noteheight#;
395         xs = 1.0;
396         caveness:=0.1;
397         def_triangle;
398         filldraw triangle;
399 fet_endchar;
400
401 endgroup;
402
403 %%% Editable values:
404
405
406 % slope of slash. From scm/grob-description.scm. How to auto-copy?
407 slash_slope := 1.7; 
408
409 % thickness of lines. quarter notes get 1.5slt width.
410 slash_thick# := 2/3*0.48staff_space#;
411
412 define_pixels(slash_thick);
413
414 def draw_slash(expr hwid_hash) =
415         set_char_box (0, staff_space# / slash_slope + hwid_hash,
416                         staff_space#/2 + stafflinethickness#/2,
417                         staff_space#/2 + stafflinethickness#/2);
418
419         clearxy;
420         pickup pencircle scaled blot_diameter;
421
422         bot y1 = - d;
423         top y2 = h;
424         lft x1 = 0;
425         lft x2 = staff_space / slash_slope;
426         
427         rt x3 = w;
428         y3 = y2;
429         y4 = y1;
430         x3- x2 = x4 - x1;
431
432         filldraw z1 --- z2 --- z3 --- z4 --- cycle;
433
434         if hwid_hash > 2 slash_thick#:
435                 save th;
436
437                 th = slash_thick - blot_diameter;
438                 y6 = y7;
439                 y5 = y8;
440                 y3 - y7 = th;
441                 y5 - y1 = th;
442                 z6 - z5 = whatever * (1,  slash_slope);
443                 z8 - z7 = whatever * (1,  slash_slope);
444
445                 z5  = z1 + whatever * (1,  slash_slope) + (th, 0);
446                 z8  = z4 + whatever * (1,  slash_slope) + (-th, 0);
447
448                 unfill
449                         z5 -- z6 -- z7 -- z8 -- cycle;
450         fi
451         labels (range 1 thru 10);
452
453
454 enddef;
455
456
457
458
459 fet_beginchar("Whole slashhead","0slash","wholeslashhead")
460         draw_slash(2 slash_thick# + 0.5 staff_space#);
461 fet_endchar;
462
463 fet_beginchar("Half slashhead","1slash","halfslashhead")
464         draw_slash(2 slash_thick# + 0.15 staff_space#);
465 fet_endchar;
466
467 fet_beginchar("Quart slashhead","2slash","quartslashhead")
468         draw_slash(slash_thick#);
469 fet_endchar;
470
471 % thick is the distance between the two parallel lines in the cross (distance between centres of lines)
472 def draw_cross(expr thick) =
473         pent := 1.2stafflinethickness;
474         pickup pencircle scaled pent;
475         % alfa is the slant of the lines (i.e. 1 means 45 degrees)
476         alfa := (2h-pent)/(w-pent);
477         % llen is the length of the little outer lines
478         % llen = thick / sin(2atan(alfa))
479         llen := thick/(ypart(dir(2angle(1,alfa))));
480         xa := llen/sqrt(1+alfa**2);
481         ya := xa*alfa;
482         xl := w/2-xa-pent/2;
483         yl := h-ya-pent/2;
484         save crz; path crz;
485         crz = (xa,0) -- (xa+xl,yl) -- (xl,yl+ya) -- (0,ya);
486         draw crz shifted(w/2,0);
487         draw crz xscaled -1 shifted(w/2,0);
488         draw crz yscaled -1 shifted(w/2,0);
489         draw crz scaled -1 shifted(w/2,0);
490 enddef;
491
492 fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead")
493         wid# := black_notehead_width#+4stafflinethickness#;
494         hei# := noteheight#+stafflinethickness#;
495         set_char_box(0, wid#,hei#/2,hei#/2);
496         draw_cross(3.75stafflinethickness);
497 fet_endchar;
498
499 fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead")
500         wid# := black_notehead_width#+2stafflinethickness#;
501         hei# := noteheight#+stafflinethickness#/2;
502         set_char_box(0, wid#,hei#/2,hei#/2);
503         draw_cross(3stafflinethickness);
504 fet_endchar;
505
506 fet_beginchar("Crossed notehead", "2cross", "crossedhead")
507         wid# := black_notehead_width#;
508         hei# := noteheight#;
509         set_char_box(0, wid#,hei#/2,hei#/2);
510         draw_cross(stafflinethickness/4);
511 fet_endchar;
512
513 fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead")
514         wid# := black_notehead_width#*sqrt(sqrt2);
515         hei# := noteheight#*sqrt(sqrt2);
516         set_char_box(0, wid#,hei#/2,hei#/2);
517         cthick := (1.2+1/4)*stafflinethickness;
518         cxr := w/2-cthick/2;
519         cyr := h-cthick/2;
520         pickup pencircle scaled cthick;
521         draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0);
522         xpos := cxr/sqrt2;
523         ypos := cyr/sqrt2;
524         draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
525         draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
526 fet_endchar;
527
528
529
530 fet_endgroup("noteheads");
531 define_pixels(black_notehead_width);