Nitpick: ly:spanner-bound grob name slur -> spanner.
[lilypond.git] / mf / feta-din-code.mf
blob809227de450e8462e7fa94c16141e6e10da27586
1 % feta-din-code.mf -- implement dynamic signs
3 % part of LilyPond's pretty-but-neat music font
5 % source file of the Feta (not the Font-En-Tja) music font
7 % (c) 1997--2009 Jan Nieuwenhuizen <janneke@gnu.org>
10 ex# := (dynamic_design_size / 2.4) * pt#;
11 descender# := 0.5 ex#;
12 ascender# := 0.72 ex#;
13 staffspace# := 1.75 / 2.0 * ex#;
14 horizontal_space# := .66 ex#;
16 font_x_height ex#;
17 font_normal_space horizontal_space#;
19 define_pixels (staffspace, linethickness, ex, descender, ascender);
23 % TODO: blot diameter should be fixed, not scalable.
26 save serif_thick, med_thick, bottom_blot;
28 serif_thick# = 1.1 linethickness#;
29 define_blacker_pixels (serif_thick);
31 med_thick = round (1.5 linethickness);
32 bottom_blot = 1.3 serif_thick;
35 code := 32;
37 fet_beginchar ("Space", "space");
38         set_char_box (0, horizontal_space#, 0, ex#);
39 fet_endchar;
43 % Couldn't find many z examples.  This one is losely inspired
44 % by a sfz from Mueller Etuden fuer Horn (Edition Hofmeister).
47 code := 121;
49 fet_beginchar ("dynamic z", "z");
50         save thin_thick, top_narrow, over_shoot;
51         save bot_thick;
53         set_char_box (0, .98 ex#, 0, 0.9 ex#);
55         thin_thick = serif_thick;
56         top_narrow = thin_thick;
57         top_overshoot = .8 serif_thick;
58         top_thick = .3 h;
59         bot_thick = .2 ex;
60         bot_overshoot = serif_thick;
62         x0 = top_narrow;
63         y0 = .9 [y1r, y1l];
65         penpos1 (top_thick, 80);
66         y1l = .72 h;
67         x1r = .34 ex;
69         x2 = .66 ex;
70         y2 = y1r - top_overshoot;
72         y3 = h - .7 thin_thick;
73         x3 = w - .6 top_narrow - .5 thin_thick;
74         y4 = .5 thin_thick;
75         x4 = .5 thin_thick;
77         penpos3 (thin_thick, angle (z3 - z4) + 90);
78         penpos4 (thin_thick, angle (z3 - z4) + 90);
80         penpos5 (bot_thick, 70);
81         x5l =.25 ex;
82         y5l = .4 bot_overshoot;
84         penpos6 (3/2 bot_thick, 70);
85         y6l = -bot_overshoot;
86         x6 = w - 3 top_narrow;
88         x7 = w;
89         y7 = .82 [y8r, y6r];
91         penpos8 (thin_thick, 20);
92         x8r = w - .35 top_narrow;
93         y8r = .45 h;
95         penlabels (range 0 thru 8);
97 %       pickup pencircle scaled 1;
99 %       draw
100         fill z0{down}
101              .. z1l{dir (10)}
102              .. simple_serif (z3l, z3r, 90)
103              .. z2{left}
104              .. z1r{left}
105              ..tension 1.2.. cycle;
107 %       draw
108         fill z3l
109              -- z3r
110              -- z4r
111              -- z4l
112              -- cycle;
114 %       draw
115         fill simple_serif (z4r, z4l, 90)
116              .. z5l{right}
117              .. z6l{right}
118              .. z7{up}
119              .. simple_serif (z8r, z8l, 90)
120              .. z6r{left}
121              .. z5r{left}
122              .. cycle;
123 fet_endchar;
126 % forte f, grabbed from Ed Breitkopf Mozart horn concerto 3.
128 % NOTES:
130 % * the bulbs are open
132 % * blotting around the serif
134 % TODO: insert blots around the serif
137 slant_angle = 20;
138 code := 101;
140 fet_beginchar ("dynamic f", "f");
141         save left_angle, right_angle;
142         save serif_length, serif_eccentricity;
143         save f_thick;
144         save bulb_thick, bulb_diam, fill_up;
145         save slant;
146         save p;
147         path p;
149         set_char_box (0, 1.1 ex#, descender#, ex# + ascender#);
151         bulb_diam = 7.5 / 40 ex;
152         bulb_thick = 8.5 / 40 ex;
153         fill_up = 1.5 serif_thick;
154         left_angle = slant_angle - 6;
155         right_angle = slant_angle - 3;
156         f_thick = 7/16 ex;
157         serif_length = 0.96 ex;
158         serif_eccentricity = 0.01 ex;
160         % z1 is the `base point'
161         z1 = (0.2 ex, -serif_thick);
163         penpos2 (f_thick, 0);
164         y2 = y1 + ex;
165         z2l = z1 + whatever * dir (90 - left_angle);
167         penpos3 (med_thick, -90);
168         y3l = y1 + ex + ascender;
169         x3l = x1 + ex;
171         penpos4 (bulb_thick, -20);
172         z3r = whatever [z4r, z4l];
174         x4l - x3l = 1/10 ex;
176         penpos5 (bulb_thick, -45);
177         x5r = 0.1 [x4l, x4r];
178         y5l = y4l - bulb_diam;
180         z6 = z2r + whatever * dir (90 - right_angle);
181         y6 = y1 + 3/8 ex;
183         penpos7 (med_thick, -90);
184         x7 = x1 - 1/4 ex;
185         y7r = y1 -descender;
187         penpos8 (bulb_thick, 160);
188         x8l = x7l - 1/10 ex;
190         z7l = whatever [z8r, z8l];
192         penpos9 (bulb_thick, 135);
193         x9r = 0.1 [x8l, x8r];
194         y9l = y8l + bulb_diam;
196         labels (1, 6, 9);
197         penlabels (2, 3, 4, 5, 7, 8, 9);
199 %       pickup pencircle scaled 1;
201 %       draw
202         fill z1
203              -- z2l{z2l - z1}
204              ..tension 1.1.. z3l{right}
205              .. z4r{down}
206              .. z5r{left}
207              .. z5l{up}
208              ..tension 0.8.. z4l{up}
209              .. z3r{left}
210              ..tension 1.1.. z2r{z6 - z2r}
211              -- z6{z6 - z2r}
212              ..tension 1.25.. z7r{left}
213              .. z8r{up}
214              .. z9r{right}
215              .. z9l{down}
216              ..tension 0.8.. z8l{down}
217              .. z7l{right}
218              .. {z2l - z1}cycle;
220         x13 - x14 = serif_length;
221         y13 = y14;
222         y14 = y2;
223         0.5 [x13, x14] = x2 + serif_eccentricity;
225         draw_rounded_block (z14 - (0, 0.7 serif_thick),
226                             z13 + (0, 0.7 serif_thick),
227                             1.4 serif_thick);
229         labels (13, 14);
230 fet_endchar;
234 % Notes:
236 % - The `s' is trapezoidal (i.e., narrower at the top).
238 % - The white space is differently shaped at the top (the bulb's inner
239 %   curve is filled up).
241 % - Less heavy than the `f' and `p' signs.
244 code := 114;
246 fet_beginchar ("dynamic s", "s");
247         save left_angle, right_angle;
248         save s_thick, s_thin;
249         save bulb_diam, bulb_len;
250         save over_shoot;
251         save base_point;
252         pair base_point;
254         set_char_box (0, 17/24 ex#, 0, ex#);
256         over_shoot = 0;                 % .2 serif_thick;
257         bulb_diam = 11/70 ex;
258         bulb_len = 1.0 bulb_diam;
259         left_angle = slant_angle - 2;
260         right_angle = slant_angle - 11;
261         s_thick = 16/70 ex;
262         s_thin = serif_thick;
264         base_point = (0, 0);
266         penpos1 (bulb_diam, -45);
267         z1 = 0.35 [z2l, z2r] + bulb_len * dir (45);
269         penpos2 (bulb_diam, -25);
270         y2l = 0.845 [y7r, y3r];
271         z2l = base_point + whatever * dir (90 - left_angle);
273         penpos3 (s_thin, 100);
274         x3l = 1/2 w;
275         y3l = ypart base_point - over_shoot;
277         penpos4 (s_thick, 25);
278         y4l = y1r;
279         z4r = base_point + (w, 0) + whatever * dir (90 - right_angle);
281         penpos5 (s_thick, 40);
282         z5 = z3l + whatever * dir (90 - right_angle);
283         y5 = 0.48 [y7r, y3r];
285         penpos6 (s_thick, 25);
286         z6l = base_point + whatever * dir (90 - left_angle);
287         y6r = y9l;
289         penpos7 (.9 s_thin, 110);
290         z7l = 0.45 [z6r, z8l] + whatever * dir (90 - left_angle);
291         y7r = h + over_shoot;
293         penpos8 (.9 bulb_diam, -25);
294         z8 = .6 [z4l, z4r] + whatever * dir (90 - right_angle);
295         y8r = 0.23 [y7r, y3r];
297         penpos9 (.9 bulb_diam, -45);
298         z9 = .4 [z8r, z8l] + .9 bulb_len * dir (-135);
300         penlabels (range 1 thru 9);
302 %       pickup pencircle scaled 1;
304 %       draw
305         fill z2l{down}
306              .. z3l{right}
307              .. z4r{up}
308              .. z5r
309              .. z6r{up}
310              .. z7l{right}
311         %    .. z8l{down}
312              .. z9l{dir (-125)}
313              .. z9r{right}
314              .. z7r{left}
315              .. z6l{down}
316              .. z5l
317              .. z4l{down}
318              .. z3r{left}
319              .. z2r{up}
320              .. z1r{up}
321              .. z1l{left}
322              .. cycle;
323 fet_endchar;
326 % for `p' and `m'
328 save slant;
329 slant := ypart (dir (slant_angle));
333 % Piano `p', grabbed from Ed Breitkopf Mozart horn concerto 3.
335 % Notes:
337 % * There is no dishing in the serif (but we do it anyway).
339 % * The cheek is a little fatter than the stem.
341 % * The slant is extreme: 20 degrees.
343 % * The twiddle (what's-it-called) is a slightly darker than the serif.
345 % * The hole in the cheek has a straight right side.
347 % * Corners are filled up.
350 code := 111;
352 fet_beginchar ("dynamic p", "p")
353         % TODO: w really is 13/12 ex
354         %       but should do kerning
356         save twiddle_thick, stem_thick, cheek_thick, cheek_width;
357         save fill_up, straigh_len;
358         save serif, dishing_angle, p, tmp;
359         save cheek_medium, left_serif_protrude, right_serif_protrude;
360         save lower_overshoot;
361         save blot_t, corner_t;
362         path serif, p;
363         pair tmp, updir;
365         set_char_box (0, 15/12 ex#, descender#, 1.0 ex#);
367         twiddle_thick = med_thick;
368         cheek_medium = 1/6 ex;
370         dishing_angle = 5;
371         fill_up = 1.5 serif_thick;
372         straigh_len = 0.5 ex;
373         lower_overshoot = .3 serif_thick;
375         stem_thick = 2/6 ex;
376         cheek_thick = 13/32 ex;
377         cheek_width = 0.72 ex;
378         left_serif_protrude = 18/60 ex;
379         right_serif_protrude = 15/60 ex;
381         currenttransform := currenttransform slanted slant;
383         penpos1 (twiddle_thick, -slant - 5);
384         penpos2 (cheek_medium, 90 - slant);
385         penpos3 (cheek_medium, 90 - slant);
387         x4r - x4l = cheek_thick;
389         penpos4 (whatever, 0);
390         penpos5 (whatever, -38);
391         penpos6 (stem_thick, 0);
392         penpos17 (straigh_len, 90 - slant);
394         whatever [z17l, z17r] =  z4l;
395         y17 = 7/16 ex;
396         x6l = 0;
397         y6l = -descender + serif_thick / 2;
398         z1l = z6l - whatever * dir (110);
399         y1r = 0.5 ex;
400         y2r = ex;
401         z7 = whatever * up + z6l;
402         y7 = 43/60 ex;
403         z2l = whatever * up + 0.3 [z7, z1r];
404         y8 = 0.9 [y7, y2l];
405         z8 = 2/3 [z6l, z6r] + whatever * up;
406         y3r = ex;
407         z3l = 0.58 [(stem_thick, -descender),
408                     (stem_thick + cheek_width - cheek_thick, -descender)]
409               + whatever * up;
410         y4r = .38 ex;
411         z4r = whatever * up + (stem_thick + cheek_width, -descender);
412         z5l = whatever * up + z3l;
413         y5r = -lower_overshoot;
414         y5l = y5r + cheek_medium * ypart dir (55);
415         z9 = z6r + whatever * up;
416         y9 = .2 [y5l, y5r];
418         p := z2r{right}
419              .. {dir (-60)}z8{dir 60}
420              .. z3r{right}
421              .. z4r{down}
422              ..tension 1.1.. z5r{left}
423              .. {curl 1}z9
424              -- z6r
425              -- z6l
426              -- z7{up}
427              .. z2l{left}
428              ..tension 1.2.. simple_serif (z1r, z1l, -90)
429              .. cycle;
431         blot_t := 0.13;
432         corner_t := xpart (p intersectiontimes z9);
434 %       pickup pencircle scaled 1;
436 %       draw
437         fill subpath (0, corner_t - 2 blot_t) of p
438              .. subpath (corner_t + blot_t, length p) of p
439              .. cycle;
441         y12 = 0.5 ex;
442         z12 = z6r + whatever * up;
444         unfill z17l
445                ..tension 1.5.. z17r
446                .. z3l{left}
447                ..tension 1.05.. z12{down}
448                ..tension 1.05.. z5l{right}
449                .. cycle;
451         penlabels (1, 2, 3, 4, 5, 6, 17);
452         labels (7, 8, 9);
454         pickup pencircle scaled serif_thick;
456         lft x11 = -left_serif_protrude;
457         rt x10 = stem_thick + right_serif_protrude;
458         bot y10 = bot y11 = -descender;
460         z15 = z6l + up * fill_up;
461         z16 = z6r + up * 1.2 fill_up;
463         % Since pens are not affected by currenttransform we directly
464         % transform the necessary points, then simulating the pen with
465         % an outline while using the identity transformation.
467         forsuffixes $ = 7, 10, 11, 15, 16:
468                 tmp := z$ transformed currenttransform;
469                 x$ := xpart tmp;
470                 y$ := ypart tmp;
471         endfor;
473         currenttransform := identity;
475         updir = z7 - z15;
477         serif := simple_serif (z10, z11, dishing_angle);
479         penpos10 (serif_thick, -dishing_angle - 90);
480         penpos11 (serif_thick, dishing_angle - 90);
481         penpos13 (serif_thick, angle (direction 0.05 of serif) + 90);
482         penpos14 (serif_thick, angle (direction 0.85 of serif) + 90);
484         z13 = point 0.05 of serif;
485         z14 = point 0.85 of serif;
487         penlabels (10, 11, 13, 14);
488         labels (15, 16);
490 %       draw
491         fill z15{-updir}
492              .. z14l{direction 0.85 of serif}
493              .. z11l{-dir (dishing_angle)}
494              .. z11r{dir (dishing_angle)}
495              .. z14r{-direction 0.85 of serif}
496              .. z13r{-direction 0.05 of serif}
497              .. z10r{dir (-dishing_angle)}
498              .. z10l{-dir (-dishing_angle)}
499              .. z13l{direction 0.05 of serif}
500              .. z16{updir}
501              -- cycle;
502 fet_endchar;
506 % NOTES:
508 % * Right stem is fatter and more straight than the left two stems.
510 % * The twiddle at the left is similar to the `p' twiddle.
512 % * The bottoms of the stems are blotted.
515 % This is cut & paste programming.  Somehow three `i' shapes in two
516 % characters (`p' and `m') -- doesn't seem worth the trouble of writing
517 % a macro.
520 code := 108;
522 fet_beginchar ("dynamic m", "m");
523         save i_thick, i_angle, i_twiddle_thick;
524         save i_twiddle_start_angle, i_twiddle_start_y;
525         save i_twiddle_end_angle, i_left_space;
526         save idir, center, right_ending;
527         save overshoot;
528         save p;
529         pair center, idir, right_ending;
530         path p;
532         set_char_box (0, 1.5 ex#, 0, 1.0 ex#);
534         % should share code with p for twiddle.
536         overshoot = .25 serif_thick;
537         i_thick := 21/80 ex;
538         i_twiddle_thick = 1.2 serif_thick;
539         i_twiddle_start_y = 8/16 ex;
540         i_twiddle_start_angle = 0;
541         i_twiddle_end_angle := 35;
543         center = (0, 0);
545         currenttransform := currenttransform slanted slant;
547         i_angle := 0;
548         idir := dir (90 - i_angle);
549         i_left_space = 16/80 ex;
551         penpos1 (i_twiddle_thick, -i_twiddle_start_angle);
552         y1 = i_twiddle_start_y;
553         z1r = center - (i_left_space, 0) + whatever * idir;
555         y2l = ex + overshoot;
556         z2l = .08 [z3l, z3r] + whatever * idir;
557         z2r = 5/8 [z1r, z3l] + whatever * idir;
558         y2r = y5l + 1/9 ex;
559         z2 = 1/2 [z2l, z2r];
561         penpos3 (i_thick, 0);
562         y3 = 0.5 bottom_blot + ypart center;
563         z3l = center + whatever * idir;
565         penpos4 (i_thick - bottom_blot, 0);
566         y4 = ypart center;
567         z4 - z3 = whatever * idir;
569         penpos5 (i_thick, 0);
570         z5 = z4 + whatever * idir;
571         y5 = 55/80 ex;
573         fill simple_serif (z1l, z1r, 90)
574              ..tension 1.2.. z2r{right}
575              .. z5l{z3 - z5}
576              -- z3l{z3 - z5}
577              .. z4l{right}
578              -- z4r{right}
579              .. z3r{z5 - z3}
580              -- z5r{z5 - z3}
581              ..tension 1.2.. z2l{left}
582              .. cycle;
584         right_ending := z5r;
585         penlabels (1, 2, 3, 4, 5);
587         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589         clearxy;
591         i_angle := -3.2;
592         idir := dir (90 - i_angle);
593         i_left_space := 14/80 ex;
595         penpos1 (serif_thick, -i_twiddle_start_angle);
596         z1r = right_ending;
598         y2l = ex+ overshoot;
599         z2l = .08 [z3l, z3r] + whatever * idir;
600         z2r = 5/8 [z1r, z3l] + whatever * idir;
601         y2r = y5l + 1/9 ex;
602         z2 = 1/2 [z2l, z2r];
604         penpos3 (i_thick, 0);
605         y3 = 0.5 bottom_blot + ypart center;
606         z3l = z5l + whatever * idir;
608         penpos4 (i_thick - bottom_blot, 0);
609         y4 = ypart center;
610         z4 - z3 = whatever * idir;
612         penpos5 (i_thick, 0);
613         z5l = right_ending + (i_left_space, 0);
615         fill simple_serif (z1l, z1r, 90)
616              ..tension 1.05.. z2r{right}
617              .. z5l{z3 - z5}
618              -- z3l
619              ..  z4l{right}
620              -- z4r{right}
621              .. z3r{z5 - z3}
622              -- z5r{z5 - z3}
623              ..tension 1.2.. z2l{left}
624              .. cycle;
626         right_ending := z5r;
627         penlabels (1, 2, 3, 4, 5);
629         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
631         clearxy;
633         i_thick := 23/80 ex;
634         i_angle := -6;
635         idir := dir (90 - i_angle);
636         i_left_space := 14/80 ex;
638         penpos1 (serif_thick, -i_twiddle_start_angle);
639         z1r = right_ending;
641         y2l = ex + overshoot;
642         z2l = .08 [z3l, z3r] + whatever * idir;
643         z2r = 5/8 [z1r, z3l] + whatever * idir;
644         y2r = y5l + 1/9 ex;
645         z2 = 1/2 [z2l, z2r];
647         penpos3 (whatever, 20);
648         y3l = 1/8 ex + ypart center;
649         z3l = z7l + whatever * idir;
650         z3r = z7r + whatever * idir;
652         penpos5 (whatever, 10);
653         z5l = right_ending + (i_left_space, 0);
654         z5r = z7r + whatever * idir;
656         penpos6 (serif_thick, -i_twiddle_end_angle);
657         y6l = 23/80 ex + ypart center;
658         z6l = 1.6 [z3l, z3r] + whatever * idir;
660         penpos7 (i_thick, 0);
661         y7 = 0;
662         z7l = z5l + whatever * idir;
664         z8 = z7 - (0, overshoot);
666         fill simple_serif (z1l, z1r, 90)
667              ..tension 1.05.. z2r{right}
668              .. z5l{z3 - z5}
669              -- z3l{z3 - z5}
670              .. z8{right}
671              .. simple_serif (z6r, z6l, 90)
672              ..tension 0.85.. z3r{z5 - z3}
673              -- z5r{z5 - z3}
674              ..tension 1.2.. z2l{left}
675              .. cycle;
677         penlabels (range 1 thru 8);
678 fet_endchar;
681 code := 113;
683 fet_beginchar ("dynamic r", "r");
684         save base_point, stem_thick, bulb_diam;
685         save twiddle_thick, attach_len, overshoot, taille;
686         pair base_point;
688         set_char_box (0, .75 ex#, 0, ex#);
690         stem_thick =.26 ex;
691         bulb_diam = .30 ex;
692         twiddle_thick = 1.1 serif_thick;
693         overshoot = .5 serif_thick;
694         taille = -0.3 serif_thick;
695         attach_len + bulb_diam / 2 + stem_thick = w;
698         base_point = (0, 0);
700         currenttransform := identity slanted ypart (dir (15));
702         penpos1 (stem_thick, 0);
703         x1l = 0;
704         y1l = .5 bottom_blot;
706         penpos2 (stem_thick, 0);
707         x2l = x1l;
708         y2l - y1l = 36/47 ex;
710         penpos3 (twiddle_thick, -20);
711         x3r = x2l - .2 ex;
712         y3 = .77  ex;
714         x4l = -0.1 [x1l, x1r];
715         y4l = ex + overshoot;
716         x4r = 0.62 [x3r, x2l];
717         y4r = 0.5 [y4l, y2l];
719         penpos5 (whatever, -74);
720         y5l - y5r =  bulb_diam;
721         y5l = ex + overshoot;
722         x5 = x2r + attach_len;
724         penpos6 (bulb_diam, 0);
725         z6 = z5;
727 %       z7 = z6l + taille * dir (180);
728         z7 = z6 + .4 * bulb_diam * dir (-125);
730         z8 = 9/10 [z1r, z2r];
732         x9 = 0.15 [x1r, x1l];
733         y9 = y4l - .12 ex;
735         penpos10 (stem_thick - bottom_blot, 0);
736         x10 = x1;
737         y10 = 0;
739 %       pickup pencircle scaled 1;
741 %       draw 
742         fill z1r{down}
743              .. z10r{left}
744              -- z10l{left}
745              .. z1l{up}
746              -- z2l{up}
747              .. z4r{left}
748              ..tension 1.2.. {down}simple_serif (z3r, z3l,-90){up}
749              ..tension 0.95.. z4l
750              .. {curl 1}z9{curl 1}
751              .. z5l
752              .. z6r{dir (-80)}
753              .. z5r{left}
754              .. z7
755              .. z6l
756              ..tension 1.2.. z8{down}
757              -- cycle;
759         penlabels (range 1 thru 10);
760 fet_endchar;
763 %%% KERNING
765 ligtable "m":
766         "p" kern 0.2 ex#,
767         "f" kern -0.1 ex#;
769 ligtable "f":
770         "f" kern -0.13 ex#;
772 ligtable "r":
773         "f" kern 0.1 ex#;
776 %% notes from old dyn code.
778 % `f' obviously has a _lot_ bigger slant than `p' (see Wanske p.239).
779 % However; perhaps we need two f symbols:
780 %  - a super-slanted one used in `f', `mf', `sfz', `sf'
781 %  - a more normal-slanted in `ff', `fff', `fp', `fp' (see Wanske p.241)
783 % Looking at professionally typeset music reveals that typesetters
784 % are somewhat unsure about slanting in `mf', `fp', `sfz'
786 % `f' and `p' (in any combination) are a lot (factor two) fatter than
787 % `s', `m', and `z'.  Sometimes the `m' and `z' are a bit fatter than
788 % `s'.
790 % Chester, Breitkopf suggest smaller sizes of these other glyphs,
791 % using the x-height as reference point.