]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-bolletjes.mf
rewrite note head MF code.
[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 test_outlines := 0;
23
24 noteheight#:=staff_space#+ (1 + overdone_heads) *stafflinethickness#;
25
26
27 %
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.)
30 %
31
32 def draw_outside_ellipse (expr ellipsidity, tilt, superness,
33                         slant) =
34         save p;
35         path p;
36
37         p := superellipse ((ellipsidity, 0), (-slant * ellipsidity, 1.0),
38                         (- ellipsidity, 0), (slant * ellipsidity, -1.0), superness);
39
40         p := p rotated tilt;
41
42         save top_point, right_point;
43         pair top_point, right_point;
44
45         top_point := directionpoint left of p;
46         right_point := directionpoint up of p;
47
48         save scaling, width, height;
49
50         scaling# = noteheight# /(2 ypart (top_point));
51         width# := 2 xpart (right_point) * scaling#;
52
53         define_pixels (width, scaling);
54         
55         set_char_box (0, width#, noteheight#/2, noteheight#/2);
56
57         p := p scaled scaling shifted (width/2, 0) ;
58         if test_outlines = 1:
59                 pickup pencircle scaled 1 ; draw p;
60         else:
61                 fill p;
62         fi;
63 enddef;
64
65
66 def undraw_inside_ellipse (expr ellipsidity, tilt, superness, clearance,
67                         center) =
68 begingroup
69         save p;
70         path p;
71
72         p := superellipse ((ellipsidity, 0), (0, 1.0),
73                         (- ellipsidity, 0), (0, -1.0), superness);
74
75         p := p rotated tilt;
76
77         save top_point, right_point;
78         pair top_point, right_point;
79
80         top_point := directionpoint left of p;
81         right_point := directionpoint up of p;
82
83         save height, scaling;
84
85         height# = staff_space# + stafflinethickness# - clearance;
86         scaling# = height# /(2 ypart (top_point));
87
88         define_pixels (scaling);
89         p := (p scaled scaling) shifted center;
90
91         if test_outlines = 1:
92                 pickup pencircle scaled 1; draw p;
93         else:
94                 unfill p;
95         fi
96 endgroup;
97 enddef;
98
99
100
101
102
103 %
104 % dimensions aren't entirely right.
105 %
106 fet_beginchar ("Brevis notehead", "-1", "brevishead");
107         save stemthick, fudge;
108         define_pixels (stemthick);
109         fudge = blot_diameter /2;
110         stemthick# = 2 stafflinethickness#;
111
112         draw_outside_ellipse (1.80, 0, 0.707, 0);
113         undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#,
114                                 (w /2, 0));
115
116         pickup pencircle scaled stemthick;
117
118         bot y1 = -d;
119         top y2 = h;
120         rt x1 - fudge = 0;
121         x1 = x2;
122
123         fudge + lft x3 = w;
124         x4 = x3;
125         y4 = y2;
126         y3 = y1;
127
128         draw_gridline(z1,z2,stemthick);
129         draw_gridline(z3,z4,stemthick);
130
131 fet_endchar;
132
133
134
135 % whole note
136 % Wanske, p.38
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#,
141                         (w /2, 0));
142
143 %       draw_staff_outline (-2, 2, 0.5);
144
145 fet_endchar;
146
147
148 % half note
149 % Wanske, p.39
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));
154
155 fet_endchar;
156         
157 % quarter note
158 % Wanske p.38
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;
162 fet_endchar;
163
164
165
166
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#,
171                                 (w /2, 0));
172
173 fet_endchar;
174
175 % half note
176 % Wanske, p.39
177 fet_beginchar("Half diamondhead", "1diamond", 
178         "halfdiamondhead")
179
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));
183
184 fet_endchar;
185
186 % quarter note
187 % Wanske p.38
188 fet_beginchar("Quart diamondheadh", "2diamondh", "diamondheadh")
189         draw_outside_ellipse (1.80, 35, 0.495, -0.25);
190 fet_endchar;
191
192
193 save pen_thick;
194 pen_thick# = stafflinethickness#  + .1 staff_space#;
195 define_pixels(pen_thick);
196
197
198 begingroup;
199
200
201 def def_triangle_old =
202         save triangle,kern; path triangle;
203         kern = 1/3(x2-x1);
204         z2 = z1 rotated 120;
205         z3 = z1 rotated 240;
206         z12 = caveness[.5[z1,z2],z3];
207         z23 = z12 rotated 120;
208         z31 = z12 rotated 240;
209         triangle = z1 .. z12 .. z2 ..
210                     z2 .. z23 .. z3 ..
211                     z3 .. z31 .. z1 ..
212                     cycle;
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);
218 enddef;
219
220
221 def def_triangle =
222         save triangle,kern; path triangle;
223         save left_point, height, width;
224         pair exact_left_point;
225
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;
229
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));
234         z2 = z1 rotated 120;
235         z3 = z1 rotated 240;
236
237         z12 = caveness[.5[z1,z2],z3];
238         z23 = z12 rotated 120;
239         z31 = z12 rotated 240;
240         triangle = z1 .. z12 .. z2 ..
241                     z2 .. z23 .. z3 ..
242                     z3 .. z31 .. z1 ..
243                     cycle;
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#);
248 enddef;
249
250 fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead")
251         save hei,xs;
252         save llap;
253         save tilt;
254
255         tilt = 40;
256         llap# = 3/4noteheight#;
257
258         xs = 1.5;
259         caveness:=0.1;
260         def_triangle;
261         draw triangle;
262 fet_endchar;
263
264 fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead")
265         save hei,xs;
266         save llap;
267         save tilt;
268
269         tilt = 40;
270         llap# = 2/3noteheight#;
271         xs = 1.2;
272         caveness:=0.1;
273         def_triangle;
274         draw triangle;
275 fet_endchar;
276
277 fet_beginchar("Quart trianglehead", "2triangle", "trianglehead")
278         save hei,xs;
279         save llap;
280         save tilt;
281         tilt = 40;
282         llap# = 2/3noteheight#;
283         xs = 1.0;
284         caveness:=0.1;
285         def_triangle;
286         filldraw triangle;
287 fet_endchar;
288
289 endgroup;
290
291 %%% Editable values:
292
293
294 % slope of slash. From scm/grob-description.scm. How to auto-copy?
295 slash_slope := 1.7; 
296
297 % thickness of lines. quarter notes get 1.5slt width.
298 slash_thick# := 2/3*0.48staff_space#;
299
300 define_pixels(slash_thick);
301
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);
306
307         clearxy;
308         pickup pencircle scaled blot_diameter;
309
310         bot y1 = - d;
311         top y2 = h;
312         lft x1 = 0;
313         lft x2 = staff_space / slash_slope;
314         
315         rt x3 = w;
316         y3 = y2;
317         y4 = y1;
318         x3- x2 = x4 - x1;
319
320         filldraw z1 --- z2 --- z3 --- z4 --- cycle;
321
322         if hwid_hash > 2 slash_thick#:
323                 save th;
324
325                 th = slash_thick - blot_diameter;
326                 y6 = y7;
327                 y5 = y8;
328                 y3 - y7 = th;
329                 y5 - y1 = th;
330                 z6 - z5 = whatever * (1,  slash_slope);
331                 z8 - z7 = whatever * (1,  slash_slope);
332
333                 z5  = z1 + whatever * (1,  slash_slope) + (th, 0);
334                 z8  = z4 + whatever * (1,  slash_slope) + (-th, 0);
335
336                 unfill
337                         z5 -- z6 -- z7 -- z8 -- cycle;
338         fi
339         labels (range 1 thru 10);
340
341
342 enddef;
343
344
345
346
347 fet_beginchar("Whole slashhead","0slash","wholeslashhead")
348         draw_slash(2 slash_thick# + 0.5 staff_space#);
349 fet_endchar;
350
351 fet_beginchar("Half slashhead","1slash","halfslashhead")
352         draw_slash(2 slash_thick# + 0.15 staff_space#);
353 fet_endchar;
354
355 fet_beginchar("Quart slashhead","2slash","quartslashhead")
356         draw_slash(slash_thick#);
357 fet_endchar;
358
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);
369         ya := xa*alfa;
370         xl := w/2-xa-pent/2;
371         yl := h-ya-pent/2;
372         save crz; path crz;
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);
378 enddef;
379
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);
385 fet_endchar;
386
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);
392 fet_endchar;
393
394 fet_beginchar("Crossed notehead", "2cross", "crossedhead")
395         wid# := black_notehead_width#;
396         hei# := noteheight#;
397         set_char_box(0, wid#,hei#/2,hei#/2);
398         draw_cross(stafflinethickness/4);
399 fet_endchar;
400
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;
406         cxr := w/2-cthick/2;
407         cyr := h-cthick/2;
408         pickup pencircle scaled cthick;
409         draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0);
410         xpos := cxr/sqrt2;
411         ypos := cyr/sqrt2;
412         draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
413         draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
414 fet_endchar;
415
416
417
418 fet_endgroup("noteheads");
419 define_pixels(black_notehead_width);