]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-schrift.mf
Prepare glyph shapes for mf2pt1 conversion.
[lilypond.git] / mf / feta-schrift.mf
1 % -*- Fundamental -*-  (emacs-20 mf mode mucks
2 % feta-schrift.mf --  implement scripts
3 %
4 % source file of the Feta (defintively not an abbreviation for Font-En-Tja)
5 % music font
6 %
7 % (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 %       Jan Nieuwenhuizen <janneke@gnu.org>
9 %
10
11
12 fet_begingroup ("scripts")
13
14 def draw_fermata =
15         save alpha, radius, crook_thinness, crook_fatness, dot_radius;
16         save pat;
17         path pat;
18
19         % [Wanske] and some Baerenreiter editions
20         % suggest about 80 degrees instead of a half-circle
21         alpha := 10;
22
23         radius# = 1.25 staff_space#;
24         crook_thinness# = 1.5 linethickness#;
25         crook_fatness# = 0.25 staff_space# + 1.5 linethickness#;
26
27         radius# + crook_fatness# / 2 = h#;
28         radius# + crook_thinness# / 2 = w#;
29
30         set_char_box (w#, w#, crook_thinness# / 2, h#);
31
32         define_pixels (radius, crook_thinness, crook_fatness);
33         dot_radius = round (4/6 crook_fatness);
34
35         penpos1 (crook_thinness, 0);
36         penpos2 (crook_fatness, -90);
37         z1 = (-radius, 0);
38         z2 = (0, radius);
39
40         pat := z2l{left}
41                .. z1l{dir (-alpha - 90)}
42                .. {dir (90 - alpha)}z1r
43                .. {right}z2r;
44         pat := pat
45                & reverse pat xscaled -1
46                & cycle;
47         fill pat;
48
49         pickup pencircle scaled 2 dot_radius;
50         x4 = 0;
51         bot y4 = -crook_thinness / 2;
52         drawdot z4;
53 enddef;
54
55
56 fet_beginchar ("fermata up", "ufermata")
57         draw_fermata;
58         penlabels (1, 2, 4);
59 fet_endchar;
60
61
62 fet_beginchar ("fermata down", "dfermata")
63         draw_fermata;
64         y_mirror_char;
65 fet_endchar;
66
67
68 def draw_short_fermata =
69         save fat_factor, thinness, dot_radius;
70         save left_dist, right_dist;
71         pair left_dist, right_dist;
72
73         set_char_box (staff_space#, staff_space#, 0, 2.2 staff_space#);
74
75         dot_radius# = 0.133 staff_space# + 1.33 linethickness#;
76         define_pixels (dot_radius)
77
78         fat_factor = .11;
79         thinness = 1.5 linethickness;
80
81         pickup pencircle scaled thinness;
82
83         rt x2 = w;
84         lft x5 = -b;
85         bot y5 = 0;
86         top y3 = h;
87         y1 = y2 = y5;
88
89         x3 = 0;
90         z1 - z4 = whatever * (charwd, -charht);
91         z4 = fat_factor [z3, z5];
92
93         left_dist = (unitvector (z3 - z5) rotated 90) * 0.5 thinness;
94         right_dist = (unitvector (z2 - z3) rotated 90) * 0.5 thinness;
95
96         fill bot z5
97              .. (z5 - left_dist)
98              --- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
99                    ((z1 - right_dist) -- (z4 - right_dist)))
100              --- (z1 - right_dist)
101              .. bot z1
102              --- bot z2
103              .. (z2 + right_dist)
104              --- (z3 + right_dist)
105              .. top z3
106              .. (z3 + left_dist)
107              --- (z5 + left_dist)
108              .. cycle;
109
110         pickup pencircle scaled 2 dot_radius;
111
112         x1 - 2x6 = x2;
113         bot y6 = -d;
114
115         drawdot z6;
116 enddef;
117
118 fet_beginchar ("short fermata up", "ushortfermata")
119         draw_short_fermata;
120         labels (1, 2, 3, 4, 5, 6);
121 fet_endchar;
122
123
124 fet_beginchar ("short fermata down", "dshortfermata")
125         draw_short_fermata;
126         xy_mirror_char;
127 fet_endchar;
128
129
130 def draw_long_fermata =
131         save stemthick, beamheight, dot_radius, wd;
132         save pat;
133         path pat;
134
135         define_pixels (wd, dot_radius);
136
137         wd# = 2.5 staff_space#;
138         stemthick = 1.5 linethickness;
139         beamheight = 0.3 staff_space + linethickness;
140         dot_radius# = 0.133 staff_space# + 1.333 * linethickness#;
141
142         set_char_box (wd# / 2, wd# / 2, 0, 3/2 staff_space#);
143
144         pickup pencircle scaled blot_diameter;
145
146         top y1 = h;
147         lft x1 = -b;
148         x2 = x3 = 0;
149         y2 = h;
150         y3 = h - beamheight;
151
152         pat := z2
153                --- top z1
154                .. lft z1;
155
156         pickup pencircle scaled stemthick;
157
158         x4 = -b + stemthick;
159         y4 = y3;
160         lft x5 = -b;
161         bot y5 = -d;
162
163         pat := pat
164                --- lft z5
165                .. bot z5
166                .. rt z5
167                --- z4
168                --- z3;
169         pat := pat
170                & reverse pat xscaled -1
171                & cycle;
172
173         fill pat;
174
175         pickup pencircle scaled 2 dot_radius;
176
177         x6 = 0;
178         bot y6 = -d;
179
180         drawdot z6;
181 enddef;
182
183
184 fet_beginchar ("long fermata up", "ulongfermata")
185         draw_long_fermata;
186         labels (1, 2, 3, 4, 5, 6);
187 fet_endchar;
188
189
190 fet_beginchar ("long fermata down", "dlongfermata")
191         draw_long_fermata;
192         y_mirror_char;
193 fet_endchar;
194
195
196 def draw_very_long_fermata =
197         save ibeamheight, obeamheight;
198         save ihwd, ohwd, iht, oht;      % inner/outer half_width/height
199         save stemthick, dot_radius;
200         save opat, ipat;
201         path opat, ipat;
202
203         define_pixels (ihwd, ohwd, iht, oht)
204
205         ihwd# = 1.0 staff_space#;
206         ohwd# = 1.5 staff_space#;
207         iht# = 0.9 staff_space#;
208         oht# = 1.6 staff_space#;
209
210         stemthick = 1.5 linethickness;
211         ibeamheight = 0.3 staff_space;
212         obeamheight = 0.5 staff_space;
213         dot_radius = (iht - ibeamheight) * 4/10;
214
215         set_char_box (ohwd#, ohwd#, 0, oht#);
216
217         pickup pencircle scaled blot_diameter;
218
219         top y1 = oht;
220         lft x1 = -ohwd;
221         x2 = x3 = 0;
222         y2 = oht;
223         y3 = oht - obeamheight;
224         top y11 = iht;
225         lft x11 = -ihwd;
226         x12 = x13 = 0;
227         y12 = iht;
228         y13 = iht - ibeamheight;
229
230         opat := z2
231                 --- top z1
232                 .. lft z1;
233         ipat := z12
234                 --- top z11
235                 .. lft z11;
236
237         pickup pencircle scaled stemthick;
238
239         x4 = -ohwd + stemthick;
240         y4 = y3;
241         lft x5 = -ohwd;
242         bot y5 = 0;
243         x14 = -ihwd + stemthick;
244         y14 = y13;
245         lft x15 = -ihwd;
246         bot y15 = 0;
247
248         opat := opat
249                 --- lft z5
250                 .. bot z5
251                 .. rt z5
252                 --- z4
253                 --- z3;
254         opat := opat
255                 & reverse opat xscaled -1
256                 & cycle;
257         ipat := ipat
258                 --- lft z15
259                 .. bot z15
260                 .. rt z15
261                 --- z14
262                 --- z13;
263         ipat := ipat
264                 & reverse ipat xscaled -1
265                 & cycle;
266
267         fill opat;
268         fill ipat;
269
270         pickup pencircle scaled 2 dot_radius;
271
272         x6 = 0;
273         bot y6 = -d;
274
275         drawdot z6;
276 enddef;
277
278
279 fet_beginchar ("very long fermata up", "uverylongfermata")
280         draw_very_long_fermata;
281         labels (1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 6);
282 fet_endchar;
283
284
285 fet_beginchar ("very long fermata down", "dverylongfermata")
286         draw_very_long_fermata;
287         y_mirror_char;
288 fet_endchar;
289
290
291 %
292 % Thumbs are used in cello music.
293 % TODO : thumbs should look like the finger-font and should be placed in
294 % the same way in the score.
295 %
296
297 fet_beginchar ("Thumb", "thumb")
298         save thin, height, width, thick, depth;
299         height# = 5/4 width#;
300         height# = staff_space#;
301         depth# = 1.6 (height# / 2);
302
303         set_char_box (width# / 2, width# / 2, depth#, height# / 2);
304
305         define_pixels (height, width);
306
307         thin = .6 linethickness + 0.06 staff_space;
308         2 thick + 0.5 (height - 2 thin) = width;
309
310         penpos1 (thick, 0);
311         penpos2 (thin, 90);
312         penpos3 (thick, 180);
313         penpos4 (thin, 270);
314         z1r = (w, 0);
315         z2r = (0, h);
316         z3r = (-w, 0);
317         z4r = (0, -h);
318
319         penlabels (1, 2, 3, 4);
320
321         penstroke z1e{up}
322                   .. z2e{left}
323                   .. z3e{down}
324                   .. z4e{right}
325                   .. cycle;
326
327         save brush_thick;
328         y5 = -d + brush_thick / 2;
329         brush_thick = 0.9 thick;
330         x5 = 0;
331
332         labels (5);
333
334         draw_brush (z4r, 1.4 thin, z5, brush_thick);
335 fet_endchar;
336
337
338 %
339 % FIXME: rounded endings
340 %
341 % `\accent' is TeX reserved.
342 %
343
344 def draw_accent (expr bottom_left, top_right, thickness, diminish) =
345         pickup pencircle scaled thickness;
346
347         lft x1 = xpart bottom_left;
348         top y1 = ypart top_right;
349         lft x6 = xpart bottom_left;
350         bot y6 = ypart bottom_left;
351
352         rt z4 = (xpart top_right, (ypart top_right + ypart bottom_left) / 2);
353         x5 = x3 = (xpart top_right + xpart bottom_left) / 2
354                   - linethickness + 0.1 staff_space;
355         z3 = whatever [z1, z4];
356         z5 = whatever [z6, z4];
357
358         penpos1 (thickness, angle (z3 - z1) + 90);
359         penpos3 (thickness, angle (z3 - z1) + 90);
360         penpos4 (thickness, 90);
361         penpos5 (thickness, angle (z6 - z5) + 90);
362         penpos6 (thickness, angle (z6 - z5) + 90);
363
364         x4 - x7 = diminish * thickness;
365         y7 = y4;
366
367         fill z1l
368              --- z3l
369              --- z7
370              --- z5l
371              --- z6l
372              .. lft z6{down}
373              .. bot z6
374              .. z6r
375              --- z4l
376              ..tension 0.8.. rt z4
377              ..tension 0.8.. z4r
378              --- z1r
379              .. top z1
380              .. lft z1{down}
381              .. cycle;
382 enddef;
383
384
385 fet_beginchar ("> accent", "sforzato")
386         set_char_box (.9 staff_space#, .9 staff_space#,
387                       .5 staff_space#, .5 staff_space#);
388
389         draw_accent ((-w, -d), (w, h),
390                      0.05 staff_space + linethickness, 0.6);
391         penlabels (1, 3, 4, 5, 6);
392         labels (7);
393 fet_endchar;
394
395
396 fet_beginchar ("espr", "espr")
397         set_char_box (1.9 staff_space#, 1.9 staff_space#,
398                       .5 staff_space#, .5 staff_space#);
399
400         draw_accent ((w - 1.78 staff_space, -d), (w, h),
401                      0.05 staff_space + linethickness, 0.6);
402         addto currentpicture also currentpicture xscaled -1;
403 fet_endchar;
404
405
406 fet_beginchar ("staccato dot", "staccato")
407         save radius;
408         radius# = 0.20 * staff_space#;
409         define_whole_pixels (radius);
410
411         pickup pencircle scaled 2 radius;
412         drawdot (0, 0);
413
414         set_char_box (radius#, radius#, radius#, radius#);
415 fet_endchar;
416
417
418 def draw_staccatissimo =
419         save radius, height;
420         height# = .8 staff_space#;
421         radius# = linethickness# + .1 staff_space#;
422         define_whole_pixels (radius);
423         define_pixels (height);
424
425         draw_brush ((0, 0), linethickness, (0, height), 2 radius);
426
427         set_char_box (radius#, radius#,
428                       blot_diameter# / 2, height# + radius#);
429 enddef;
430
431
432 fet_beginchar ("staccatissimo/martellato up", "ustaccatissimo")
433         draw_staccatissimo;
434 fet_endchar;
435
436
437 fet_beginchar ("staccatissimo/martellato down", "dstaccatissimo")
438         draw_staccatissimo;
439         y_mirror_char;
440 fet_endchar;
441
442
443 fet_beginchar ("portato/single tenuto", "tenuto")
444         save thick;
445         thick# = 1.6 linethickness#;
446         define_whole_pixels (thick);
447
448         set_char_box (.6 staff_space#, .6 staff_space#,
449                       thick# / 2,thick# / 2);
450
451         pickup pencircle scaled thick;
452         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
453 fet_endchar;
454
455
456 def draw_portato =
457         save thick, radius;
458         thick# = 1.4 linethickness#;
459         radius# = 1.2 linethickness# + 0.04 staff_space#;
460         define_whole_pixels (thick, radius);
461
462         set_char_box (.6 staff_space#, .6 staff_space#,
463                       thick# / 2, .5 staff_space# + radius#);
464
465         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
466
467         pickup pencircle scaled 2 radius;
468         drawdot (0, h);
469 enddef;
470
471
472 fet_beginchar ("portato/tenuto with staccato", "uportato")
473         draw_portato;
474 fet_endchar;
475
476
477 fet_beginchar ("portato/tenuto with staccato", "dportato")
478         draw_portato;
479         y_mirror_char
480 fet_endchar;
481
482
483 def draw_marcato =
484         save fat_factor, thinness;
485         save left_dist, right_dist;
486         pair left_dist, right_dist;
487
488         set_char_box (staff_space# / 2, staff_space# / 2,
489                       0, 1.1 staff_space#);
490
491         fat_factor = .3;
492         thinness = linethickness;
493
494         pickup pencircle scaled thinness;
495
496         rt x2 = w;
497         lft x5 = -b;
498         bot y5 = 0;
499         top y3 = h;
500         y1 = y2 = y5;
501
502         x3 =0;
503         z1 - z4 = whatever * (charwd, -charht);
504         z4 = fat_factor [z3, z5];
505
506         left_dist = (unitvector (z3 - z5) rotated 90) * 0.5 thinness;
507         right_dist = (unitvector (z2 - z3) rotated 90) * 0.5 thinness;
508
509         fill bot z5
510              .. (z5 - left_dist)
511              --- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
512                    ((z1 - right_dist) -- (z4 - right_dist)))
513              --- (z1 - right_dist)
514              .. bot z1
515              --- bot z2
516              .. (z2 + right_dist)
517              --- (z3 + right_dist)
518              .. top z3
519              .. (z3 + left_dist)
520              --- (z5 + left_dist)
521              .. cycle;
522 enddef;
523
524
525 fet_beginchar ("marcato up", "umarcato")
526         draw_marcato;
527         labels (1, 2, 3, 4, 5);
528 fet_endchar;
529
530
531 %
532 % The down marcato char (not very much used).
533 % Contrary to what some MF/TeX `gurus' believe
534 % it is *point*-symmetric with the "up" version
535 %
536
537 fet_beginchar ("marcato down", "dmarcato")
538         draw_marcato;
539         xy_mirror_char;
540 fet_endchar;
541
542
543 %
544 % used in french horn music todo
545 %
546 % TODO: too light at 20pt
547 %
548
549 fet_beginchar ("open (unstopped)", "open")
550         save thin, height, width, thick;
551
552         height# = 5/4 width#;
553         height# = staff_space#;
554         thin = .6 linethickness + 0.06 staff_space;
555
556         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
557
558         define_pixels (width, height);
559
560         2 thick + 0.6 (height - 2 thin) = width;
561
562         penpos1 (thick, 0);
563         penpos2 (thin, 90);
564         penpos3 (thick, 180);
565         penpos4 (thin, 270);
566         z1r = (w, 0);
567         z2r = (0, h);
568         z3r = (-w, 0);
569         z4r = (0, -h);
570
571         penlabels (1, 2, 3, 4);
572
573         penstroke z1e{up}
574                   .. z2e{left}
575                   .. z3e{down}
576                   .. z4e{right}
577                   .. cycle;
578 fet_endchar;
579
580
581 fet_beginchar ("plus (stopped)", "stopped")
582         save thick, size;
583
584         thick = 2 linethickness;
585         size# = 1.1 staff_space#;
586
587         set_char_box (size# / 2, size# / 2, size# / 2, size# / 2);
588
589         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
590         addto currentpicture also currentpicture rotated 90;
591 fet_endchar;
592
593
594 fet_beginchar ("Upbow", "upbow")
595         save ht, wd, thick;
596
597         thick = 1.4 linethickness;
598         wd# = 1.3 staff_space#;
599         ht# = 1.6 wd#;
600
601         set_char_box (wd# / 2, wd# / 2, 0, ht#);
602
603         draw_accent ((-h, -w), (0, w), thick, 0.9);
604         currentpicture := currentpicture rotated -90;
605 fet_endchar;
606
607
608 fet_beginchar ("Downbow", "downbow")
609         save stemthick, beamheight, wd;
610         save pat;
611         path pat;
612
613         define_pixels (wd);
614
615         wd# = 1.5 staff_space#;
616         stemthick = 1.2 linethickness;
617
618         set_char_box (wd# / 2, wd# / 2, 0, 4/3 staff_space#);
619
620         beamheight = 4/10 h;
621
622         pickup pencircle scaled blot_diameter;
623
624         top y1 = h;
625         lft x1 = -b;
626         x2 = x3 = 0;
627         y2 = h;
628         y3 = h - beamheight;
629
630         pat := z2
631                --- top z1
632                .. lft z1;
633
634         pickup pencircle scaled stemthick;
635
636         x4 = -b + stemthick;
637         y4 = y3;
638         lft x5 = -b;
639         bot y5 = -d;
640
641         pat := pat
642                --- lft z5
643                .. bot z5
644                .. rt z5
645                --- z4
646                --- z3;
647         pat := pat
648                & reverse pat xscaled -1
649                & cycle;
650
651         fill pat;
652 fet_endchar;
653
654 %
655 % Inspired by a computer-set version of Auf dem Strom by Baerenreiter.
656 %
657
658 def draw_turn =
659         save thin, thick, ball_diam, darkness;
660         save wd, ht, thick_nibangle, ball_nib_thick;
661         save turndir;
662         pair turndir;
663
664         wd# = 35/16 staff_space#;
665         ht# = 18/17 staff_space#;
666         darkness = 0.3 linethickness + 0.09 staff_space;
667
668         set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2);
669
670         thick_nibangle = 60;
671         thick = 3 darkness;
672         thin = darkness;
673         ball_nib_thick = 2.7 darkness;
674         ball_diam = ball_nib_thick + (h - ball_nib_thick) / 10;
675
676         x3l = w;
677         y3 = 0;
678         y4l = h;
679         x4 = x2;
680         x2l = w / 2;
681         y2l = -d;
682         z1 = (0,0);
683
684         penpos1 (1.1 thick, thick_nibangle);
685         penpos2 (thick, thick_nibangle);
686         penpos3 (thin, 180);
687         penpos4 (ball_nib_thick, -90);
688
689         path swoosh, ploop;
690         swoosh := z1l{curl 0}
691                   .. z2l
692                   .. z3l{up}
693                   .. {left}z4l
694                   -- z4r
695                   .. z3r{down}
696                   .. z2r{left};
697         fill swoosh
698              .. (swoosh scaled -1)
699              .. cycle;
700
701         x5r = x4;
702         y5r = y4l - ball_diam / 2;
703         z6r = z5r;
704
705         penpos5 (1.6 ball_diam / 2, 10);
706         penpos6 (ball_diam / 2, 150);
707
708         ploop := z4l{left}
709                  .. z5l
710                  .. z6l
711                  -- cycle;
712         fill ploop;
713         fill ploop scaled -1;
714 enddef;
715
716
717 fet_beginchar ("Reverse turn","reverseturn")
718         draw_turn;
719         currentpicture := currentpicture yscaled -1;
720 fet_endchar;
721
722
723 fet_beginchar ("Turn","turn")
724         draw_turn;
725         penlabels (1, 2, 3, 4, 5, 6, 7);
726 fet_endchar;
727
728
729 %
730 % Inspired by a (by now) PD edition of Durand & C'ie edition of
731 % Saint-Saens' Celloconcerto no. 1
732 %
733 % FIXME take out hardcoded vars.
734 % FIXME the two loops on the `t' should be smoother (and the left one bigger).
735 % FIXME generic macros for serifs: top of the t and bottom of r
736 %
737
738 fet_beginchar ("Trill (`tr')", "trill")
739         save start_nib_angle, ascender_extra, ex, hair_thick, fatness;
740         save slant, t_fatness, r_fatness, kerning, t_overshoot;
741         save uitschieter, bulb_size, krul_ang;
742         save u, v;
743
744         ascender_extra# = 1/2 ex#;
745         ascender# = ascender_extra# + ex#;
746         ex# = 1.4 staff_space#;
747         kerning# = 0.6 ex#;
748         start_nib_angle = 20;
749         bulb_size = 0.8;
750         define_pixels (ex, ascender_extra, ascender, kerning);
751
752         t_overshoot = 0.03 ex;
753         fatness = 12/40 ex;
754         t_fatness = 0.78 fatness;
755         t_width =  1.9 t_fatness;
756         r_fatness = 0.78 fatness;
757         uitschieter = 0.48 ex;
758         hair_thick = linethickness;
759         r_flare = .5 hair_thick + 0.25 r_fatness;
760         r_width =  2 r_fatness + 0.25 kerning;
761         slant = .2;
762
763         local_copy (transform)(currenttransform);
764         currenttransform := currenttransform slanted slant
765                                              shifted (-staff_space, 0);
766
767         set_char_box (.85 staff_space#, .85 staff_space#, 0, ascender#);
768
769         y1 = ascender;
770
771         % try to position in such a way that the center is the visual
772         % center
773
774         x1l = 0.2 staff_space;
775         x1r - x1l = t_fatness;
776         penpos1 (start_nib_wid, start_nib_angle);
777
778         z2 = (x1, 7/18 ex);
779         penpos2 (start_nib_wid, start_nib_angle);
780
781         z3l = (x2l + 0.5 t_width, - t_overshoot);
782
783         z4l = (x2l + t_width, 0.23 ex);
784         penpos4 (whatever, 180);        % 200
785         x4l - x4r = hair_thick;
786
787         x3r = 0.5 [x4r, x2r];
788 %       1.7 [x3l, x3r] = x4r;
789         y3r - y3l = 0.6 t_fatness;
790
791         save krul_p;
792         path krul_p;
793
794         krul_ang = 32;
795
796         pickup pencircle scaled hair_thick;
797
798         z5 = (x2l + t_fatness / 2, 2/3 ex);
799         lft x6 = x2l - uitschieter;
800         y6 = y5;                                % - 1/20 ex;
801         z7 = z5 + whatever * dir krul_ang;
802         up_angle = krul_ang;                    % = angle (z7-z5)
803         x7 = 5/10 kerning + x5;
804
805         krul_p := z4{up}
806                   ..tension 0.98.. z5
807                   .. z6
808                   .. z5
809                   --- z7;
810
811         z4' = point 0.85 of krul_p;
812         penpos4' (hair_thick, angle (direction 0.85 of krul_p) + 90);
813
814         % the body of the `t' and the bottom loop
815         fill z1r{dir (angle (z1l - z1r) + 30)}
816              .. z1l{-dir (angle (z1r - z1l) - 45)}
817              -- z2l{down}
818              ..tension (1 + .5 slant).. z3l{right}
819              .. z4l{up}
820              .. z4'l{direction 0.85 of krul_p}
821              -- z4'r{-direction 0.85 of krul_p}
822              .. z4r{down}
823              .. z3r{left}
824              ..tension (1.5 + .7 slant).. z2r{up}
825              .. z1r
826              -- cycle;
827
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.3 of krul_p;
844         penpos7' (hair_thick, angle (direction 3.3 of krul_p) + 90);
845
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;
854
855         y9 = 3/4 ex;
856         x9 = x1 + kerning;
857         penpos9 (r_fatness, 0);
858
859         x10 = x9;
860         y10 = -0.3 linethickness;
861         penpos10 (r_fatness, 0);
862
863         penpos11 (hair_thick, -4);
864         z11r = z9r;
865
866         z13l = (x9l + r_width, y11 -  linethickness);
867         penpos13 (r_flare, 180);
868
869         z15 = z13r - (bulb_size * r_fatness, 0);
870         z14 = 0.5 [z13l, z15] - (0, bulb_size * r_fatness);
871
872         save before, after;
873         path before, after;
874         before := z13l{up}
875                   .. {down}z11l;
876         after := z9r{up}
877                  .. z7r
878                  --- z7'r;
879         (u, v) = before intersectiontimes after;
880
881         % the connection between `t' and `r', the body of the `r',
882         % and part of the bulb
883         fill z7'l
884              --- z7l
885              .. z9l{down}
886              --- simple_serif (z10l, z10r, -30)
887              --- z9r{up}
888              ..tension 0.94.. z13r{down}
889              -- z15{down}
890              .. z13l{up}
891              .. subpath (0, u) of before
892              .. subpath (v, infinity) of after
893              -- cycle;
894
895         % the rest of the bulb
896         fill z15{up}
897              ..tension 1.06.. z13l{down}
898              .. z14
899              .. cycle;
900
901         penlabels (range 1 thru 15);
902         penlabels (4', 5', 5'', 5''', 6', 6'', 6''', 7');
903 fet_endchar;
904
905
906 def draw_heel =
907         save radius, thickness;
908         save pat;
909         path pat;
910
911         radius# := .5 staff_space#;
912         define_pixels (radius);
913
914         set_char_box (radius#, radius#, radius#, 2/3 staff_space#);
915
916         thickness := 1.5 linethickness;
917
918         pickup pencircle scaled thickness;
919
920         rt x1 = b;
921         top y1 = h;
922
923         x2 =x1;
924         y2 = 0;
925
926         x3 = 0;
927         bot y3 = -d;
928
929         pat := top z3{right}
930                .. lft z2{up}
931                .. lft z1{up}
932                .. top z1
933                .. rt z1{down}
934                .. rt z2{down}
935                .. bot z3{left};
936         pat := pat
937                & reverse pat xscaled -1
938                & cycle;
939         fill pat;
940 enddef;
941
942
943 fet_beginchar ("left heel", "upedalheel")
944         draw_heel;
945         labels (1, 2, 3);
946 fet_endchar;
947
948
949 fet_beginchar ("right heel", "dpedalheel")
950         draw_heel;
951         y_mirror_char;
952 fet_endchar;
953
954
955 def draw_toe =
956         save ht, wd, thickness;
957
958         thickness := 1.5 linethickness;
959         ht# := 1.5 staff_space#;
960         wd# := 1/3 ht#;
961         define_pixels (ht, wd);
962
963         set_char_box (wd#, wd#, 0, ht#);
964         draw_accent ((-h, -w), (0, w), thickness, 0.9);
965         currentpicture := currentpicture rotated -90;
966 enddef;
967
968
969 fet_beginchar ("left toe", "upedaltoe")
970         draw_toe;
971 fet_endchar;
972
973
974 fet_beginchar ("right toe", "dpedaltoe")
975         draw_toe;
976         y_mirror_char;
977 fet_endchar;
978
979
980 fet_beginchar ("Flageolet", "flageolet")
981         save height, width, thickness;
982         height #= 4/15 staffsize#;
983         width #= height#;
984         thickness #= blot_diameter#;
985         define_pixels (height, width, thickness);
986
987         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
988
989         pickup pencircle scaled thickness;
990
991         penpos1 (thickness, 90);
992         penpos2 (thickness, 180);
993         penpos3 (thickness, 270);
994         penpos4 (thickness, 0);
995
996         x1= .5 [x2, x4];
997         x1 = 0;
998         top y1 = height / 2;
999         rt x4 - lft x2 = width;
1000         y2 = 0;
1001         y4 = y2;
1002         x3 = x1;
1003         bot y3 = -height / 2;
1004
1005         penlabels (1, 2, 3, 4);
1006
1007         penstroke z1e
1008                   .. z2e
1009                   .. z3e
1010                   .. z4e
1011                   .. cycle;
1012 fet_endchar;
1013
1014
1015 %
1016 % TODO:  ARGRGHGH code dup.
1017 %
1018
1019 fet_beginchar ("Segno", "segno")
1020         save thin, thick, ball_diam, darkness, pointheight;
1021         save wd, ht, thick_nibangle, ball_nib_thick;
1022         save turndir;
1023         pair turndir;
1024
1025         ht# = 3 staff_space#;
1026         wd# = 2 staff_space#;
1027         darkness = .08 staff_space + 0.4 linethickness;
1028
1029         set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2);
1030
1031         thick_nibangle = 30;
1032         thick = 3 darkness;
1033         thin = darkness;
1034         ball_nib_thick = 2.7 darkness;
1035         ball_diam = ball_nib_thick + (w - ball_nib_thick) / 10;
1036         pointheight = 2 linethickness;
1037
1038         y3l = h;
1039         2 x3 = x2 + x4;
1040         x4 = 0;
1041         y4 = y2;
1042         y2l = .6 h;
1043         x2l = -b;
1044         z1 = (0, 0);
1045
1046         penpos1 (thick, 2 thick_nibangle);
1047         penpos2 (thick, thick_nibangle);
1048         penpos3 (thin, -90);
1049         penpos4 (ball_nib_thick, 180 - thick_nibangle);
1050
1051         save swoosh, ploop;
1052         path swoosh, ploop;
1053
1054         swoosh := z1l{curl 0}
1055                   .. z2l
1056                   .. z3l{right}
1057                   .. {down}z4l
1058                   -- z4r
1059                   .. z3r{left}
1060                   .. z2r{down};
1061         fill swoosh
1062              .. (swoosh scaled -1)
1063              .. cycle;
1064
1065         y5r = y4;
1066         x5r = x4l - ball_diam / 2;
1067         z6r = z5r;
1068
1069         penpos5 (1.6 ball_diam / 2, 100);
1070         penpos6 (ball_diam / 2, 240);
1071
1072         ploop := z4l{down}
1073                  .. z5l
1074                  .. z6l
1075                  -- cycle;
1076         fill ploop;
1077         fill ploop scaled -1;
1078
1079         penpos7 (2 thin, 0);
1080         z7l = (-b, -d);
1081         penpos8 (2 thin, 0);
1082         z8r = (w, h);
1083
1084         penstroke z7e
1085                   -- z8e;
1086
1087         pickup pencircle scaled 2 thin;
1088         drawdot (-x2r, pointheight);
1089         drawdot (x2r, -pointheight);
1090
1091         penlabels (range 1 thru 8);
1092 fet_endchar;
1093
1094
1095 fet_beginchar ("Coda", "coda")
1096         save stickout, thin, thick, codawidth, codaheight;
1097
1098         stickout# = 0.35 staff_space#;
1099         codawidth# = 2/3 staff_space#;
1100         codaheight# = staff_space#;
1101         define_pixels (codawidth, codaheight);
1102
1103         set_char_box (codawidth# + stickout#, codawidth# + stickout#,
1104                       codaheight# + stickout#, codaheight# + stickout#);
1105
1106         thin = 1.2 linethickness;
1107         0.1 (codaheight - 2 thin) = (codawidth - 2 thick);
1108
1109         penpos1 (thick, 0);
1110         penpos2 (thin, -90);
1111         penpos3 (thick, -180);
1112         penpos4 (thin, -270);
1113
1114         x1l = -codawidth;
1115         y2l = codaheight;
1116         y1 = 0;
1117         x2 = 0;
1118         z3 = -z1;
1119         z4 = -z2;
1120
1121         penlabels (1, 2, 3, 4);
1122
1123         penstroke z1e{up}
1124                   .. z2e{right}
1125                   .. z3e{down}
1126                   .. z4e{left}
1127                   .. cycle;
1128
1129         draw_gridline ((0,-h),(0,h),thin);
1130         draw_gridline ((-w,0),(w,0),thin);
1131 fet_endchar;
1132
1133
1134 fet_beginchar ("Varied Coda", "varcoda")
1135         save thin, thick, codawidth, codaheight;
1136         thin# = 1.2 linethickness#;
1137         thick# = 1.0 linethickness# + 0.25 staff_space#;
1138         codawidth# = 2/3 staff_space#;
1139         codaheight# = staff_space#;
1140         define_pixels (thin, thick, codawidth, codaheight);
1141
1142         set_char_box (codawidth# + thick#, codawidth# + thick#,
1143                       codaheight# + thick#, codaheight# + thick#);
1144
1145         x1 = -codawidth;
1146         y1 = y2 - thin;
1147         x2 = codawidth;
1148         y2 = codaheight;
1149         draw_rounded_block (z1, z2, blot_diameter);
1150
1151         x3 = x1;
1152         y3 = -codaheight;
1153         x4 = x1 + thick;
1154         y4 = y2;
1155         draw_rounded_block (z3, z4, blot_diameter);
1156
1157         labels (1, 2, 3, 4);
1158
1159         addto currentpicture also currentpicture scaled -1;
1160
1161         draw_gridline ((0, -h), (0, h), thin);
1162         draw_gridline ((-w, 0), (w, 0), thin);
1163 fet_endchar;
1164
1165
1166 def draw_comma =
1167         save alpha, thick, thin, ht;
1168
1169         alpha := 35;
1170         thin# = 1.2 linethickness#;
1171         thick# = 3 linethickness#;
1172         ht# = .6 staff_space#;
1173         define_pixels (thin, thick, ht);
1174
1175         set_char_box (0, .5 staff_space#, ht#, ht#);
1176
1177         penpos1 (thick, alpha);
1178         penpos2 (thick, alpha + 90);
1179         penpos3 (thin, 180 - alpha);
1180         penpos4 (thin, 90 - alpha);
1181
1182         x3r = 0;
1183         x1l = x3l;
1184         y2r = -y4l = h;
1185         z1 = z2;
1186         z3 = z4;
1187
1188         fill z1l{dir (alpha + 90)}
1189              .. z2r{dir alpha}
1190              .. z1r{dir (alpha - 90)}
1191              .. z3l{dir (270 - alpha)}
1192              .. z4l{dir (alpha + 180)}
1193              .. z3r{dir (90-alpha)}
1194              .. cycle;
1195 enddef;
1196
1197
1198 fet_beginchar ("Right Comma", "rcomma");
1199         draw_comma;
1200         penlabels (1, 2, 3, 4);
1201 fet_endchar;
1202
1203
1204 fet_beginchar ("Left Comma", "lcomma");
1205         draw_comma;
1206         xy_mirror_char;
1207 fet_endchar;
1208
1209
1210 def draw_varcomma =
1211         save thick, thin, ht, wd, alpha;
1212
1213         alpha := 35;
1214         thin# = 1.2 linethickness#;
1215         thick# = 3 linethickness#;
1216         ht# = .6 staff_space#;
1217         wd# = .25 staff_space#;
1218         define_pixels (thin, thick, ht, alpha);
1219
1220         set_char_box (wd#, wd#, ht#, ht#);
1221
1222         z1 = (-b, -d);
1223         z2 = (w, h);
1224
1225         draw_brush (z1, thin, z2, thick);
1226 enddef;
1227
1228
1229 fet_beginchar ("Right Varied Comma", "rvarcomma");
1230         draw_varcomma;
1231         labels (1, 2);
1232 fet_endchar;
1233
1234
1235 fet_beginchar ("Left Varied Comma", "lvarcomma");
1236         draw_varcomma;
1237         xy_mirror_char;
1238 fet_endchar;
1239
1240
1241 thick# := 1/24 designsize;
1242 define_blacker_pixels (thick);
1243
1244 rthin := 0.075 * staff_space + 0.5 linethickness;
1245 rthick := 2 thick + rthin;
1246
1247
1248 def draw_arpeggio =
1249         save alpha;
1250         save ne, nw, se, sw;
1251         save x, y;
1252         pair ne,nw,se,sw;
1253
1254         alpha := -40;
1255
1256         nw = dir (alpha + 180);
1257         ne = dir (alpha + 90);
1258         se = dir alpha;
1259         sw = dir (alpha - 90);
1260
1261         penpos1 (rthin, alpha + 90);
1262         penpos2 (5/4 rthick, alpha);
1263         penpos3 (3/4 rthick, alpha);
1264         penpos4 (5/4 rthick, alpha);
1265         penpos5 (rthin, alpha + 90);
1266
1267         z1 = (width / 2, height) - overshoot * se;
1268         z2 = 2 [z4, (width / 2, height / 2)];
1269         z3 = 1/2 [z2, z4];
1270         x4 = 2/8 staff_space;
1271         y4 = rthin;
1272
1273         z5 = 2 [z1, (width / 2, height / 2)];
1274         z6 = z2l + 1/2 rthin * sw;
1275         z7 = z4l + 1/2 rthin * sw + 1/2 rthin * se;
1276         z8 = 2 [z6, (width / 2, height / 2)];
1277         z9 = 2 [z7, (width / 2, height / 2)];
1278
1279         fill z1l{se}
1280              --- z6
1281              .. z3l
1282              .. z7{se}
1283              --- z5l
1284              .. z5r{nw}
1285              --- z8
1286              .. z3r
1287              .. z9{nw}
1288              --- z1r
1289              .. cycle;
1290 enddef;
1291
1292
1293 fet_beginchar ("Arpeggio", "arpeggio");
1294 %       draw_staff (-2, 2, 0.0);
1295
1296         save height, overshoot, width;
1297         height# = staff_space#;
1298         width# = 0.8 height#;
1299         overshoot# = 0.25 staff_space#;
1300         define_pixels (height, overshoot, width);
1301
1302         set_char_box (0, width#, 0, height#);
1303         draw_arpeggio;
1304         penlabels (range 1 thru 9);
1305 fet_endchar;
1306
1307
1308 %
1309 % Extendable Trill symbol.
1310 % Not yet used
1311 % Rename me to Trill, rename Trill to Tr?
1312 %
1313
1314 fet_beginchar ("Trill_element", "trill_element");
1315         save height, overshoot;
1316         height# = staff_space#;
1317         width# = 0.8 height#;
1318         overshoot# = 0.25 staff_space#;
1319         define_pixels (height, overshoot, width);
1320
1321         set_char_box (0, height#, 0, width#);
1322         draw_arpeggio;
1323
1324         currentpicture := currentpicture shifted -(width / 2, height / 2);
1325         currentpicture := currentpicture rotated 90;
1326         currentpicture := currentpicture shifted (height / 2, width / 2);
1327 fet_endchar;
1328
1329
1330 %
1331 % Arpeggio arrow by Chris Jackson <chris@fluffhouse.org.uk>
1332 %
1333
1334 def draw_arpeggio_arrow =
1335         save thinness, height, width, overshoot;
1336         save nw, ne, se, sw;
1337         save alpha;
1338         save before_left, before_right, after_left, after_right;
1339         save u_left, v_left, u_right, v_right;
1340         pair nw, ne, se, sw;
1341         path before_left, before_right, after_left, after_right;
1342
1343         height# = staff_space#;
1344         width# = 0.8 height#;
1345         overshoot# = 0.25 staff_space#;
1346         define_pixels (height, overshoot, width);
1347
1348         set_char_box (0, width#, 0, height#);
1349
1350         alpha := -40;
1351         nw = dir (alpha + 180);
1352         ne = dir (alpha + 90);
1353         se = dir alpha;
1354         sw = dir (alpha - 90);
1355
1356         penpos1 (rthin, alpha + 90);
1357         penpos2 (5/4 rthick, alpha);
1358         penpos3 (5/4 rthick, 0);
1359
1360         z1 = (width / 2, height) - overshoot * se; % numbering is consistent
1361                                                    % with the arpeggio symbol
1362         z2 = 2 [z4, (width / 2, height / 2)];
1363         z3 = (0.5 width, 0.5 height);
1364         z4 = (0.25 staff_space, rthin);
1365         z6 = z2l + 1/2 rthin * sw;
1366         z9 = (width / 2, height) + overshoot * se;
1367
1368         bot z10 = (0.5 w, 0);
1369         lft z11 = (-0.3 w, 0.8 h);
1370         rt z12 = (1.3 w, 0.8 h);
1371
1372         pickup pencircle scaled 0.5 rthin;
1373
1374         before_left := z1l
1375                        --- z6
1376                        .. {down}z3l;
1377         after_left := (z3 + (0, -0.25 rthin / cosd (angle (nw))))
1378                       -- (z11 + 0.25 rthin * ne);
1379         (u_left, v_left) = before_left intersectiontimes after_left;
1380
1381         before_right := (z12 + 0.25 rthin * nw)
1382                         -- (z3 + (0, -0.25 rthin / cosd (angle (nw))));
1383         after_right := z3r{up}
1384                        .. z9
1385                        --- z1r;
1386         (u_right, v_right) = before_right intersectiontimes after_right;
1387
1388         fill subpath (0, u_left) of before_left
1389              .. subpath (v_left, infinity) of after_left
1390              .. top z11
1391              .. lft z11
1392              .. {dir -50}(z11 + 0.25 rthin * sw)
1393              .. (z10 + 0.25 rthin * sw){dir -70}
1394              .. bot z10
1395              .. {dir 70}(z10 + 0.25 rthin * se)
1396              .. (z12 + 0.25 rthin * se){dir 50}
1397              .. rt z12
1398              .. top z12
1399              .. subpath (0, u_right) of before_right
1400              .. subpath (v_right, infinity) of after_right
1401              .. cycle;
1402
1403 %       fill (z3 + (0, -0.25 rthin / cosd (angle (nw))))
1404 %            -- (z12 + 0.25 rthin * nw)
1405 %            .. top z12
1406 %            .. rt z12
1407 %            .. (z12 + 0.25 rthin * se){dir -130}
1408 %            .. {dir -110}(z10 + 0.25 rthin * se)
1409 %            .. bot z10
1410 %            .. (z10 + 0.25 rthin * sw){dir 110}
1411 %            .. {dir 130}(z11 + 0.25 rthin * sw)
1412 %            .. lft z11
1413 %            .. top z11
1414 %            .. (z11 + 0.25 rthin * ne)
1415 %            -- cycle;
1416 enddef;
1417
1418
1419 fet_beginchar ("Arpeggio arrow down", "arpeggio.arrow.M1");
1420         draw_arpeggio_arrow;
1421         penlabels (range 1 thru 12);
1422 fet_endchar;
1423
1424
1425 fet_beginchar ("Arpeggio arrow up", "arpeggio.arrow.1");
1426         draw_arpeggio_arrow;
1427         currentpicture := currentpicture scaled -1
1428                                          shifted (0.8 staff_space,
1429                                                   staff_space);
1430 fet_endchar;
1431
1432
1433 % Hmm
1434 input feta-slag;
1435
1436
1437 % railroad tracks.
1438 %
1439 % I actually have no clue how they should look, so we use a slightly curvy
1440 % and tapered shape.
1441 %
1442
1443 fet_beginchar ("Caesura", "caesura");
1444         save slant, space_between, clearance;
1445         save alpha, p;
1446         save botthick, topthick;
1447         save krom;
1448         path p;
1449
1450         botthick = 1.5 linethickness;
1451         topthick = 2.5 linethickness;
1452
1453         pickup pencircle scaled botthick;
1454
1455         slant = 3.5;
1456         space_between# = 0.6 staff_space#;
1457         clearance# = 0.2 staff_space#;
1458         height# = 1.2 staff_space#;
1459
1460         set_char_box (0, 2.0 staff_space#,
1461                       staff_space# - clearance#, height#);
1462         define_pixels (space_between, clearance, height);
1463
1464         bot y1 = -d;
1465         top y2 = h;
1466
1467         lft x1 = 0;
1468         x2 = (y2 - y1) / slant;
1469
1470         krom = 10;
1471
1472         alpha = angle (z2 - z1);
1473         penpos1 (botthick, alpha - krom);
1474         penpos3 (botthick, alpha - krom + 90);
1475
1476         penpos2 (topthick, alpha + krom);
1477         penpos4 (topthick, alpha + krom + 90);
1478
1479         z3 = z1;
1480         z4 = z2;
1481
1482         penlabels (1, 2, 3, 4);
1483
1484         p := z3r{(z1r - z1l)}
1485              .. z4r{z2r-z2l}
1486              .. z2r{z4l-z4r}
1487              .. z4l{z2l-z2r}
1488              .. z3l{z1l-z1r}
1489              .. z1l{z3r-z3l}
1490              .. cycle;
1491         fill p;
1492         fill p shifted (space_between, 0);
1493 fet_endchar;
1494
1495
1496 fet_endgroup ("scripts");