]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-bolletjes.mf
* scm/output-lib.scm (note-head-style->attachment-coordinates):
[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 attachment_y;
35         save p;
36         path p;
37
38         p := superellipse ((ellipsidity, 0), (-slant * ellipsidity, 1.0),
39                         (- ellipsidity, 0), (slant * ellipsidity, -1.0), superness);
40
41         p := p rotated tilt;
42
43         save top_point, right_point;
44         pair top_point, right_point;
45
46         top_point := directionpoint left of p;
47         right_point := directionpoint up of p;
48
49         save scaling, width, height;
50
51         scaling# = noteheight# /(2 ypart (top_point));
52         width# := 2 xpart (right_point) * scaling#;
53
54         define_pixels (width, scaling);
55         
56         set_char_box (0, width#, noteheight#/2, noteheight#/2);
57
58         % attachment Y
59         charwy := ypart (right_point) * scaling#;
60         charwx := xpart (right_point) * scaling#;
61
62         p := p scaled scaling shifted (width/2, 0) ;
63         if test_outlines = 1:
64                 pickup pencircle scaled 1 ; draw p;
65         else:
66                 fill p;
67         fi;
68 enddef;
69
70
71 def undraw_inside_ellipse (expr ellipsidity, tilt, superness, clearance,
72                         center) =
73 begingroup
74         save p;
75         path p;
76
77         p := superellipse ((ellipsidity, 0), (0, 1.0),
78                         (- ellipsidity, 0), (0, -1.0), superness);
79
80         p := p rotated tilt;
81
82         save top_point, right_point;
83         pair top_point, right_point;
84
85         top_point := directionpoint left of p;
86         right_point := directionpoint up of p;
87
88         save height, scaling;
89
90         height# = staff_space# + stafflinethickness# - clearance;
91         scaling# = height# /(2 ypart (top_point));
92
93         define_pixels (scaling);
94         p := (p scaled scaling) shifted center;
95
96         if test_outlines = 1:
97                 pickup pencircle scaled 1; draw p;
98         else:
99                 unfill p;
100         fi
101 endgroup;
102 enddef;
103
104
105
106
107
108 %
109 % dimensions aren't entirely right.
110 %
111 fet_beginchar ("Brevis notehead", "-1", "brevishead");
112         save stemthick, fudge;
113         define_pixels (stemthick);
114         fudge = blot_diameter /2;
115         stemthick# = 2 stafflinethickness#;
116
117         draw_outside_ellipse (1.80, 0, 0.707, 0);
118         undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#,
119                                 (w /2, 0));
120
121         pickup pencircle scaled stemthick;
122
123         bot y1 = -d;
124         top y2 = h;
125         rt x1 - fudge = 0;
126         x1 = x2;
127
128         fudge + lft x3 = w;
129         x4 = x3;
130         y4 = y2;
131         y3 = y1;
132
133         draw_gridline(z1,z2,stemthick);
134         draw_gridline(z3,z4,stemthick);
135
136 fet_endchar;
137
138
139
140 % whole note
141 % Wanske, p.38
142 fet_beginchar("Whole notehead", "0", "wholehead")
143         draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0, 0.707, 0);
144         undraw_inside_ellipse (1.30, 125 - puff_up_factor *10,
145                         0.68, 2 stafflinethickness#,
146                         (w /2, 0));
147
148 %       draw_staff_outline (-2, 2, 0.5);
149
150 fet_endchar;
151
152
153 % half note
154 % Wanske, p.39
155 fet_beginchar("Half notehead", "1", "halfhead")
156         draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17);
157         undraw_inside_ellipse (3.25, 33, 0.81,
158                 2.5 stafflinethickness#, (w/2, 0));
159
160 fet_endchar;
161         
162 % quarter note
163 % Wanske p.38
164 fet_beginchar("Quart notehead", "2", "quarthead")
165         draw_outside_ellipse (1.54 - puff_up_factor / 2.0, 32, 0.707, 0);
166         black_notehead_width# := charwd;
167 fet_endchar;
168
169
170
171
172 fet_beginchar("Whole diamondhead", "0diamond", "wholediamondhead")
173         draw_outside_ellipse (1.80, 0, 0.495, 0);
174         undraw_inside_ellipse (1.30, 125, 0.6,
175                         .4 staff_space# +  stafflinethickness#,
176                                 (w /2, 0));
177
178 fet_endchar;
179
180 % half note
181 % Wanske, p.39
182 fet_beginchar("Half diamondhead", "1diamond", 
183         "halfdiamondhead")
184
185         draw_outside_ellipse (1.50, 34, 0.49, 0.17);
186         undraw_inside_ellipse (3.5, 33, 0.80,
187                 .3 staff_space# + 1.5 stafflinethickness#, (w/2, 0));
188
189 fet_endchar;
190
191 % quarter note
192 % Wanske p.38
193 fet_beginchar("Quart diamondheadh", "2diamondh", "diamondheadh")
194         draw_outside_ellipse (1.80, 35, 0.495, -0.25);
195 fet_endchar;
196
197
198 save pen_thick;
199 pen_thick# = stafflinethickness#  + .1 staff_space#;
200 define_pixels(pen_thick);
201
202
203 begingroup;
204
205
206 def def_triangle_old =
207         save triangle,kern; path triangle;
208         kern = 1/3(x2-x1);
209         z2 = z1 rotated 120;
210         z3 = z1 rotated 240;
211         z12 = caveness[.5[z1,z2],z3];
212         z23 = z12 rotated 120;
213         z31 = z12 rotated 240;
214         triangle = z1 .. z12 .. z2 ..
215                     z2 .. z23 .. z3 ..
216                     z3 .. z31 .. z1 ..
217                     cycle;
218         triangle := triangle shifted (-x1+pent/2-kern,0) xscaled xs;
219         pickup pencircle scaled pent xscaled xs;
220         hei = max(y1,-y2)+pent/2; 
221         %set_char_box(-kern*xs*fac, ((x3-x1)*fac+pent#)*xs,hei*fac,hei*fac);
222         set_char_box(0, ((x3-x1-kern)*fac+pent#)*xs,hei*fac,hei*fac);
223 enddef;
224
225
226 def def_triangle =
227         save triangle,kern; path triangle;
228         save left_point, height, width;
229         pair exact_left_point;
230
231         exact_left_point := llap# * dir (90 + tilt);
232         height# = max (ypart exact_left_point,
233                         -ypart  (exact_left_point rotated 120)) + pen_thick#/2;
234
235         kern# = 1/3 xpart (exact_left_point - (exact_left_point rotated 120));
236         width# = xpart (-exact_left_point + (exact_left_point rotated 240));
237         define_pixels (kern);   
238         z1 = (hround_pixels (xpart exact_left_point), vround_pixels  (ypart exact_left_point));
239         z2 = z1 rotated 120;
240         z3 = z1 rotated 240;
241
242         z12 = caveness[.5[z1,z2],z3];
243         z23 = z12 rotated 120;
244         z31 = z12 rotated 240;
245         triangle = z1 .. z12 .. z2 ..
246                     z2 .. z23 .. z3 ..
247                     z3 .. z31 .. z1 ..
248                     cycle;
249         triangle := triangle shifted (-x1+pen_thick/2-kern,0) xscaled xs;
250         pickup pencircle scaled pen_thick xscaled xs;
251 %       labels(1,2,12,23,31,3);
252         set_char_box(0, width# - kern#+ pen_thick#, height#, height#);
253 enddef;
254
255 fet_beginchar("Whole trianglehead", "0triangle", "wholetrianglehead")
256         save hei,xs;
257         save llap;
258         save tilt;
259
260         tilt = 40;
261         llap# = 3/4noteheight#;
262
263         xs = 1.5;
264         caveness:=0.1;
265         def_triangle;
266         draw triangle;
267 fet_endchar;
268
269 fet_beginchar("Half trianglehead", "1triangle", "halftrianglehead")
270         save hei,xs;
271         save llap;
272         save tilt;
273
274         tilt = 40;
275         llap# = 2/3noteheight#;
276         xs = 1.2;
277         caveness:=0.1;
278         def_triangle;
279         draw triangle;
280 fet_endchar;
281
282 fet_beginchar("Quart trianglehead", "2triangle", "trianglehead")
283         save hei,xs;
284         save llap;
285         save tilt;
286         tilt = 40;
287         llap# = 2/3noteheight#;
288         xs = 1.0;
289         caveness:=0.1;
290         def_triangle;
291         filldraw triangle;
292 fet_endchar;
293
294 endgroup;
295
296 %%% Editable values:
297
298
299 % slope of slash. From scm/grob-description.scm. How to auto-copy?
300 slash_slope := 1.7; 
301
302 % thickness of lines. quarter notes get 1.5slt width.
303 slash_thick# := 2/3*0.48staff_space#;
304
305 define_pixels(slash_thick);
306
307 def draw_slash(expr hwid_hash) =
308         set_char_box (0, staff_space# / slash_slope + hwid_hash,
309                         staff_space#/2 + stafflinethickness#/2,
310                         staff_space#/2 + stafflinethickness#/2);
311
312         charwx := charwd;
313         charwy := charht;
314
315         clearxy;
316         pickup pencircle scaled blot_diameter;
317
318         bot y1 = - d;
319         top y2 = h;
320         lft x1 = 0;
321         lft x2 = staff_space / slash_slope;
322         
323         rt x3 = w;
324         y3 = y2;
325         y4 = y1;
326         x3- x2 = x4 - x1;
327
328         filldraw z1 --- z2 --- z3 --- z4 --- cycle;
329
330         if hwid_hash > 2 slash_thick#:
331                 save th;
332
333                 th = slash_thick - blot_diameter;
334                 y6 = y7;
335                 y5 = y8;
336                 y3 - y7 = th;
337                 y5 - y1 = th;
338                 z6 - z5 = whatever * (1,  slash_slope);
339                 z8 - z7 = whatever * (1,  slash_slope);
340
341                 z5  = z1 + whatever * (1,  slash_slope) + (th, 0);
342                 z8  = z4 + whatever * (1,  slash_slope) + (-th, 0);
343
344                 unfill
345                         z5 -- z6 -- z7 -- z8 -- cycle;
346         fi
347         labels (range 1 thru 10);
348
349
350 enddef;
351
352
353
354
355 fet_beginchar("Whole slashhead","0slash","wholeslashhead")
356         draw_slash(2 slash_thick# + 0.5 staff_space#);
357 fet_endchar;
358
359 fet_beginchar("Half slashhead","1slash","halfslashhead")
360         draw_slash(2 slash_thick# + 0.15 staff_space#);
361 fet_endchar;
362
363 fet_beginchar("Quart slashhead","2slash","quartslashhead")
364         draw_slash(slash_thick#);
365 fet_endchar;
366
367 % thick is the distance between the two parallel lines in the cross (distance between centres of lines)
368 def draw_cross(expr thick) =
369         save pent, slant, ne_dir;
370         pair ne_dir;
371         save crz; path crz;
372
373         pent# := 1.2stafflinethickness#;
374         define_pixels (pent);
375         pickup pencircle scaled pent;
376
377         top y3 = h;
378         ne_dir := (1, (2 h -pent)/(w - pent));
379         rt x4 = w/2;
380         y5 = 0;
381         z4 - z5 = whatever * ne_dir;
382         x6 = 0;
383         z6 - z3 = whatever * ne_dir;
384         z3 - z4 = whatever * (ne_dir yscaled -1);
385
386         z1 = (0, charht - 1.5 pent#);
387         y2 = 0;
388         z2 = z1 + whatever * (ne_dir yscaled -1);
389         z7 = z2 + whatever * ne_dir;
390         x7 = charwd/2 - .5 pent#;
391         top y6 = h - pent;
392
393         
394         labels (1,2,3,4,5,6);
395
396         crz = (z6 -- z3 -- z4 -- z5) ;
397         draw crz shifted(w/2,0);
398         draw crz xscaled -1 shifted(w/2,0);
399         draw crz yscaled -1 shifted(w/2,0);
400         draw crz scaled -1 shifted(w/2,0);
401
402         charwx := charwd;
403         charwy := y7;
404 enddef;
405
406 fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead")
407         wid# := black_notehead_width#+4stafflinethickness#;
408         hei# := noteheight#+stafflinethickness#;
409         set_char_box(0, wid#,hei#/2,hei#/2);
410         
411         draw_cross(3.75stafflinethickness);
412 fet_endchar;
413
414 fet_beginchar("Half Crossed notehead", "1cross", "halfcrossedhead")
415         wid# := black_notehead_width#+2stafflinethickness#;
416         hei# := noteheight#+stafflinethickness#/2;
417         set_char_box(0, wid#,hei#/2,hei#/2);
418         draw_cross(3stafflinethickness);
419 fet_endchar;
420
421 fet_beginchar("Crossed notehead", "2cross", "crossedhead")
422         wid# := black_notehead_width#;
423         hei# := noteheight#;
424         set_char_box(0, wid#,hei#/2,hei#/2);
425         draw_cross(stafflinethickness/4);
426 fet_endchar;
427
428 fet_beginchar("X-Circled notehead", "2xcircle", "xcircledhead")
429         wid# := black_notehead_width#*sqrt(sqrt2);
430         hei# := noteheight#*sqrt(sqrt2);
431         set_char_box(0, wid#,hei#/2,hei#/2);
432         cthick := (1.2+1/4)*stafflinethickness;
433         cxr := w/2-cthick/2;
434         cyr := h-cthick/2;
435         pickup pencircle scaled cthick;
436         draw fullcircle xscaled 2cxr yscaled 2cyr shifted (w/2,0);
437         xpos := cxr/sqrt2;
438         ypos := cyr/sqrt2;
439         draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
440         draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
441
442         charwx := 3/4 charwd ; 
443         charwy := 1/4 charwd ; 
444 fet_endchar;
445
446
447
448 fet_endgroup("noteheads");
449 define_pixels(black_notehead_width);