Typo.
[lilypond.git] / mf / feta-schrift.mf
blob70fd516c5893a6a1d77ff9eb8954a3932c57841d
1 % -*- Fundamental -*-  (emacs-20 mf mode mucks
2 % feta-schrift.mf --  implement scripts
4 % source file of the Feta (defintively not an abbreviation for Font-En-Tja)
5 % music font
7 % (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
8 %       Jan Nieuwenhuizen <janneke@gnu.org>
12 fet_begingroup ("scripts");
14 def draw_fermata =
15         save alpha, radius, crook_thinness, crook_fatness, dot_size;
16         save pat;
17         path pat;
19         % [Wanske] and some Baerenreiter editions
20         % suggest about 80 degrees instead of a half-circle
21         alpha := 10;
23         radius# = 1.25 staff_space#;
24         crook_thinness# = 1.5 linethickness#;
25         crook_fatness# = 0.25 staff_space# + 1.5 linethickness#;
27         radius# + crook_fatness# / 2 = h#;
28         radius# + crook_thinness# / 2 = w#;
30         set_char_box (w#, w#, crook_thinness# / 2, h#);
32         define_pixels (radius, crook_thinness, crook_fatness);
34         dot_size# = 8/6 crook_fatness#;
35         define_whole_blacker_pixels (dot_size);
37         penpos1 (crook_thinness, 0);
38         penpos2 (crook_fatness, -90);
39         z1 = (-radius, 0);
40         z2 = (0, radius);
42         pat := z2l{left}
43                .. z1l{dir (-alpha - 90)}
44                .. {dir (90 - alpha)}z1r
45                .. {right}z2r;
46         pat := pat
47                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
48                -- cycle;
49         fill pat;
51         pickup pencircle scaled dot_size;
52         x4 = 0;
53         bot y4 = vround (-crook_thinness / 2);
54         drawdot z4;
55 enddef;
58 fet_beginchar ("fermata up", "ufermata");
59         draw_fermata;
60         penlabels (1, 2, 4);
61 fet_endchar;
64 fet_beginchar ("fermata down", "dfermata");
65         draw_fermata;
66         y_mirror_char;
67 fet_endchar;
70 def draw_short_fermata =
71         save fat_factor, thinness, dot_size;
72         save left_dist, right_dist, se, ne;
73         pair left_dist, right_dist, se, ne;
75         set_char_box (staff_space#, staff_space#, 0, 2.2 staff_space#);
77         dot_size# = 0.266 staff_space# + 2.666 linethickness#;
78         define_whole_blacker_pixels (dot_size);
80         fat_factor = .11;
81         thinness = 1.5 linethickness;
83         pickup pencircle scaled thinness;
85         rt x2 = w;
86         lft x5 = -b;
87         bot y5 = 0;
88         top y3 = h;
89         y1 = y2 = y5;
91         x3 = 0;
92         z1 - z4 = whatever * (charwd, -charht);
93         z4 = fat_factor [z3, z5];
95         ne = unitvector (z3 - z5);
96         se = unitvector (z2 - z3);
98         left_dist = (ne rotated 90) * 0.5 thinness;
99         right_dist = (se rotated 90) * 0.5 thinness;
101         fill bot z5{right}
102              .. (z5 - left_dist){ne}
103              -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
104                   ((z1 - right_dist) -- (z4 - right_dist)))
105              -- (z1 - right_dist){se}
106              .. bot z1{right}
107              -- bot z2{right}
108              .. (z2 + right_dist){-se}
109              -- (z3 + right_dist){-se}
110              .. top z3
111              .. (z3 + left_dist){-ne}
112              -- (z5 + left_dist){-ne}
113              .. cycle;
115         pickup pencircle scaled dot_size;
117         x1 - 2 x6 = x2;
118         x6 := vround (x6);
119         bot y6 = -d;
121         drawdot z6;
122 enddef;
124 fet_beginchar ("short fermata up", "ushortfermata");
125         draw_short_fermata;
126         labels (1, 2, 3, 4, 5, 6);
127 fet_endchar;
130 fet_beginchar ("short fermata down", "dshortfermata");
131         draw_short_fermata;
132         xy_mirror_char;
133 fet_endchar;
136 def draw_long_fermata =
137         save stemthick, beamheight, dot_size, wd;
138         save pat;
139         path pat;
141         wd# = 2.5 staff_space#;
142         stemthick = hround (1.5 linethickness);
143         beamheight = 0.3 staff_space + linethickness;
144         dot_size# = 0.266 staff_space# + 2.666 * linethickness#;
145         define_pixels (wd);
146         define_whole_blacker_pixels (dot_size);
148         set_char_box (wd# / 2, wd# / 2, 0, 3/2 staff_space#);
150         pickup pencircle scaled blot_diameter;
152         top y1 = h;
153         lft x1 = -b;
155         pat := top z1{left}
156                .. {down}lft z1;
158         pickup pencircle scaled stemthick;
160         x2 = -b + stemthick;
161         y2 = h - beamheight;
162         lft x3 = -b;
163         bot y3 = -d;
165         pat := pat
166                -- lft z3
167                .. bot z3
168                .. rt z3
169                -- z2;
170         pat := pat
171                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
172                -- cycle;
174         fill pat;
176         pickup pencircle scaled dot_size;
178         x4 = 0;
179         bot y4 = -d;
181         drawdot z4;
182 enddef;
185 fet_beginchar ("long fermata up", "ulongfermata");
186         draw_long_fermata;
187         labels (1, 2, 3, 4);
188 fet_endchar;
191 fet_beginchar ("long fermata down", "dlongfermata");
192         draw_long_fermata;
193         y_mirror_char;
194 fet_endchar;
197 def draw_very_long_fermata =
198         save ibeamheight, obeamheight;
199         save ihwd, ohwd, iht, oht;      % inner/outer half_width/height
200         save stemthick, dot_size;
201         save opat, ipat;
202         path opat, ipat;
204         ihwd# = 1.0 staff_space#;
205         ohwd# = 1.5 staff_space#;
206         iht# = 0.9 staff_space#;
207         oht# = 1.6 staff_space#;
208         define_pixels (ihwd, ohwd, iht, oht)
210         stemthick = hround (1.5 linethickness);
211         ibeamheight# = 0.3 staff_space#;
212         obeamheight# = 0.5 staff_space#;
213         define_pixels (ibeamheight, obeamheight);
215         dot_size# = (iht# - ibeamheight#) * 8/10;
216         define_whole_blacker_pixels (dot_size);
218         set_char_box (ohwd#, ohwd#, 0, oht#);
220         pickup pencircle scaled blot_diameter;
222         top y1 = oht;
223         lft x1 = -ohwd;
224         top y11 = iht;
225         lft x11 = -ihwd;
227         opat := top z1{left}
228                 .. {down}lft z1;
229         ipat := top z11{left}
230                 .. {down}lft z11;
232         pickup pencircle scaled stemthick;
234         x2 = -ohwd + stemthick;
235         y2 = oht - obeamheight;
236         lft x3 = -ohwd;
237         bot y3 = 0;
238         x12 = -ihwd + stemthick;
239         y12 = iht - ibeamheight;
240         lft x13 = -ihwd;
241         bot y13 = 0;
243         opat := opat
244                 -- lft z3
245                 .. bot z3
246                 .. rt z3
247                 -- z2;
248         opat := opat
249                 -- reverse opat xscaled -1 shifted (-feta_eps, 0)
250                 -- cycle;
251         ipat := ipat
252                 -- lft z13
253                 .. bot z13
254                 .. rt z13
255                 -- z12;
256         ipat := ipat
257                 -- reverse ipat xscaled -1 shifted (-feta_eps, 0)
258                 -- cycle;
260         fill opat;
261         fill ipat;
263         pickup pencircle scaled dot_size;
265         x4 = 0;
266         bot y4 = -d;
268         drawdot z4;
269 enddef;
272 fet_beginchar ("very long fermata up", "uverylongfermata");
273         draw_very_long_fermata;
274         labels (1, 2, 3, 11, 12, 13, 4);
275 fet_endchar;
278 fet_beginchar ("very long fermata down", "dverylongfermata");
279         draw_very_long_fermata;
280         y_mirror_char;
281 fet_endchar;
285 % Thumbs are used in cello music.
286 % TODO : thumbs should look like the finger-font and should be placed in
287 % the same way in the score.
290 fet_beginchar ("Thumb", "thumb");
291         save thin, height, width, thick, depth;
292         height# = 5/4 width#;
293         height# = staff_space#;
294         depth# = 1.6 (height# / 2);
296         set_char_box (width# / 2, width# / 2, depth#, height# / 2);
298         define_pixels (height, width);
300         thin = .6 linethickness + 0.06 staff_space;
301         2 thick + 0.5 (height - 2 thin) = width;
303         penpos1 (thick, 0);
304         penpos2 (thin, 90);
305         penpos3 (thick, 180);
306         penpos4 (thin, 270);
307         z1r = (w, 0);
308         z2r = (0, h);
309         z3r = (-w, 0);
310         z4r = (0, -h);
312         penlabels (1, 2, 3, 4);
314         penstroke z1e{up}
315                   .. z2e{left}
316                   .. z3e{down}
317                   .. z4e{right}
318                   .. cycle;
320         save brush_thick;
321         y5 = -d + brush_thick / 2;
322         brush_thick = 0.9 thick;
323         x5 = 0;
325         labels (5);
327         draw_brush (z4r, 1.4 thin, z5, brush_thick);
328 fet_endchar;
332 % `\accent' is TeX reserved.
335 def draw_accent (expr bottom_left, top_right, thickness, diminish) =
336         save thinning_start;
337         thinning_start = 0.4;
338         pickup pencircle scaled thickness;
340         lft x1 = xpart bottom_left;
341         top y1 = ypart top_right;
342         lft x6 = xpart bottom_left;
343         bot y6 = ypart bottom_left;
345         rt z4 = (xpart top_right, (ypart top_right + ypart bottom_left) / 2);
346         x5 = x3 = thinning_start [xpart top_right, xpart bottom_left]
347                   - linethickness + 0.1 staff_space;
348         z3 = whatever [z1, z4];
349         z5 = whatever [z6, z4];
351         penpos1 (thickness, angle (z3 - z1) + 90);
352         penpos3 (thickness, angle (z3 - z1) + 90);
353         penpos4 (thickness, 90);
354         penpos5 (thickness, angle (z6 - z5) + 90);
355         penpos6 (thickness, angle (z6 - z5) + 90);
357         x4 - x7 = diminish * thickness;
358         y7 = y4;
360         fill z1l
361              -- z3l
362              -- z7
363              -- z5l
364              -- z6l
365              .. lft z6{down}
366              .. bot z6
367              .. z6r
368              -- z4l
369              ..tension 0.8.. rt z4
370              ..tension 0.8.. z4r
371              -- z1r
372              .. top z1
373              .. lft z1{down}
374              .. cycle;
375 enddef;
378 fet_beginchar ("> accent", "sforzato");
379         set_char_box (.9 staff_space#, .9 staff_space#,
380                       .5 staff_space#, .5 staff_space#);
382         draw_accent ((-w, -d), (w, h),
383                      0.05 staff_space + linethickness, 0.7);
384         penlabels (1, 3, 4, 5, 6);
385         labels (7);
386 fet_endchar;
389 fet_beginchar ("espr", "espr");
390         set_char_box (1.9 staff_space#, 1.9 staff_space#,
391                       .5 staff_space#, .5 staff_space#);
393         draw_accent ((w - 1.78 staff_space, -d), (w, h),
394                      0.05 staff_space + linethickness, 0.6);
395         addto currentpicture also currentpicture xscaled -1;
396 fet_endchar;
399 fet_beginchar ("staccato dot", "staccato");
400         save radius;
401         radius# = 0.20 * staff_space#;
402         define_whole_pixels (radius);
404         pickup pencircle scaled 2 radius;
405         drawdot (0, 0);
407         set_char_box (radius#, radius#, radius#, radius#);
408 fet_endchar;
411 def draw_staccatissimo =
412         save radius, height;
413         height# = .8 staff_space#;
414         radius# = linethickness# + .1 staff_space#;
415         define_whole_blacker_pixels (radius);
416         define_pixels (height);
418         draw_brush ((0, 0), linethickness, (0, height), 2 radius);
420         set_char_box (radius#, radius#,
421                       blot_diameter# / 2, height# + radius#);
422 enddef;
425 fet_beginchar ("staccatissimo/martellato up", "ustaccatissimo");
426         draw_staccatissimo;
427 fet_endchar;
430 fet_beginchar ("staccatissimo/martellato down", "dstaccatissimo");
431         draw_staccatissimo;
432         y_mirror_char;
433 fet_endchar;
436 fet_beginchar ("portato/single tenuto", "tenuto");
437         save thick;
438         thick# = 1.6 linethickness#;
439         define_whole_blacker_pixels (thick);
441         set_char_box (.6 staff_space#, .6 staff_space#,
442                       thick# / 2, thick# / 2);
444         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
445 fet_endchar;
448 def draw_portato =
449         save thick, dot_size;
450         thick# = 1.4 linethickness#;
451         dot_size# = 2.4 linethickness# + 0.08 staff_space#;
452         define_whole_blacker_pixels (thick, dot_size);
454         set_char_box (.6 staff_space#, .6 staff_space#,
455                       thick# / 2, .5 staff_space# + .5 dot_size#);
457         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
459         pickup pencircle scaled dot_size;
460         drawdot (0, h);
461 enddef;
464 fet_beginchar ("portato/tenuto with staccato", "uportato");
465         draw_portato;
466 fet_endchar;
469 fet_beginchar ("portato/tenuto with staccato", "dportato");
470         draw_portato;
471         y_mirror_char
472 fet_endchar;
475 def draw_marcato =
476         save fat_factor, thinness;
477         save left_dist, right_dist, ne, se;
478         pair left_dist, right_dist, ne, se;
480         set_char_box (staff_space# / 2, staff_space# / 2,
481                       0, 1.1 staff_space#);
483         fat_factor = .3;
484         thinness = linethickness;
486         pickup pencircle scaled thinness;
488         rt x2 = w;
489         lft x5 = -b;
490         bot y5 = 0;
491         top y3 = h;
492         y1 = y2 = y5;
494         x3 =0;
495         z1 - z4 = whatever * (charwd, -charht);
496         z4 = fat_factor [z3, z5];
498         ne = unitvector (z3 - z5);
499         se = unitvector (z2 - z3);
501         left_dist = (ne rotated 90) * 0.5 thinness;
502         right_dist = (se rotated 90) * 0.5 thinness;
504         fill bot z5{right}
505              .. (z5 - left_dist){ne}
506              -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
507                   ((z1 - right_dist) -- (z4 - right_dist)))
508              -- (z1 - right_dist){se}
509              .. bot z1{right}
510              -- bot z2{right}
511              .. (z2 + right_dist){-se}
512              -- (z3 + right_dist){-se}
513              .. top z3
514              .. (z3 + left_dist){-ne}
515              -- (z5 + left_dist){-ne}
516              .. cycle;
517 enddef;
520 fet_beginchar ("marcato up", "umarcato");
521         draw_marcato;
522         labels (1, 2, 3, 4, 5);
523 fet_endchar;
527 % The down marcato char (not very much used).
528 % Contrary to what some MF/TeX `gurus' believe
529 % it is *point*-symmetric with the "up" version
532 fet_beginchar ("marcato down", "dmarcato");
533         draw_marcato;
534         xy_mirror_char;
535 fet_endchar;
539 % used in french horn music todo
541 % TODO: too light at 20pt
544 fet_beginchar ("open (unstopped)", "open");
545         save thin, height, width, thick;
547         height# = 5/4 width#;
548         height# = staff_space#;
549         thin = .6 linethickness + 0.06 staff_space;
551         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
553         define_pixels (width, height);
555         2 thick + 0.6 (height - 2 thin) = width;
557         penpos1 (thick, 0);
558         penpos2 (thin, 90);
559         penpos3 (thick, 180);
560         penpos4 (thin, 270);
561         z1r = (w, 0);
562         z2r = (0, h);
563         z3r = (-w, 0);
564         z4r = (0, -h);
566         penlabels (1, 2, 3, 4);
568         penstroke z1e{up}
569                   .. z2e{left}
570                   .. z3e{down}
571                   .. z4e{right}
572                   .. cycle;
573 fet_endchar;
576 fet_beginchar ("plus (stopped)", "stopped");
577         save hthick, vthick, size, outer_hsize, outer_vsize;
579         hthick# = vthick# = 2 linethickness#;
580         size# = 1.1 staff_space#;
581         define_whole_blacker_pixels (vthick);
582         define_whole_vertical_blacker_pixels (hthick);
584         set_char_box (size# / 2, size# / 2, size# / 2, size# / 2);
586         outer_hsize = hround ((b + w - vthick) / 2);
587         outer_vsize = vround ((h + d - hthick) / 2);
588         w := b := (2 outer_hsize + vthick) / 2;
589         h := d := (2 outer_vsize + hthick) / 2;
591         draw_rounded_block ((-b, -d + outer_vsize),
592                             (w, -d + outer_vsize + hthick), hthick);
593         draw_rounded_block ((-b + outer_hsize, -d),
594                             (-b + outer_hsize + vthick, h), vthick);
595 fet_endchar;
598 fet_beginchar ("Upbow", "upbow");
599         save ht, wd, thick;
601         thick = 1.4 linethickness;
602         wd# = 1.3 staff_space#;
603         ht# = 1.6 wd#;
605         set_char_box (wd# / 2, wd# / 2, 0, ht#);
607         draw_accent ((-h, -w), (0, w), thick, 0.9);
608         currentpicture := currentpicture rotated -90;
609 fet_endchar;
612 fet_beginchar ("Downbow", "downbow");
613         save stemthick, beamheight, wd;
614         save pat;
615         path pat;
617         wd# = 1.5 staff_space#;
618         define_pixels (wd);
620         stemthick = hround (1.2 linethickness);
622         set_char_box (wd# / 2, wd# / 2, 0, 4/3 staff_space#);
624         beamheight = 4/10 h;
626         pickup pencircle scaled blot_diameter;
628         top y1 = h;
629         lft x1 = -b;
631         pat := top z1{left}
632                .. {down}lft z1;
634         pickup pencircle scaled stemthick;
636         x2 = -b + stemthick;
637         y2 = h - beamheight;
638         lft x3 = -b;
639         bot y3 = -d;
641         pat := pat
642                -- lft z3
643                .. bot z3
644                .. rt z3
645                -- z2;
646         pat := pat
647                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
648                -- cycle;
650         fill pat;
652         labels (1, 2, 3);
653 fet_endchar;
656 % Inspired by a computer-set version of Auf dem Strom by Baerenreiter.
659 def draw_turn =
660         save thin, thick, ball_diam, darkness;
661         save wd, ht, thick_nibangle, ball_nib_thick;
662         save turndir;
663         pair turndir;
665         wd# = 35/16 staff_space#;
666         ht# = 18/17 staff_space#;
667         darkness = 0.3 linethickness + 0.09 staff_space;
669         set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2);
671         thick_nibangle = 60;
672         thick = 3 darkness;
673         thin = darkness;
674         ball_nib_thick = 2.7 darkness;
675         ball_diam = ball_nib_thick + (h - ball_nib_thick) / 10;
677         x3l = w;
678         y3 = 0;
679         y4l = h;
680         x4 = x2;
681         x2l = w / 2;
682         y2l = -d;
683         z1 = (0,0);
685         penpos1 (1.1 thick, thick_nibangle);
686         penpos2 (thick, thick_nibangle);
687         penpos3 (thin, 180);
688         penpos4 (ball_nib_thick, -90);
690         path swoosh, ploop;
691         swoosh := z1l{curl 0}
692                   .. z2l
693                   .. z3l{up}
694                   .. {left}z4l
695                   -- z4r
696                   .. z3r{down}
697                   .. z2r{left};
698         fill swoosh
699              .. swoosh scaled -1 shifted (-feta_eps, -feta_eps)
700              .. cycle;
702         x5r = x4;
703         y5r = y4l - ball_diam / 2;
704         z6r = z5r;
706         penpos5 (1.6 ball_diam / 2, 10);
707         penpos6 (ball_diam / 2, 150);
709         ploop := z4l{left}
710                  .. z5l
711                  .. z6l
712                  -- cycle;
713         fill ploop;
714         fill ploop scaled -1 shifted (-feta_eps, -feta_eps);
715 enddef;
718 fet_beginchar ("Reverse turn", "reverseturn");
719         draw_turn;
720         currentpicture := currentpicture yscaled -1;
721 fet_endchar;
724 fet_beginchar ("Turn", "turn");
725         draw_turn;
726         penlabels (1, 2, 3, 4, 5, 6, 7);
727 fet_endchar;
731 % Inspired by a (by now) PD edition of Durand & C'ie edition of
732 % Saint-Saens' Celloconcerto no. 1
734 % FIXME take out hardcoded vars.
735 % FIXME the two loops on the `t' should be smoother (and the left one bigger).
736 % FIXME generic macros for serifs: top of the t and bottom of r
739 fet_beginchar ("Trill (`tr')", "trill");
740         save start_nib_angle, ascender_extra, ex, hair_thick, fatness;
741         save slant, t_fatness, r_fatness, kerning, t_overshoot;
742         save uitschieter, bulb_size, krul_ang;
743         save u, v;
745         ascender_extra# = 1/2 ex#;
746         ascender# = ascender_extra# + ex#;
747         ex# = 1.4 staff_space#;
748         kerning# = 0.6 ex#;
749         start_nib_angle = 20;
750         bulb_size = 0.8;
751         define_pixels (ex, ascender_extra, ascender, kerning);
753         t_overshoot = 0.03 ex;
754         fatness = 12/40 ex;
755         t_fatness = 0.78 fatness;
756         t_width =  1.9 t_fatness;
757         r_fatness = 0.78 fatness;
758         uitschieter = 0.48 ex;
759         hair_thick = linethickness;
760         r_flare = .5 hair_thick + 0.25 r_fatness;
761         r_width =  2 r_fatness + 0.25 kerning;
762         slant = .2;
764         local_copy (transform)(currenttransform);
765         currenttransform := currenttransform slanted slant
766                                              shifted (-staff_space, 0);
768         set_char_box (.85 staff_space#, .85 staff_space#, 0, ascender#);
770         y1 = ascender;
772         % try to position in such a way that the center is the visual
773         % center
775         x1l = 0.2 staff_space;
776         x1r - x1l = t_fatness;
777         penpos1 (start_nib_wid, start_nib_angle);
779         z2 = (x1, 7/18 ex);
780         penpos2 (start_nib_wid, start_nib_angle);
782         z3l = (x2l + 0.5 t_width, - t_overshoot);
784         z4l = (x2l + t_width, 0.23 ex);
785         penpos4 (whatever, 180);        % 200
786         x4l - x4r = hair_thick;
788         x3r = 0.5 [x4r, x2r];
789 %       1.7 [x3l, x3r] = x4r;
790         y3r - y3l = 0.6 t_fatness;
792         save krul_p;
793         path krul_p;
795         krul_ang = 32;
797         pickup pencircle scaled hair_thick;
799         z5 = (x2l + t_fatness / 2, 2/3 ex);
800         lft x6 = x2l - uitschieter;
801         y6 = y5;                                % - 1/20 ex;
802         z7 = z5 + whatever * dir krul_ang;
803         up_angle = krul_ang;                    % = angle (z7-z5)
804         x7 = 5/10 kerning + x5;
806         krul_p := z4{up}
807                   ..tension 0.98.. z5
808                   .. z6
809                   .. z5{z7 - z5}
810                   -- z7;
812         z4' = point 0.85 of krul_p;
813         penpos4' (hair_thick, angle (direction 0.85 of krul_p) + 90);
815         % the body of the `t' and the bottom loop
816         fill z1r{dir (angle (z1l - z1r) + 30)}
817              .. z1l{-dir (angle (z1r - z1l) - 45)}
818              -- z2l{down}
819              ..tension (1 + .5 slant).. z3l{right}
820              .. z4l{up}
821              .. z4'l{direction 0.85 of krul_p}
822              -- z4'r{-direction 0.85 of krul_p}
823              .. z4r{down}
824              .. z3r{left}
825              ..tension (1.5 + .7 slant).. z2r{up}
826              -- cycle;
828         z5' = point 1.1 of krul_p;
829         penpos5' (hair_thick, angle (direction 1.1 of krul_p) + 90);
830         z5'' = point 1.5 of krul_p;
831         penpos5'' (hair_thick, angle (direction 1.5 of krul_p) + 90);
832         z5''' = point 1.8 of krul_p;
833         penpos5''' (hair_thick, angle (direction 1.8 of krul_p) + 90);
834         z6 = point 2 of krul_p;
835         penpos6 (hair_thick, angle (direction 2 of krul_p) + 90);
836         z6' = point 2.3 of krul_p;
837         penpos6' (hair_thick, angle (direction 2.3 of krul_p) + 90);
838         z6'' = point 2.6 of krul_p;
839         penpos6'' (hair_thick, angle (direction 2.6 of krul_p) + 90);
840         z6''' = point 2.9 of krul_p;
841         penpos6''' (hair_thick, angle (direction 2.9 of krul_p) + 90);
842         penpos7 (hair_thick, up_angle + 90);
843         z7' = point 3.2 of krul_p;
844         penpos7' (hair_thick, angle (direction 3.2 of krul_p) + 90);
846         % the left loop
847         penstroke z5'e{direction 1.1 of krul_p}
848                   .. z5''e{direction 1.5 of krul_p}
849                   .. z5'''e{direction 1.8 of krul_p}
850                   .. z6e{direction 2 of krul_p}
851                   .. z6'e{direction 2.3 of krul_p}
852                   .. z6''e{direction 2.6 of krul_p}
853                   .. {direction 2.9 of krul_p}z6'''e;
855         y9 = 3/4 ex;
856         x9 = x1 + kerning;
857         penpos9 (r_fatness, 0);
859         x10 = x9;
860         y10 = -0.3 linethickness;
861         penpos10 (r_fatness, 0);
863         penpos11 (hair_thick, -4);
864         z11r = z9r;
866         z13l = (x9l + r_width, y11 - linethickness);
867         penpos13 (r_flare, 180);
869         z15 = z13r - (bulb_size * r_fatness, 0);
870         z14 = 0.5 [z13l, z15] - (0, bulb_size * r_fatness);
872         save before, after;
873         path before, after;
874         before := z13l{up}
875                   .. {down}z11l;
876         after := z9r{up}
877                  .. z7r{z7' - z7}
878                  -- z7'r;
879         (u, v) = before intersectiontimes after;
881         save before_bulb, after_bulb;
882         path before_bulb, after_bulb;
883         before_bulb := z9r{up}
884                        ..tension 0.94.. z13r{down};
885         after_bulb := z13l{up}
886                       ..tension 1.06.. z15{down};
887         (u_bulb, v_bulb) = before_bulb intersectiontimes after_bulb;
889         % the connection between `t' and `r', the body of the `r',
890         % and the bulb
891         fill z7'l
892              -- z7l{z7 - z7'}
893              .. z9l{down}
894              -- simple_serif (z10l, z10r, -30)
895              -- z9r{up}
896              .. subpath (0, u_bulb) of before_bulb
897              .. subpath (v_bulb, infinity) of after_bulb
898              .. z14
899              .. z13l{up}
900              .. subpath (0, u) of before
901              .. subpath (v, infinity) of after
902              -- cycle;
904         penlabels (range 1 thru 15);
905         penlabels (4', 5', 5'', 5''', 6', 6'', 6''', 7');
906 fet_endchar;
909 def draw_heel =
910         save radius, thickness;
911         save pat;
912         path pat;
914         radius# := .5 staff_space#;
916         set_char_box (radius#, radius#, radius#, 2/3 staff_space#);
918         thickness := hround (1.5 linethickness);
920         pickup pencircle scaled thickness;
922         rt x1 = b;
923         top y1 = h;
925         x2 =x1;
926         y2 = 0;
928         x3 = 0;
929         bot y3 = -d;
931         pat := top z3{right}
932                .. lft z2{up}
933                -- lft z1
934                .. top z1
935                .. rt z1
936                -- rt z2{down}
937                .. bot z3{left};
938         pat := pat
939                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
940                -- cycle;
941         fill pat;
942 enddef;
945 fet_beginchar ("left heel", "upedalheel");
946         draw_heel;
947         labels (1, 2, 3);
948 fet_endchar;
951 fet_beginchar ("right heel", "dpedalheel");
952         draw_heel;
953         y_mirror_char;
954 fet_endchar;
957 def draw_toe =
958         save ht, wd, thickness;
960         thickness := 1.5 linethickness;
961         ht# := 1.5 staff_space#;
962         wd# := 1/3 ht#;
963         define_pixels (ht, wd);
965         set_char_box (wd#, wd#, 0, ht#);
966         draw_accent ((-h, -w), (0, w), thickness, 0.9);
967         currentpicture := currentpicture rotated -90;
968 enddef;
971 fet_beginchar ("left toe", "upedaltoe");
972         draw_toe;
973 fet_endchar;
976 fet_beginchar ("right toe", "dpedaltoe");
977         draw_toe;
978         y_mirror_char;
979 fet_endchar;
982 fet_beginchar ("Flageolet", "flageolet");
983         save height, width, thickness, superness;
985         height# = 4/15 staffsize#;
986         width# = height#;
987         thickness# = blot_diameter#;
988         define_pixels (height, width);
989         define_whole_blacker_pixels (thickness);
991         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
993         penpos1 (thickness, 90);
994         penpos2 (thickness, 180);
995         penpos3 (thickness, 270);
996         penpos4 (thickness, 0);
998         x1 = 0;
999         y1r = h;
1000         x4r = w;
1001         x2r = -x4r;
1002         y2 = 0;
1003         y4 = y2;
1004         x3 = x1;
1005         y3r = -y1r;
1007         penlabels (1, 2, 3, 4);
1009         % mf doesn't handle pixel dropouts in outline objects, so we use
1010         % `draw' if not called by mpost
1011         if known miterlimit:
1012                 penstroke z1e
1013                           .. z2e
1014                           .. z3e
1015                           .. z4e
1016                           .. cycle;
1017         else:
1018                 pickup pencircle scaled thickness;
1019                 draw z1
1020                      .. z2
1021                      .. z3
1022                      .. z4
1023                      .. cycle;
1024         fi;
1025 fet_endchar;
1029 % TODO:  ARGRGHGH code dup.
1032 fet_beginchar ("Segno", "segno");
1033         save thin, thick, ball_diam, darkness, pointheight;
1034         save wd, ht, thick_nibangle, ball_nib_thick;
1035         save turndir;
1036         pair turndir;
1038         ht# = 3 staff_space#;
1039         wd# = 2 staff_space#;
1040         darkness = .08 staff_space + 0.4 linethickness;
1042         set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2);
1044         thick_nibangle = 30;
1045         thick = 3 darkness;
1046         thin = darkness;
1047         ball_nib_thick = 2.7 darkness;
1048         ball_diam = ball_nib_thick + (w - ball_nib_thick) / 10;
1049         pointheight = 2 linethickness;
1051         y3l = h;
1052         2 x3 = x2 + x4;
1053         x4 = 0;
1054         y4 = y2;
1055         y2l = .6 h;
1056         x2l = -b;
1057         z1 = (0, 0);
1059         penpos1 (thick, 2 thick_nibangle);
1060         penpos2 (thick, thick_nibangle);
1061         penpos3 (thin, -90);
1062         penpos4 (ball_nib_thick, 180 - thick_nibangle);
1064         save swoosh, ploop;
1065         path swoosh, ploop;
1067         swoosh := z1l{curl 0}
1068                   .. z2l
1069                   .. z3l{right}
1070                   .. {down}z4l
1071                   -- z4r
1072                   .. z3r{left}
1073                   .. z2r{down};
1074         fill swoosh
1075              .. (swoosh scaled -1)
1076              .. cycle;
1078         y5r = y4;
1079         x5r = x4l - ball_diam / 2;
1080         z6r = z5r;
1082         penpos5 (1.6 ball_diam / 2, 100);
1083         penpos6 (ball_diam / 2, 240);
1085         ploop := z4l{down}
1086                  .. z5l
1087                  .. z6l
1088                  -- cycle;
1089         fill ploop;
1090         fill ploop scaled -1;
1092         penpos7 (2 thin, 0);
1093         z7l = (-b, -d);
1094         penpos8 (2 thin, 0);
1095         z8r = (w, h);
1097         penstroke z7e
1098                   -- z8e;
1100         pickup pencircle scaled 2 thin;
1101         drawdot (-x2r, pointheight);
1102         drawdot (x2r, -pointheight);
1104         penlabels (range 1 thru 8);
1105 fet_endchar;
1108 fet_beginchar ("Coda", "coda");
1109         save stickout, thin, thick, codawidth, codaheight;
1111         stickout# = 0.35 staff_space#;
1112         codawidth# = 2/3 staff_space#;
1113         codaheight# = staff_space#;
1114         define_pixels (codawidth, codaheight);
1116         set_char_box (codawidth# + stickout#, codawidth# + stickout#,
1117                       codaheight# + stickout#, codaheight# + stickout#);
1119         thin = 1.2 linethickness;
1120         0.1 (codaheight - 2 thin) = (codawidth - 2 thick);
1122         penpos1 (thick, 0);
1123         penpos2 (thin, -90);
1124         penpos3 (thick, -180);
1125         penpos4 (thin, -270);
1127         x1l = -codawidth;
1128         y2l = codaheight;
1129         y1 = 0;
1130         x2 = 0;
1131         z3 = -z1;
1132         z4 = -z2;
1134         penlabels (1, 2, 3, 4);
1136         fill z1l{up}
1137              .. z2l{right}
1138              .. z3l{down}
1139              .. z4l{left}
1140              .. cycle;
1141         unfill z1r{up}
1142                .. z2r{right}
1143                .. z3r{down}
1144                .. z4r{left}
1145                .. cycle;
1147         draw_gridline ((0, -h), (0, h), thin);
1148         draw_gridline ((-w, 0), (w, 0), thin);
1149 fet_endchar;
1152 fet_beginchar ("Varied Coda", "varcoda");
1153         save thin, thick, codawidth, codaheight;
1154         thin# = 1.2 linethickness#;
1155         thick# = 1.0 linethickness# + 0.25 staff_space#;
1156         codawidth# = 2/3 staff_space#;
1157         codaheight# = staff_space#;
1158         define_pixels (thin, thick, codawidth, codaheight);
1160         set_char_box (codawidth# + thick#, codawidth# + thick#,
1161                       codaheight# + thick#, codaheight# + thick#);
1163         x1 = -codawidth + thick - .5 blot_diameter;
1164         y1 = y2 - thin;
1165         x2 = codawidth - thick + .5 blot_diameter;
1166         y2 = codaheight;
1167         draw_square_block (z1, z2);
1169         x3 = -codawidth;
1170         y3 = -codaheight;
1171         x4 = x3 + thick;
1172         y4 = y2;
1173         draw_block (z3, z4);
1175         labels (1, 2, 3, 4);
1177         addto currentpicture also currentpicture scaled -1;
1179         draw_gridline ((0, -h), (0, h), thin);
1180         draw_gridline ((-w, 0), (w, 0), thin);
1181 fet_endchar;
1184 def draw_comma =
1185         save alpha, thick, thin, ht;
1187         alpha := 35;
1188         thin# = 1.2 linethickness#;
1189         thick# = 3 linethickness#;
1190         ht# = .6 staff_space#;
1191         define_pixels (thin, thick, ht);
1193         set_char_box (0, .5 staff_space#, ht#, ht#);
1195         penpos1 (thick, alpha);
1196         penpos2 (thick, alpha + 90);
1197         penpos3 (thin, 180 - alpha);
1198         penpos4 (thin, 90 - alpha);
1200         x3r = 0;
1201         x1l = x3l;
1202         y2r = -y4l = h;
1203         z1 = z2;
1204         z3 = z4;
1206         fill z1l{dir (alpha + 90)}
1207              .. z2r{dir alpha}
1208              .. z1r{dir (alpha - 90)}
1209              .. z3l{dir (270 - alpha)}
1210              .. z4l{dir (180 - alpha)}
1211              .. z3r{dir (90-alpha)}
1212              .. cycle;
1213 enddef;
1216 fet_beginchar ("Right Comma", "rcomma");
1217         draw_comma;
1218         penlabels (1, 2, 3, 4);
1219 fet_endchar;
1222 fet_beginchar ("Left Comma", "lcomma");
1223         draw_comma;
1224         xy_mirror_char;
1225 fet_endchar;
1228 def draw_varcomma =
1229         save thick, thin, ht, wd, alpha;
1231         alpha := 35;
1232         thin# = 1.2 linethickness#;
1233         thick# = 3 linethickness#;
1234         ht# = .6 staff_space#;
1235         wd# = .25 staff_space#;
1236         define_pixels (thin, thick, ht, alpha);
1238         set_char_box (wd#, wd#, ht#, ht#);
1240         z1 = (-b, -d);
1241         z2 = (w, h);
1243         draw_brush (z1, thin, z2, thick);
1244 enddef;
1247 fet_beginchar ("Right Varied Comma", "rvarcomma");
1248         draw_varcomma;
1249         labels (1, 2);
1250 fet_endchar;
1253 fet_beginchar ("Left Varied Comma", "lvarcomma");
1254         draw_varcomma;
1255         xy_mirror_char;
1256 fet_endchar;
1259 thick# := 1/24 designsize;
1260 define_blacker_pixels (thick);
1262 rthin := 0.075 * staff_space + 0.5 linethickness;
1263 rthick := 2 thick + rthin;
1266 def draw_arpeggio =
1267         save alpha;
1268         save ne, nw, se, sw;
1269         save x, y;
1270         pair ne, nw, se, sw;
1272         alpha := -40;
1274         nw = dir (alpha + 180);
1275         ne = dir (alpha + 90);
1276         se = dir alpha;
1277         sw = dir (alpha - 90);
1279         penpos1 (rthin, alpha + 90);
1280         penpos2 (5/4 rthick, alpha);
1281         penpos3 (3/4 rthick, alpha);
1282         penpos4 (5/4 rthick, alpha);
1283         penpos5 (rthin, alpha + 90);
1285         z1 = (width / 2, height) - overshoot * se;
1286         z2 = 2 [z4, (width / 2, height / 2)];
1287         z3 = 1/2 [z2, z4];
1288         x4 = 2/8 staff_space;
1289         y4 = rthin;
1291         z5 = 2 [z1, (width / 2, height / 2)];
1292         z6 = z2l + 1/2 rthin * sw;
1293         z7 = z4l + 1/2 rthin * sw + 1/2 rthin * se;
1294         z8 = 2 [z6, (width / 2, height / 2)];
1295         z9 = 2 [z7, (width / 2, height / 2)];
1297         fill z1l{se}
1298              -- z6
1299              .. z3l
1300              .. z7{se}
1301              -- z5l
1302              .. z5r{nw}
1303              -- z8
1304              .. z3r
1305              .. z9{nw}
1306              -- z1r
1307              .. cycle;
1308 enddef;
1311 fet_beginchar ("Arpeggio", "arpeggio");
1312         save height, overshoot, width;
1313         height# = staff_space#;
1314         width# = 0.8 height#;
1315         overshoot# = 0.25 staff_space#;
1316         define_pixels (height, overshoot, width);
1318         set_char_box (0, width#, 0, height#);
1319         draw_arpeggio;
1320         penlabels (range 1 thru 9);
1322         draw_staff (-2, 2, 0.0);
1323 fet_endchar;
1327 % Extendable Trill symbol.
1328 % Not yet used
1329 % Rename me to Trill, rename Trill to Tr?
1332 fet_beginchar ("Trill_element", "trill_element");
1333         save height, overshoot;
1334         height# = staff_space#;
1335         width# = 0.8 height#;
1336         overshoot# = 0.25 staff_space#;
1337         define_pixels (height, overshoot, width);
1339         set_char_box (0, height#, 0, width#);
1340         draw_arpeggio;
1342         currentpicture := currentpicture shifted -(width / 2, height / 2);
1343         currentpicture := currentpicture rotated 90;
1344         currentpicture := currentpicture shifted (height / 2, width / 2);
1345 fet_endchar;
1349 % Arpeggio arrow by Chris Jackson <chris@fluffhouse.org.uk>
1352 def draw_arpeggio_arrow =
1353         save thinness, height, width, overshoot;
1354         save nw, ne, se, sw;
1355         save alpha;
1356         save before_left, before_right, after_left, after_right;
1357         save u_left, v_left, u_right, v_right;
1358         pair nw, ne, se, sw;
1359         path before_left, before_right, after_left, after_right;
1361         height# = staff_space#;
1362         width# = 0.8 height#;
1363         overshoot# = 0.25 staff_space#;
1364         define_pixels (height, overshoot, width);
1366         set_char_box (0, width#, 0, height#);
1368         alpha := -40;
1369         nw = dir (alpha + 180);
1370         ne = dir (alpha + 90);
1371         se = dir alpha;
1372         sw = dir (alpha - 90);
1374         penpos1 (rthin, alpha + 90);
1375         penpos2 (5/4 rthick, alpha);
1376         penpos3 (5/4 rthick, 0);
1378         z1 = (width / 2, height) - overshoot * se; % numbering is consistent
1379                                                    % with the arpeggio symbol
1380         z2 = 2 [z4, (width / 2, height / 2)];
1381         z3 = (0.5 width, 0.5 height);
1382         z4 = (0.25 staff_space, rthin);
1383         z6 = z2l + 1/2 rthin * sw;
1384         z9 = (width / 2, height) + overshoot * se;
1386         pickup pencircle scaled vround (0.5 rthin);
1388         bot z10 = (0.5 w, 0);
1389         lft z11 = (0.5 w - hround (0.8 w), 0.8 h);
1390         rt z12 = (0.5 w + hround (0.8 w), 0.8 h);
1392         before_left := z1l
1393                        -- z6{z6 - z1l}
1394                        .. {down}z3l;
1395         after_left := (z3 + (0, -0.25 rthin / cosd (angle (nw))))
1396                       -- (z11 + 0.25 rthin * ne);
1397         (u_left, v_left) = before_left intersectiontimes after_left;
1399         before_right := (z12 + 0.25 rthin * nw)
1400                         -- (z3 + (0, -0.25 rthin / cosd (angle (nw))));
1401         after_right := z3r{up}
1402                        .. z9{z1r - z9}
1403                        -- z1r;
1404         (u_right, v_right) = before_right intersectiontimes after_right;
1406         fill subpath (0, u_left) of before_left
1407              .. subpath (v_left, infinity) of after_left
1408              .. top z11
1409              .. lft z11
1410              .. {dir -50}(z11 + 0.25 rthin * sw)
1411              .. (z10 + 0.25 rthin * sw){dir -70}
1412              .. bot z10
1413              .. {dir 70}(z10 + 0.25 rthin * se)
1414              .. (z12 + 0.25 rthin * se){dir 50}
1415              .. rt z12
1416              .. top z12
1417              .. subpath (0, u_right) of before_right
1418              .. subpath (v_right, infinity) of after_right
1419              .. cycle;
1421         % mf doesn't handle pixel dropouts in outline objects, so we use
1422         % `draw' if not called by mpost
1423         if not known miterlimit:
1424                 pickup pencircle scaled 0.7 rthin;
1425                 draw z1
1426                      -- (z9 + 0.5 rthin * dir (alpha - 90));
1427         fi;
1428 enddef;
1431 fet_beginchar ("Arpeggio arrow down", "arpeggio.arrow.M1");
1432         draw_arpeggio_arrow;
1433         penlabels (range 1 thru 12);
1434 fet_endchar;
1437 fet_beginchar ("Arpeggio arrow up", "arpeggio.arrow.1");
1438         draw_arpeggio_arrow;
1439         currentpicture := currentpicture scaled -1
1440                                          shifted (w - feta_eps, h - feta_eps);
1441 fet_endchar;
1444 % Hmm
1445 input feta-slag;
1449 % Railroad tracks.  We define two variants of these -- both as slightly
1450 % tapered, comma-shaped curves and as two straight parallel slashes.
1453 fet_beginchar ("Curved caesura", "caesura.curved");
1454         save slant, space_between, clearance;
1455         save alpha, pat;
1456         save botthick, topthick;
1457         save krom;
1458         path pat;
1460         botthick = 1.5 linethickness;
1461         topthick = 2.5 linethickness;
1463         pickup pencircle scaled botthick;
1465         slant = 3.5;
1466         space_between# = 0.6 staff_space#;
1467         clearance# = 0.2 staff_space#;
1468         height# = 1.2 staff_space#;
1470         set_char_box (0, 2.0 staff_space#,
1471                       staff_space# - clearance#, height#);
1472         define_pixels (clearance, height);
1473         define_whole_pixels (space_between);
1475         bot y1 = -d;
1476         top y2 = h;
1478         lft x1 = 0;
1479         x2 = (y2 - y1) / slant;
1481         krom = 10;
1483         alpha = angle (z2 - z1);
1484         penpos1 (botthick, alpha - krom);
1485         penpos3 (botthick, alpha - krom + 90);
1487         penpos2 (topthick, alpha + krom);
1488         penpos4 (topthick, alpha + krom + 90);
1490         z3 = z1;
1491         z4 = z2;
1493         penlabels (1, 2, 3, 4);
1495         pat := z3r{(z1r - z1l)}
1496                .. z4r{z2r-z2l}
1497                .. z2r{z4l-z4r}
1498                .. z4l{z2l-z2r}
1499                .. z3l{z1l-z1r}
1500                .. z1l{z3r-z3l}
1501                .. cycle;
1502         fill pat;
1503         fill pat shifted (space_between, 0);
1504 fet_endchar;
1507 fet_beginchar ("Straight caesura", "caesura.straight");
1508         save slant, space_between, clearance;
1509         save thick, ne, pat;
1510         path pat;
1511         pair ne;
1513         slant = 2.0;
1514         thick = 2.88 linethickness;
1516         space_between# = 0.56 staff_space#;
1517         clearance# = 0.2 staff_space#;
1519         set_char_box (0, 2.0 staff_space#,
1520                       staff_space# - clearance#, 1.2 staff_space#);
1521         define_whole_pixels (space_between);
1523         x1 = 0;
1524         x2 = x1 + thick;
1525         y1 = y2 = -d;
1527         x3 = x4 + thick;
1528         x4 = x1 + (h + d) / slant;
1529         y3 = y4 = h;
1531         ne = unitvector (z4 - z1);
1532         
1533         z1a = z1 + blot_diameter * ne;
1534         z1b = z1 + blot_diameter * right;
1535         z2a = z2 + blot_diameter * ne;
1536         z2b = z2 + blot_diameter * left;
1538         z3a = z3 - blot_diameter * ne;
1539         z3b = z3 + blot_diameter * left;
1540         z4a = z4 - blot_diameter * ne;
1541         z4b = z4 + blot_diameter * right;
1543         pat = z1a{-ne}
1544               .. {right}z1b
1545               -- z2b{right}
1546               .. {ne}z2a
1547               -- z3a{ne}
1548               .. {left}z3b
1549               -- z4b{left}
1550               .. {-ne}z4a
1551               -- cycle;
1553         fill pat;
1554         fill pat shifted (space_between, 0);
1556         labels(range 1 thru 4);
1557         labels(1a, 1b, 2a, 2b, 3a, 3b, 4a, 4b);
1558 fet_endchar;
1560 fet_endgroup ("scripts");