]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-scripts.mf
Add '-dcrop' option to ps and svg backends
[lilypond.git] / mf / feta-scripts.mf
1 % Feta (not the Font-En-Tja) music font --  implement scripts
2 % This file is part of LilyPond, the GNU music typesetter.
3 %
4 % Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5 %       Jan Nieuwenhuizen <janneke@gnu.org>
6 %
7 %
8 % The LilyPond font is free software: you can redistribute it and/or modify
9 % it under the terms of the GNU General Public License as published by
10 % the Free Software Foundation, either version 3 of the License, or
11 % (at your option) any later version, or under the SIL Open Font License.
12 %
13 % LilyPond is distributed in the hope that it will be useful,
14 % but WITHOUT ANY WARRANTY; without even the implied warranty of
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 % GNU General Public License for more details.
17 %
18 % You should have received a copy of the GNU General Public License
19 % along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
20
21
22 fet_begingroup ("scripts");
23
24 def draw_fermata =
25         save alpha, radius, crook_thinness, crook_fatness, dot_size;
26         save pat;
27         path pat;
28
29         % [Wanske] and some Baerenreiter editions
30         % suggest about 80 degrees instead of a half-circle
31         alpha := 10;
32
33         radius# = 1.25 staff_space#;
34         crook_thinness# = 1.5 linethickness#;
35         crook_fatness# = 0.25 staff_space# + 1.5 linethickness#;
36
37         radius# + crook_fatness# / 2 = h#;
38         radius# + crook_thinness# / 2 = w#;
39
40         set_char_box (w#, w#, crook_thinness# / 2, h#);
41
42         define_pixels (radius, crook_thinness, crook_fatness);
43
44         dot_size# = 8/6 crook_fatness#;
45         define_whole_blacker_pixels (dot_size);
46
47         penpos1 (crook_thinness, 0);
48         penpos2 (crook_fatness, -90);
49         z1 = (-radius, 0);
50         z2 = (0, radius);
51
52         pat := z2l{left}
53                .. z1l{dir (-alpha - 90)}
54                .. {dir (90 - alpha)}z1r
55                .. {right}z2r;
56         pat := pat
57                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
58                -- cycle;
59         fill pat;
60
61         pickup pencircle scaled dot_size;
62         x4 = 0;
63         bot y4 = vround (-crook_thinness / 2);
64         drawdot z4;
65 enddef;
66
67
68 fet_beginchar ("fermata up", "ufermata");
69         draw_fermata;
70         penlabels (1, 2, 4);
71 fet_endchar;
72
73
74 fet_beginchar ("fermata down", "dfermata");
75         draw_fermata;
76         y_mirror_char;
77 fet_endchar;
78
79
80 def draw_short_fermata =
81         save fat_factor, thinness, dot_size;
82         save left_dist, right_dist, se, ne;
83         pair left_dist, right_dist, se, ne;
84
85         set_char_box (staff_space#, staff_space#, 0, 2.2 staff_space#);
86
87         dot_size# = 0.266 staff_space# + 2.666 linethickness#;
88         define_whole_blacker_pixels (dot_size);
89
90         fat_factor = .11;
91         thinness = 1.5 linethickness;
92
93         pickup pencircle scaled thinness;
94
95         rt x2 = w;
96         lft x5 = -b;
97         bot y5 = 0;
98         top y3 = h;
99         y1 = y2 = y5;
100
101         x3 = 0;
102         z1 - z4 = whatever * (charwd, -charht);
103         z4 = fat_factor [z3, z5];
104
105         ne = unitvector (z3 - z5);
106         se = unitvector (z2 - z3);
107
108         left_dist = (ne rotated 90) * 0.5 thinness;
109         right_dist = (se rotated 90) * 0.5 thinness;
110
111         fill bot z5{right}
112              .. (z5 - left_dist){ne}
113              -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
114                   ((z1 - right_dist) -- (z4 - right_dist)))
115              -- (z1 - right_dist){se}
116              .. bot z1{right}
117              -- bot z2{right}
118              .. (z2 + right_dist){-se}
119              -- (z3 + right_dist){-se}
120              .. top z3
121              .. (z3 + left_dist){-ne}
122              -- (z5 + left_dist){-ne}
123              .. cycle;
124
125         pickup pencircle scaled dot_size;
126
127         x1 - 2 x6 = x2;
128         x6 := vround (x6);
129         bot y6 = -d;
130
131         drawdot z6;
132 enddef;
133
134 fet_beginchar ("short fermata up", "ushortfermata");
135         draw_short_fermata;
136         labels (1, 2, 3, 4, 5, 6);
137 fet_endchar;
138
139
140 fet_beginchar ("short fermata down", "dshortfermata");
141         draw_short_fermata;
142         xy_mirror_char;
143 fet_endchar;
144
145
146 def draw_long_fermata =
147         save stemthick, beamheight, dot_size, wd;
148         save pat;
149         path pat;
150
151         wd# = 2.5 staff_space#;
152         stemthick = hround (1.5 linethickness);
153         beamheight = 0.3 staff_space + linethickness;
154         dot_size# = 0.266 staff_space# + 2.666 * linethickness#;
155         define_pixels (wd);
156         define_whole_blacker_pixels (dot_size);
157
158         set_char_box (wd# / 2, wd# / 2, 0, 3/2 staff_space#);
159
160         pickup pencircle scaled blot_diameter;
161
162         top y1 = h;
163         lft x1 = -b;
164
165         pat := top z1{left}
166                .. {down}lft z1;
167
168         pickup pencircle scaled stemthick;
169
170         x2 = -b + stemthick;
171         y2 = h - beamheight;
172         lft x3 = -b;
173         bot y3 = -d;
174
175         pat := pat
176                -- lft z3
177                .. bot z3
178                .. rt z3
179                -- z2;
180         pat := pat
181                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
182                -- cycle;
183
184         fill pat;
185
186         pickup pencircle scaled dot_size;
187
188         x4 = 0;
189         bot y4 = -d;
190
191         drawdot z4;
192 enddef;
193
194
195 fet_beginchar ("long fermata up", "ulongfermata");
196         draw_long_fermata;
197         labels (1, 2, 3, 4);
198 fet_endchar;
199
200
201 fet_beginchar ("long fermata down", "dlongfermata");
202         draw_long_fermata;
203         y_mirror_char;
204 fet_endchar;
205
206
207 def draw_very_long_fermata =
208         save ibeamheight, obeamheight;
209         save ihwd, ohwd, iht, oht;      % inner/outer half_width/height
210         save stemthick, dot_size;
211         save opat, ipat;
212         path opat, ipat;
213
214         ihwd# = 1.0 staff_space#;
215         ohwd# = 1.5 staff_space#;
216         iht# = 0.9 staff_space#;
217         oht# = 1.6 staff_space#;
218         define_pixels (ihwd, ohwd, iht, oht)
219
220         stemthick = hround (1.5 linethickness);
221         ibeamheight# = 0.3 staff_space#;
222         obeamheight# = 0.5 staff_space#;
223         define_pixels (ibeamheight, obeamheight);
224
225         dot_size# = (iht# - ibeamheight#) * 8/10;
226         define_whole_blacker_pixels (dot_size);
227
228         set_char_box (ohwd#, ohwd#, 0, oht#);
229
230         pickup pencircle scaled blot_diameter;
231
232         top y1 = oht;
233         lft x1 = -ohwd;
234         top y11 = iht;
235         lft x11 = -ihwd;
236
237         opat := top z1{left}
238                 .. {down}lft z1;
239         ipat := top z11{left}
240                 .. {down}lft z11;
241
242         pickup pencircle scaled stemthick;
243
244         x2 = -ohwd + stemthick;
245         y2 = oht - obeamheight;
246         lft x3 = -ohwd;
247         bot y3 = 0;
248         x12 = -ihwd + stemthick;
249         y12 = iht - ibeamheight;
250         lft x13 = -ihwd;
251         bot y13 = 0;
252
253         opat := opat
254                 -- lft z3
255                 .. bot z3
256                 .. rt z3
257                 -- z2;
258         opat := opat
259                 -- reverse opat xscaled -1 shifted (-feta_eps, 0)
260                 -- cycle;
261         ipat := ipat
262                 -- lft z13
263                 .. bot z13
264                 .. rt z13
265                 -- z12;
266         ipat := ipat
267                 -- reverse ipat xscaled -1 shifted (-feta_eps, 0)
268                 -- cycle;
269
270         fill opat;
271         fill ipat;
272
273         pickup pencircle scaled dot_size;
274
275         x4 = 0;
276         bot y4 = -d;
277
278         drawdot z4;
279 enddef;
280
281
282 fet_beginchar ("very long fermata up", "uverylongfermata");
283         draw_very_long_fermata;
284         labels (1, 2, 3, 11, 12, 13, 4);
285 fet_endchar;
286
287
288 fet_beginchar ("very long fermata down", "dverylongfermata");
289         draw_very_long_fermata;
290         y_mirror_char;
291 fet_endchar;
292
293
294 %
295 % Thumbs are used in cello music.
296 % TODO : thumbs should look like the finger-font and should be placed in
297 % the same way in the score.
298 %
299
300 fet_beginchar ("Thumb", "thumb");
301         save thin, height, width, thick, depth;
302         height# = 5/4 width#;
303         height# = staff_space#;
304         depth# = 1.6 (height# / 2);
305
306         set_char_box (width# / 2, width# / 2, depth#, height# / 2);
307
308         define_pixels (height, width);
309
310         thin = .6 linethickness + 0.06 staff_space;
311         2 thick + 0.5 (height - 2 thin) = width;
312
313         penpos1 (thick, 0);
314         penpos2 (thin, 90);
315         penpos3 (thick, 180);
316         penpos4 (thin, 270);
317         z1r = (w, 0);
318         z2r = (0, h);
319         z3r = (-w, 0);
320         z4r = (0, -h);
321
322         penlabels (1, 2, 3, 4);
323
324         penstroke z1e{up}
325                   .. z2e{left}
326                   .. z3e{down}
327                   .. z4e{right}
328                   .. cycle;
329
330         save brush_thick;
331         y5 = -d + brush_thick / 2;
332         brush_thick = 0.9 thick;
333         x5 = 0;
334
335         labels (5);
336
337         draw_brush (z4r, 1.4 thin, z5, brush_thick);
338 fet_endchar;
339
340
341 %
342 % `\accent' is TeX reserved.
343 %
344
345 def draw_accent (expr bottom_left, top_right, thickness, diminish) =
346         save thinning_start;
347         thinning_start = 0.4;
348         pickup pencircle scaled thickness;
349
350         lft x1 = xpart bottom_left;
351         top y1 = ypart top_right;
352         lft x6 = xpart bottom_left;
353         bot y6 = ypart bottom_left;
354
355         rt z4 = (xpart top_right, (ypart top_right + ypart bottom_left) / 2);
356         x5 = x3 = thinning_start [xpart top_right, xpart bottom_left]
357                   - linethickness + 0.1 staff_space;
358         z3 = whatever [z1, z4];
359         z5 = whatever [z6, z4];
360
361         penpos1 (thickness, angle (z3 - z1) + 90);
362         penpos3 (thickness, angle (z3 - z1) + 90);
363         penpos4 (thickness, 90);
364         penpos5 (thickness, angle (z6 - z5) + 90);
365         penpos6 (thickness, angle (z6 - z5) + 90);
366
367         x4 - x7 = diminish * thickness;
368         y7 = y4;
369
370         fill z1l
371              -- z3l
372              -- z7
373              -- z5l
374              -- z6l
375              .. lft z6{down}
376              .. bot z6
377              .. z6r
378              -- z4l
379              ..tension 0.8.. rt z4
380              ..tension 0.8.. z4r
381              -- z1r
382              .. top z1
383              .. lft z1{down}
384              .. cycle;
385 enddef;
386
387
388 fet_beginchar ("> accent", "sforzato");
389         set_char_box (.9 staff_space#, .9 staff_space#,
390                       .5 staff_space#, .5 staff_space#);
391
392         draw_accent ((-w, -d), (w, h),
393                      0.05 staff_space + linethickness, 0.7);
394         penlabels (1, 3, 4, 5, 6);
395         labels (7);
396 fet_endchar;
397
398
399 fet_beginchar ("espr", "espr");
400         set_char_box (1.9 staff_space#, 1.9 staff_space#,
401                       .5 staff_space#, .5 staff_space#);
402
403         draw_accent ((w - 1.78 staff_space, -d), (w, h),
404                      0.05 staff_space + linethickness, 0.6);
405         addto currentpicture also currentpicture xscaled -1;
406 fet_endchar;
407
408
409 fet_beginchar ("staccato dot", "staccato");
410         save radius;
411         radius# = 0.20 * staff_space#;
412         define_whole_pixels (radius);
413
414         pickup pencircle scaled 2 radius;
415         drawdot (0, 0);
416
417         set_char_box (radius#, radius#, radius#, radius#);
418 fet_endchar;
419
420
421 def draw_staccatissimo =
422         save radius, height;
423         height# = .8 staff_space#;
424         radius# = linethickness# + .1 staff_space#;
425         define_whole_blacker_pixels (radius);
426         define_pixels (height);
427
428         draw_brush ((0, 0), linethickness, (0, height), 2 radius);
429
430         set_char_box (radius#, radius#,
431                       blot_diameter# / 2, height# + radius#);
432 enddef;
433
434
435 fet_beginchar ("staccatissimo/martellato up", "ustaccatissimo");
436         draw_staccatissimo;
437 fet_endchar;
438
439
440 fet_beginchar ("staccatissimo/martellato down", "dstaccatissimo");
441         draw_staccatissimo;
442         y_mirror_char;
443 fet_endchar;
444
445
446 fet_beginchar ("portato/single tenuto", "tenuto");
447         save thick;
448         thick# = 1.6 linethickness#;
449         define_whole_blacker_pixels (thick);
450
451         set_char_box (.6 staff_space#, .6 staff_space#,
452                       thick# / 2, thick# / 2);
453
454         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
455 fet_endchar;
456
457
458 def draw_portato =
459         save thick, dot_size;
460         thick# = 1.4 linethickness#;
461         dot_size# = 2.4 linethickness# + 0.08 staff_space#;
462         define_whole_blacker_pixels (thick, dot_size);
463
464         set_char_box (.6 staff_space#, .6 staff_space#,
465                       thick# / 2, .5 staff_space# + .5 dot_size#);
466
467         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
468
469         pickup pencircle scaled dot_size;
470         drawdot (0, h);
471 enddef;
472
473
474 fet_beginchar ("portato/tenuto with staccato", "uportato");
475         draw_portato;
476 fet_endchar;
477
478
479 fet_beginchar ("portato/tenuto with staccato", "dportato");
480         draw_portato;
481         y_mirror_char
482 fet_endchar;
483
484
485 def draw_marcato =
486         save fat_factor, thinness;
487         save left_dist, right_dist, ne, se;
488         pair left_dist, right_dist, ne, se;
489
490         set_char_box (staff_space# / 2, staff_space# / 2,
491                       0, 1.1 staff_space#);
492
493         fat_factor = .3;
494         thinness = linethickness;
495
496         pickup pencircle scaled thinness;
497
498         rt x2 = w;
499         lft x5 = -b;
500         bot y5 = 0;
501         top y3 = h;
502         y1 = y2 = y5;
503
504         x3 =0;
505         z1 - z4 = whatever * (charwd, -charht);
506         z4 = fat_factor [z3, z5];
507
508         ne = unitvector (z3 - z5);
509         se = unitvector (z2 - z3);
510
511         left_dist = (ne rotated 90) * 0.5 thinness;
512         right_dist = (se rotated 90) * 0.5 thinness;
513
514         fill bot z5{right}
515              .. (z5 - left_dist){ne}
516              -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
517                   ((z1 - right_dist) -- (z4 - right_dist)))
518              -- (z1 - right_dist){se}
519              .. bot z1{right}
520              -- bot z2{right}
521              .. (z2 + right_dist){-se}
522              -- (z3 + right_dist){-se}
523              .. top z3
524              .. (z3 + left_dist){-ne}
525              -- (z5 + left_dist){-ne}
526              .. cycle;
527 enddef;
528
529
530 fet_beginchar ("marcato up", "umarcato");
531         draw_marcato;
532         labels (1, 2, 3, 4, 5);
533 fet_endchar;
534
535
536 %
537 % The down marcato char (not very much used).
538 % Contrary to what some MF/TeX `gurus' believe
539 % it is *point*-symmetric with the "up" version
540 %
541
542 fet_beginchar ("marcato down", "dmarcato");
543         draw_marcato;
544         xy_mirror_char;
545 fet_endchar;
546
547
548 %
549 % used in french horn music todo
550 %
551 % TODO: too light at 20pt
552 %
553
554 fet_beginchar ("open (unstopped)", "open");
555         save thin, height, width, thick;
556
557         height# = 5/4 width#;
558         height# = staff_space#;
559         thin = .6 linethickness + 0.06 staff_space;
560
561         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
562
563         define_pixels (width, height);
564
565         2 thick + 0.6 (height - 2 thin) = width;
566
567         penpos1 (thick, 0);
568         penpos2 (thin, 90);
569         penpos3 (thick, 180);
570         penpos4 (thin, 270);
571         z1r = (w, 0);
572         z2r = (0, h);
573         z3r = (-w, 0);
574         z4r = (0, -h);
575
576         penlabels (1, 2, 3, 4);
577
578         penstroke z1e{up}
579                   .. z2e{left}
580                   .. z3e{down}
581                   .. z4e{right}
582                   .. cycle;
583 fet_endchar;
584
585
586 fet_beginchar ("halfopen (unstopped)", "halfopen");
587         save thin, height, width, thick, factor, slash;
588
589         factor = 5/4;
590         height# = 5/4 width#;
591         height# = staff_space#;
592         thin = 0.6 linethickness + 0.06 staff_space;
593         slash# = 1.05 linethickness#;
594
595         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
596
597         define_pixels (width, height, slash);
598
599         2 thick + 0.6 (height - 2 thin) = width;
600
601         penpos1 (thick, 0);
602         penpos2 (thin, 90);
603         penpos3 (thick, 180);
604         penpos4 (thin, 270);
605         z1r = (w, 0);
606         z2r = (0, h);
607         z3r = (-w, 0);
608         z4r = (0, -h);
609
610         penlabels (1, 2, 3, 4);
611
612         penstroke z1e{up}
613                   .. z2e{left}
614                   .. z3e{down}
615                   .. z4e{right}
616                   .. cycle;
617
618         draw_brush ((-w * factor, -h * factor), slash,
619                     (w * factor, h * factor), slash);
620 fet_endchar;
621
622
623 fet_beginchar ("halfopen vertical", "halfopenvertical");
624         save thin, height, width, thick, factor, slash;
625
626         factor := 3/2;
627         height# = 5/4 width#;
628         height# = staff_space#;
629         thin = 0.6 linethickness + 0.06 staff_space;
630         slash# = 1.05 linethickness#;
631
632         set_char_box (width# / 2, width# / 2,
633                       height# / 2, height# / 2);
634
635         define_pixels (width, height, slash);
636
637         2 thick + 0.6 (height - 2 thin) = width;
638
639         penpos1 (thick, 0);
640         penpos2 (thin, 90);
641         penpos3 (thick, 180);
642         penpos4 (thin, 270);
643         z1r = (w, 0);
644         z2r = (0, h);
645         z3r = (-w, 0);
646         z4r = (0, -h);
647
648         penlabels (1, 2, 3, 4);
649
650         penstroke z1e{up}
651                   .. z2e{left}
652                   .. z3e{down}
653                   .. z4e{right}
654                   .. cycle;
655
656         draw_brush ((0, -h * factor), slash,
657                     (0, h * factor), slash);
658 fet_endchar;
659
660
661 fet_beginchar ("plus (stopped)", "stopped");
662         save hthick, vthick, size, outer_hsize, outer_vsize;
663
664         hthick# = vthick# = 2 linethickness#;
665         size# = 1.1 staff_space#;
666         define_whole_blacker_pixels (vthick);
667         define_whole_vertical_blacker_pixels (hthick);
668
669         set_char_box (size# / 2, size# / 2, size# / 2, size# / 2);
670
671         outer_hsize = hround ((b + w - vthick) / 2);
672         outer_vsize = vround ((h + d - hthick) / 2);
673         w := b := (2 outer_hsize + vthick) / 2;
674         h := d := (2 outer_vsize + hthick) / 2;
675
676         draw_rounded_block ((-b, -d + outer_vsize),
677                             (w, -d + outer_vsize + hthick), hthick);
678         draw_rounded_block ((-b + outer_hsize, -d),
679                             (-b + outer_hsize + vthick, h), vthick);
680 fet_endchar;
681
682
683 fet_beginchar ("Upbow", "upbow");
684         save ht, wd, thick;
685
686         thick = 1.4 linethickness;
687         wd# = 1.3 staff_space#;
688         ht# = 1.6 wd#;
689
690         set_char_box (wd# / 2, wd# / 2, 0, ht#);
691
692         draw_accent ((-h, -w), (0, w), thick, 0.9);
693         currentpicture := currentpicture rotated -90;
694 fet_endchar;
695
696
697 fet_beginchar ("Downbow", "downbow");
698         save stemthick, beamheight, wd;
699         save pat;
700         path pat;
701
702         wd# = 1.5 staff_space#;
703         define_pixels (wd);
704
705         stemthick = hround (1.2 linethickness);
706
707         set_char_box (wd# / 2, wd# / 2, 0, 4/3 staff_space#);
708
709         beamheight = 4/10 h;
710
711         pickup pencircle scaled blot_diameter;
712
713         top y1 = h;
714         lft x1 = -b;
715
716         pat := top z1{left}
717                .. {down}lft z1;
718
719         pickup pencircle scaled stemthick;
720
721         x2 = -b + stemthick;
722         y2 = h - beamheight;
723         lft x3 = -b;
724         bot y3 = -d;
725
726         pat := pat
727                -- lft z3
728                .. bot z3
729                .. rt z3
730                -- z2;
731         pat := pat
732                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
733                -- cycle;
734
735         fill pat;
736
737         labels (1, 2, 3);
738 fet_endchar;
739
740 %
741 % Inspired by a computer-set version of Auf dem Strom by Baerenreiter.
742 %
743
744 def draw_turn =
745         save thin, thick, ball_diam, darkness;
746         save wd, ht, thick_nibangle, ball_nib_thick;
747         save turndir;
748         pair turndir;
749
750         wd# = 35/16 staff_space#;
751         ht# = 18/17 staff_space#;
752         darkness = 0.3 linethickness + 0.09 staff_space;
753
754         set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2);
755
756         thick_nibangle = 60;
757         thick = 3 darkness;
758         thin = darkness;
759         ball_nib_thick = 2.7 darkness;
760         ball_diam = ball_nib_thick + (h - ball_nib_thick) / 10;
761
762         x3l = w;
763         y3 = 0;
764         y4l = h;
765         x4 = x2;
766         x2l = w / 2;
767         y2l = -d;
768         z1 = (0,0);
769
770         penpos1 (1.1 thick, thick_nibangle);
771         penpos2 (thick, thick_nibangle);
772         penpos3 (thin, 180);
773         penpos4 (ball_nib_thick, -90);
774
775         path swoosh, ploop;
776         swoosh := z1l{curl 0}
777                   .. z2l
778                   .. z3l{up}
779                   .. {left}z4l
780                   -- z4r
781                   .. z3r{down}
782                   .. z2r{left};
783         fill swoosh
784              .. swoosh scaled -1 shifted (-feta_eps, -feta_eps)
785              .. cycle;
786
787         x5r = x4;
788         y5r = y4l - ball_diam / 2;
789         z6r = z5r;
790
791         penpos5 (1.6 ball_diam / 2, 10);
792         penpos6 (ball_diam / 2, 150);
793
794         ploop := z4l{left}
795                  .. z5l
796                  .. z6l
797                  -- cycle;
798         fill ploop;
799         fill ploop scaled -1 shifted (-feta_eps, -feta_eps);
800 enddef;
801
802
803 fet_beginchar ("Reverse turn", "reverseturn");
804         draw_turn;
805         currentpicture := currentpicture yscaled -1;
806 fet_endchar;
807
808
809 fet_beginchar ("Turn", "turn");
810         draw_turn;
811         penlabels (1, 2, 3, 4, 5, 6, 7);
812 fet_endchar;
813
814
815 %
816 % Inspired by a (by now) PD edition of Durand & C'ie edition of
817 % Saint-Saens' Celloconcerto no. 1
818 %
819 % FIXME take out hardcoded vars.
820 % FIXME the two loops on the `t' should be smoother (and the left one bigger).
821 % FIXME generic macros for serifs: top of the t and bottom of r
822 %
823
824 fet_beginchar ("Trill (`tr')", "trill");
825         save start_nib_angle, ascender_extra, ex, hair_thick, fatness;
826         save slant, t_fatness, r_fatness, kerning, t_overshoot;
827         save uitschieter, bulb_size, krul_ang;
828         save u, v;
829
830         ascender_extra# = 1/2 ex#;
831         ascender# = ascender_extra# + ex#;
832         ex# = 1.4 staff_space#;
833         kerning# = 0.6 ex#;
834         start_nib_angle = 20;
835         bulb_size = 0.8;
836         define_pixels (ex, ascender_extra, ascender, kerning);
837
838         t_overshoot = 0.03 ex;
839         fatness = 12/40 ex;
840         t_fatness = 0.78 fatness;
841         t_width =  1.9 t_fatness;
842         r_fatness = 0.78 fatness;
843         uitschieter = 0.48 ex;
844         hair_thick = linethickness;
845         r_flare = .5 hair_thick + 0.25 r_fatness;
846         r_width =  2 r_fatness + 0.25 kerning;
847         slant = .2;
848
849         local_copy (transform)(currenttransform);
850         currenttransform := currenttransform slanted slant
851                                              shifted (-staff_space, 0);
852
853         set_char_box (.85 staff_space#, .85 staff_space#, 0, ascender#);
854
855         y1 = ascender;
856
857         % try to position in such a way that the center is the visual
858         % center
859
860         x1l = 0.2 staff_space;
861         x1r - x1l = t_fatness;
862         penpos1 (start_nib_wid, start_nib_angle);
863
864         z2 = (x1, 7/18 ex);
865         penpos2 (start_nib_wid, start_nib_angle);
866
867         z3l = (x2l + 0.5 t_width, - t_overshoot);
868
869         z4l = (x2l + t_width, 0.23 ex);
870         penpos4 (whatever, 180);        % 200
871         x4l - x4r = hair_thick;
872
873         x3r = 0.5 [x4r, x2r];
874 %       1.7 [x3l, x3r] = x4r;
875         y3r - y3l = 0.6 t_fatness;
876
877         save krul_p;
878         path krul_p;
879
880         krul_ang = 32;
881
882         pickup pencircle scaled hair_thick;
883
884         z5 = (x2l + t_fatness / 2, 2/3 ex);
885         lft x6 = x2l - uitschieter;
886         y6 = y5;                                % - 1/20 ex;
887         z7 = z5 + whatever * dir krul_ang;
888         up_angle = krul_ang;                    % = angle (z7-z5)
889         x7 = 5/10 kerning + x5;
890
891         krul_p := z4{up}
892                   ..tension 0.98.. z5
893                   .. z6
894                   .. z5{z7 - z5}
895                   -- z7;
896
897         z4' = point 0.85 of krul_p;
898         penpos4' (hair_thick, angle (direction 0.85 of krul_p) + 90);
899
900         % the body of the `t' and the bottom loop
901         fill z1r{dir (angle (z1l - z1r) + 30)}
902              .. z1l{-dir (angle (z1r - z1l) - 45)}
903              -- z2l{down}
904              ..tension (1 + .5 slant).. z3l{right}
905              .. z4l{up}
906              .. z4'l{direction 0.85 of krul_p}
907              -- z4'r{-direction 0.85 of krul_p}
908              .. z4r{down}
909              .. z3r{left}
910              ..tension (1.5 + .7 slant).. z2r{up}
911              -- cycle;
912
913         z5' = point 1.1 of krul_p;
914         penpos5' (hair_thick, angle (direction 1.1 of krul_p) + 90);
915         z5'' = point 1.5 of krul_p;
916         penpos5'' (hair_thick, angle (direction 1.5 of krul_p) + 90);
917         z5''' = point 1.8 of krul_p;
918         penpos5''' (hair_thick, angle (direction 1.8 of krul_p) + 90);
919         z6 = point 2 of krul_p;
920         penpos6 (hair_thick, angle (direction 2 of krul_p) + 90);
921         z6' = point 2.3 of krul_p;
922         penpos6' (hair_thick, angle (direction 2.3 of krul_p) + 90);
923         z6'' = point 2.6 of krul_p;
924         penpos6'' (hair_thick, angle (direction 2.6 of krul_p) + 90);
925         z6''' = point 2.9 of krul_p;
926         penpos6''' (hair_thick, angle (direction 2.9 of krul_p) + 90);
927         penpos7 (hair_thick, up_angle + 90);
928         z7' = point 3.2 of krul_p;
929         penpos7' (hair_thick, angle (direction 3.2 of krul_p) + 90);
930
931         % the left loop
932         penstroke z5'e{direction 1.1 of krul_p}
933                   .. z5''e{direction 1.5 of krul_p}
934                   .. z5'''e{direction 1.8 of krul_p}
935                   .. z6e{direction 2 of krul_p}
936                   .. z6'e{direction 2.3 of krul_p}
937                   .. z6''e{direction 2.6 of krul_p}
938                   .. {direction 2.9 of krul_p}z6'''e;
939
940         y9 = 3/4 ex;
941         x9 = x1 + kerning;
942         penpos9 (r_fatness, 0);
943
944         x10 = x9;
945         y10 = -0.3 linethickness;
946         penpos10 (r_fatness, 0);
947
948         penpos11 (hair_thick, -4);
949         z11r = z9r;
950
951         z13l = (x9l + r_width, y11 - linethickness);
952         penpos13 (r_flare, 180);
953
954         z15 = z13r - (bulb_size * r_fatness, 0);
955         z14 = 0.5 [z13l, z15] - (0, bulb_size * r_fatness);
956
957         save before, after;
958         path before, after;
959         before := z13l{up}
960                   .. {down}z11l;
961         after := z9r{up}
962                  .. z7r{z7' - z7}
963                  -- z7'r;
964         (u, v) = before intersectiontimes after;
965
966         save before_bulb, after_bulb;
967         path before_bulb, after_bulb;
968         before_bulb := z9r{up}
969                        ..tension 0.94.. z13r{down};
970         after_bulb := z13l{up}
971                       ..tension 1.06.. z15{down};
972         (u_bulb, v_bulb) = before_bulb intersectiontimes after_bulb;
973
974         % the connection between `t' and `r', the body of the `r',
975         % and the bulb
976         fill z7'l
977              -- z7l{z7 - z7'}
978              .. z9l{down}
979              -- simple_serif (z10l, z10r, -30)
980              -- z9r{up}
981              .. subpath (0, u_bulb) of before_bulb
982              .. subpath (v_bulb, infinity) of after_bulb
983              .. z14
984              .. z13l{up}
985              .. subpath (0, u) of before
986              .. subpath (v, infinity) of after
987              -- cycle;
988
989         penlabels (range 1 thru 15);
990         penlabels (4', 5', 5'', 5''', 6', 6'', 6''', 7');
991 fet_endchar;
992
993
994 def draw_heel =
995         save radius, thickness;
996         save pat;
997         path pat;
998
999         radius# := .5 staff_space#;
1000
1001         set_char_box (radius#, radius#, radius#, 2/3 staff_space#);
1002
1003         thickness := hround (1.5 linethickness);
1004
1005         pickup pencircle scaled thickness;
1006
1007         rt x1 = b;
1008         top y1 = h;
1009
1010         x2 =x1;
1011         y2 = 0;
1012
1013         x3 = 0;
1014         bot y3 = -d;
1015
1016         pat := top z3{right}
1017                .. lft z2{up}
1018                -- lft z1
1019                .. top z1
1020                .. rt z1
1021                -- rt z2{down}
1022                .. bot z3{left};
1023         pat := pat
1024                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
1025                -- cycle;
1026         fill pat;
1027 enddef;
1028
1029
1030 fet_beginchar ("left heel", "upedalheel");
1031         draw_heel;
1032         labels (1, 2, 3);
1033 fet_endchar;
1034
1035
1036 fet_beginchar ("right heel", "dpedalheel");
1037         draw_heel;
1038         y_mirror_char;
1039 fet_endchar;
1040
1041
1042 def draw_toe =
1043         save ht, wd, thickness;
1044
1045         thickness := 1.5 linethickness;
1046         ht# := 1.5 staff_space#;
1047         wd# := 1/3 ht#;
1048         define_pixels (ht, wd);
1049
1050         set_char_box (wd#, wd#, 0, ht#);
1051         draw_accent ((-h, -w), (0, w), thickness, 0.9);
1052         currentpicture := currentpicture rotated -90;
1053 enddef;
1054
1055
1056 fet_beginchar ("left toe", "upedaltoe");
1057         draw_toe;
1058 fet_endchar;
1059
1060
1061 fet_beginchar ("right toe", "dpedaltoe");
1062         draw_toe;
1063         y_mirror_char;
1064 fet_endchar;
1065
1066
1067 fet_beginchar ("Flageolet", "flageolet");
1068         save height, width, thickness, superness;
1069
1070         height# = 4/15 staffsize#;
1071         width# = height#;
1072         thickness# = blot_diameter#;
1073         define_pixels (height, width);
1074         define_whole_blacker_pixels (thickness);
1075
1076         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
1077
1078         penpos1 (thickness, 90);
1079         penpos2 (thickness, 180);
1080         penpos3 (thickness, 270);
1081         penpos4 (thickness, 0);
1082
1083         x1 = 0;
1084         y1r = h;
1085         x4r = w;
1086         x2r = -x4r;
1087         y2 = 0;
1088         y4 = y2;
1089         x3 = x1;
1090         y3r = -y1r;
1091
1092         penlabels (1, 2, 3, 4);
1093
1094         % mf doesn't handle pixel dropouts in outline objects, so we use
1095         % `draw' if not called by mpost
1096         if known miterlimit:
1097                 penstroke z1e
1098                           .. z2e
1099                           .. z3e
1100                           .. z4e
1101                           .. cycle;
1102         else:
1103                 pickup pencircle scaled thickness;
1104                 draw z1
1105                      .. z2
1106                      .. z3
1107                      .. z4
1108                      .. cycle;
1109         fi;
1110 fet_endchar;
1111
1112
1113 %
1114 % TODO:  ARGRGHGH code dup.
1115 %
1116
1117 fet_beginchar ("Segno", "segno");
1118         save thin, thick, ball_diam, darkness, pointheight;
1119         save wd, ht, thick_nibangle, ball_nib_thick;
1120         save turndir;
1121         pair turndir;
1122
1123         ht# = 3 staff_space#;
1124         wd# = 2 staff_space#;
1125         darkness = .08 staff_space + 0.4 linethickness;
1126
1127         set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2);
1128
1129         thick_nibangle = 30;
1130         thick = 3 darkness;
1131         thin = darkness;
1132         ball_nib_thick = 2.7 darkness;
1133         ball_diam = ball_nib_thick + (w - ball_nib_thick) / 10;
1134         pointheight = 2 linethickness;
1135
1136         y3l = h;
1137         2 x3 = x2 + x4;
1138         x4 = 0;
1139         y4 = y2;
1140         y2l = .6 h;
1141         x2l = -b;
1142         z1 = (0, 0);
1143
1144         penpos1 (thick, 2 thick_nibangle);
1145         penpos2 (thick, thick_nibangle);
1146         penpos3 (thin, -90);
1147         penpos4 (ball_nib_thick, 180 - thick_nibangle);
1148
1149         save swoosh, ploop;
1150         path swoosh, ploop;
1151
1152         swoosh := z1l{curl 0}
1153                   .. z2l
1154                   .. z3l{right}
1155                   .. {down}z4l
1156                   -- z4r
1157                   .. z3r{left}
1158                   .. z2r{down};
1159         fill swoosh
1160              .. (swoosh scaled -1)
1161              .. cycle;
1162
1163         y5r = y4;
1164         x5r = x4l - ball_diam / 2;
1165         z6r = z5r;
1166
1167         penpos5 (1.6 ball_diam / 2, 100);
1168         penpos6 (ball_diam / 2, 240);
1169
1170         ploop := z4l{down}
1171                  .. z5l
1172                  .. z6l
1173                  -- cycle;
1174         fill ploop;
1175         fill ploop scaled -1;
1176
1177         penpos7 (2 thin, 0);
1178         z7l = (-b, -d);
1179         penpos8 (2 thin, 0);
1180         z8r = (w, h);
1181
1182         penstroke z7e
1183                   -- z8e;
1184
1185         pickup pencircle scaled 2 thin;
1186         drawdot (-x2r, pointheight);
1187         drawdot (x2r, -pointheight);
1188
1189         penlabels (range 1 thru 8);
1190 fet_endchar;
1191
1192
1193 fet_beginchar ("Varied Segno", "varsegno");
1194         save ht, wd, loopdist, loopangle;
1195         save thin, med, thick;
1196         save bulbradius, center;
1197         pair center;
1198
1199         ht# = 8 staff_space#;
1200         wd# = 2.5 staff_space#;
1201
1202         set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2);
1203         % set_char_box (0, 0, ht# / 2, ht# / 2);
1204
1205         loopdist = 4/3 staff_space;
1206         loopangle = 35;
1207
1208         thick = 1/2 staff_space;
1209         med = 1/4 staff_space;
1210         thin = 1/10 staff_space;
1211
1212         x1 = staff_space;
1213         y1 = 13/4 staff_space;
1214         penpos1 (med, 210);
1215
1216         z2l = (0, 4 staff_space);
1217         penpos2 (med, 270 - loopangle);
1218
1219         x3 = -x1;
1220         y3 = y1 + 1/4 staff_space;
1221         penpos3 (med, 270 + loopangle);
1222
1223         center = (0, 2 staff_space);
1224         z4 = (3/4 staff_space, 2 staff_space)
1225              rotatedabout (center, 180 - loopangle);
1226         z5 = 2[z4, center];
1227         x9 = x4;
1228         y9 = y4 - 2 loopdist;
1229         x10 = x5;
1230         y10 = y5 - 2 loopdist;
1231
1232         penpos4 (thick, 90 - loopangle);
1233         penpos5 (thick, 90 - loopangle);
1234         penpos9 (thick, 90 - loopangle);
1235         penpos10 (thick, 90 - loopangle);
1236
1237         z6 = (4/3 staff_space, 4/3 staff_space)
1238              rotatedabout (2/3 center, -loopangle);
1239         x11 = x6;
1240         y11 = y6 - 2 loopdist;
1241
1242         penpos6 (thin, -loopangle);
1243         penpos11 (thin, -loopangle);
1244
1245         z7 = 1/3 center;
1246         penpos7 (thick, 270 - loopangle);
1247
1248         z8 = (4/3 staff_space, 0) rotated (180 - loopangle);
1249         penpos8 (thin, -loopangle);
1250
1251         z12 = -center;
1252         penpos12 (thick, 270 - loopangle);
1253
1254         z1' = 4/3[z1l, z1r];
1255         bulbradius = length (z1l - z1');
1256         pickup pencircle scaled 2 bulbradius;
1257
1258         save se_dir, nw_dir;
1259         pair se_dir, nw_dir;
1260         se_dir := dir -loopangle;
1261         nw_dir := dir (180 - loopangle);
1262
1263         draw_bulb (-1, z1r, z1l, bulbradius, .8);
1264
1265         penstroke z1e
1266                   .. z2e
1267                   .. z3e
1268                   ... {se_dir}z4e
1269                   -- z5e{se_dir}
1270                   ... z6e
1271                   ... z7e{nw_dir}
1272                   ... z8e
1273                   ... {se_dir}z9e
1274                   -- z10e{se_dir}
1275                   ... z11e
1276                   ... {nw_dir}z12e;
1277         addto currentpicture also currentpicture scaled -1;
1278
1279         penlabels (1, 1', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
1280 fet_endchar;
1281
1282
1283 fet_beginchar ("Coda", "coda");
1284         save stickout, thin, thick, codawidth, codaheight;
1285
1286         stickout# = 0.35 staff_space#;
1287         codawidth# = 2/3 staff_space#;
1288         codaheight# = staff_space#;
1289         define_pixels (codawidth, codaheight);
1290
1291         set_char_box (codawidth# + stickout#, codawidth# + stickout#,
1292                       codaheight# + stickout#, codaheight# + stickout#);
1293
1294         thin = 1.2 linethickness;
1295         0.1 (codaheight - 2 thin) = (codawidth - 2 thick);
1296
1297         penpos1 (thick, 0);
1298         penpos2 (thin, -90);
1299         penpos3 (thick, -180);
1300         penpos4 (thin, -270);
1301
1302         x1l = -codawidth;
1303         y2l = codaheight;
1304         y1 = 0;
1305         x2 = 0;
1306         z3 = -z1;
1307         z4 = -z2;
1308
1309         penlabels (1, 2, 3, 4);
1310
1311         fill z1l{up}
1312              .. z2l{right}
1313              .. z3l{down}
1314              .. z4l{left}
1315              .. cycle;
1316         unfill z1r{up}
1317                .. z2r{right}
1318                .. z3r{down}
1319                .. z4r{left}
1320                .. cycle;
1321
1322         draw_gridline ((0, -h), (0, h), thin);
1323         draw_gridline ((-w, 0), (w, 0), thin);
1324 fet_endchar;
1325
1326
1327 fet_beginchar ("Varied Coda", "varcoda");
1328         save thin, thick, codawidth, codaheight;
1329         thin# = 1.2 linethickness#;
1330         thick# = 1.0 linethickness# + 0.25 staff_space#;
1331         codawidth# = 2/3 staff_space#;
1332         codaheight# = staff_space#;
1333         define_pixels (thin, thick, codawidth, codaheight);
1334
1335         set_char_box (codawidth# + thick#, codawidth# + thick#,
1336                       codaheight# + thick#, codaheight# + thick#);
1337
1338         x1 = -codawidth + thick - .5 blot_diameter;
1339         y1 = y2 - thin;
1340         x2 = codawidth - thick + .5 blot_diameter;
1341         y2 = codaheight;
1342         draw_square_block (z1, z2);
1343
1344         x3 = -codawidth;
1345         y3 = -codaheight;
1346         x4 = x3 + thick;
1347         y4 = y2;
1348         draw_block (z3, z4);
1349
1350         labels (1, 2, 3, 4);
1351
1352         addto currentpicture also currentpicture scaled -1;
1353
1354         draw_gridline ((0, -h), (0, h), thin);
1355         draw_gridline ((-w, 0), (w, 0), thin);
1356 fet_endchar;
1357
1358
1359 def draw_comma =
1360         save alpha, thick, thin, ht;
1361
1362         alpha := 35;
1363         thin# = 1.2 linethickness#;
1364         thick# = 3 linethickness#;
1365         ht# = .6 staff_space#;
1366         define_pixels (thin, thick, ht);
1367
1368         set_char_box (0, .5 staff_space#, ht#, ht#);
1369
1370         penpos1 (thick, alpha);
1371         penpos2 (thick, alpha + 90);
1372         penpos3 (thin, 180 - alpha);
1373         penpos4 (thin, 90 - alpha);
1374
1375         x3r = 0;
1376         x1l = x3l;
1377         y2r = -y4l = h;
1378         z1 = z2;
1379         z3 = z4;
1380
1381         fill z1l{dir (alpha + 90)}
1382              .. z2r{dir alpha}
1383              .. z1r{dir (alpha - 90)}
1384              .. z3l{dir (270 - alpha)}
1385              .. z4l{dir (180 - alpha)}
1386              .. z3r{dir (90-alpha)}
1387              .. cycle;
1388 enddef;
1389
1390
1391 fet_beginchar ("Right Comma", "rcomma");
1392         draw_comma;
1393         penlabels (1, 2, 3, 4);
1394 fet_endchar;
1395
1396
1397 fet_beginchar ("Left Comma", "lcomma");
1398         draw_comma;
1399         xy_mirror_char;
1400 fet_endchar;
1401
1402
1403 def draw_varcomma =
1404         save thick, thin, ht, wd, alpha;
1405
1406         alpha := 35;
1407         thin# = 1.2 linethickness#;
1408         thick# = 3 linethickness#;
1409         ht# = .6 staff_space#;
1410         wd# = .25 staff_space#;
1411         define_pixels (thin, thick, ht, alpha);
1412
1413         set_char_box (wd#, wd#, ht#, ht#);
1414
1415         z1 = (-b, -d);
1416         z2 = (w, h);
1417
1418         draw_brush (z1, thin, z2, thick);
1419 enddef;
1420
1421
1422 fet_beginchar ("Right Varied Comma", "rvarcomma");
1423         draw_varcomma;
1424         labels (1, 2);
1425 fet_endchar;
1426
1427
1428 fet_beginchar ("Left Varied Comma", "lvarcomma");
1429         draw_varcomma;
1430         xy_mirror_char;
1431 fet_endchar;
1432
1433
1434 thick# := 1/24 designsize;
1435 define_blacker_pixels (thick);
1436
1437 rthin := 0.075 * staff_space + 0.5 linethickness;
1438 rthick := 2 thick + rthin;
1439
1440
1441 def draw_arpeggio =
1442         save alpha;
1443         save ne, nw, se, sw;
1444         save x, y;
1445         pair ne, nw, se, sw;
1446
1447         alpha := -40;
1448
1449         nw = dir (alpha + 180);
1450         ne = dir (alpha + 90);
1451         se = dir alpha;
1452         sw = dir (alpha - 90);
1453
1454         penpos1 (rthin, alpha + 90);
1455         penpos2 (5/4 rthick, alpha);
1456         penpos3 (3/4 rthick, alpha);
1457         penpos4 (5/4 rthick, alpha);
1458         penpos5 (rthin, alpha + 90);
1459
1460         z1 = (width / 2, height) - overshoot * se;
1461         z2 = 2 [z4, (width / 2, height / 2)];
1462         z3 = 1/2 [z2, z4];
1463         x4 = 2/8 staff_space;
1464         y4 = rthin;
1465
1466         z5 = 2 [z1, (width / 2, height / 2)];
1467         z6 = z2l + 1/2 rthin * sw;
1468         z7 = z4l + 1/2 rthin * sw + 1/2 rthin * se;
1469         z8 = 2 [z6, (width / 2, height / 2)];
1470         z9 = 2 [z7, (width / 2, height / 2)];
1471
1472         fill z1l{se}
1473              -- z6
1474              .. z3l
1475              .. z7{se}
1476              -- z5l
1477              .. z5r{nw}
1478              -- z8
1479              .. z3r
1480              .. z9{nw}
1481              -- z1r
1482              .. cycle;
1483 enddef;
1484
1485
1486 fet_beginchar ("Arpeggio", "arpeggio");
1487         begingroup;
1488         save height, overshoot, width;
1489         height# := staff_space#;
1490         width# := 0.8 * height#;
1491         overshoot# := 0.25 * staff_space#;
1492         define_pixels (height, overshoot, width);
1493         set_char_box (0, width#, 0, height#);
1494         draw_arpeggio;
1495         penlabels (range 1 thru 9);
1496
1497         draw_staff_if_debugging (-2, 2);
1498         endgroup;
1499 fet_endchar;
1500
1501
1502 %
1503 % Extendable Trill symbol.
1504 % Not yet used
1505 % Rename me to Trill, rename Trill to Tr?
1506 %
1507
1508 fet_beginchar ("Trill_element", "trill_element");
1509         begingroup;
1510         save height, overshoot, width;
1511         height# = staff_space#;
1512         width# = 0.8 height#;
1513         overshoot# = 0.25 staff_space#;
1514         define_pixels (height, overshoot, width);
1515
1516         set_char_box (0, height#, 0, width#);
1517         draw_arpeggio;
1518
1519         currentpicture := currentpicture shifted -(width / 2, height / 2);
1520         currentpicture := currentpicture rotated 90;
1521         currentpicture := currentpicture shifted (height / 2, width / 2);
1522         endgroup;
1523 fet_endchar;
1524
1525
1526 %
1527 % Arpeggio arrow by Chris Jackson <chris@fluffhouse.org.uk>
1528 %
1529
1530 def draw_arpeggio_arrow =
1531         save thinness, height, width, overshoot;
1532         save nw, ne, se, sw;
1533         save alpha;
1534         save before_left, before_right, after_left, after_right;
1535         save u_left, v_left, u_right, v_right;
1536         pair nw, ne, se, sw;
1537         path before_left, before_right, after_left, after_right;
1538
1539         height# = staff_space#;
1540         width# = 0.8 height#;
1541         overshoot# = 0.25 staff_space#;
1542         define_pixels (height, overshoot, width);
1543
1544         set_char_box (0, width#, 0, height#);
1545
1546         alpha := -40;
1547         nw = dir (alpha + 180);
1548         ne = dir (alpha + 90);
1549         se = dir alpha;
1550         sw = dir (alpha - 90);
1551
1552         penpos1 (rthin, alpha + 90);
1553         penpos2 (5/4 rthick, alpha);
1554         penpos3 (5/4 rthick, 0);
1555
1556         z1 = (width / 2, height) - overshoot * se; % numbering is consistent
1557                                                    % with the arpeggio symbol
1558         z2 = 2 [z4, (width / 2, height / 2)];
1559         z3 = (0.5 width, 0.5 height);
1560         z4 = (0.25 staff_space, rthin);
1561         z6 = z2l + 1/2 rthin * sw;
1562         z9 = (width / 2, height) + overshoot * se;
1563
1564         pickup pencircle scaled vround (0.5 rthin);
1565
1566         bot z10 = (0.5 w, 0);
1567         lft z11 = (0.5 w - hround (0.8 w), 0.8 h);
1568         rt z12 = (0.5 w + hround (0.8 w), 0.8 h);
1569
1570         before_left := z1l
1571                        -- z6{z6 - z1l}
1572                        .. {down}z3l;
1573         after_left := (z3 + (0, -0.25 rthin / cosd (angle (nw))))
1574                       -- (z11 + 0.25 rthin * ne);
1575         (u_left, v_left) = before_left intersectiontimes after_left;
1576
1577         before_right := (z12 + 0.25 rthin * nw)
1578                         -- (z3 + (0, -0.25 rthin / cosd (angle (nw))));
1579         after_right := z3r{up}
1580                        .. z9{z1r - z9}
1581                        -- z1r;
1582         (u_right, v_right) = before_right intersectiontimes after_right;
1583
1584         fill subpath (0, u_left) of before_left
1585              .. subpath (v_left, infinity) of after_left
1586              .. top z11
1587              .. lft z11
1588              .. {dir -50}(z11 + 0.25 rthin * sw)
1589              .. (z10 + 0.25 rthin * sw){dir -70}
1590              .. bot z10
1591              .. {dir 70}(z10 + 0.25 rthin * se)
1592              .. (z12 + 0.25 rthin * se){dir 50}
1593              .. rt z12
1594              .. top z12
1595              .. subpath (0, u_right) of before_right
1596              .. subpath (v_right, infinity) of after_right
1597              .. cycle;
1598
1599         % mf doesn't handle pixel dropouts in outline objects, so we use
1600         % `draw' if not called by mpost
1601         if not known miterlimit:
1602                 pickup pencircle scaled 0.7 rthin;
1603                 draw z1
1604                      -- (z9 + 0.5 rthin * dir (alpha - 90));
1605         fi;
1606 enddef;
1607
1608
1609 fet_beginchar ("Arpeggio arrow down", "arpeggio.arrow.M1");
1610         draw_arpeggio_arrow;
1611         penlabels (range 1 thru 12);
1612 fet_endchar;
1613
1614
1615 fet_beginchar ("Arpeggio arrow up", "arpeggio.arrow.1");
1616         draw_arpeggio_arrow;
1617         currentpicture := currentpicture scaled -1
1618                                          shifted (w - feta_eps, h - feta_eps);
1619 fet_endchar;
1620
1621
1622 % Hmm
1623 input feta-trills;
1624
1625
1626 %
1627 % Railroad tracks.  We define two variants of these -- both as slightly
1628 % tapered, comma-shaped curves and as two straight parallel slashes.
1629 %
1630
1631 fet_beginchar ("Curved caesura", "caesura.curved");
1632         save slant, space_between, clearance;
1633         save alpha, pat;
1634         save botthick, topthick;
1635         save krom;
1636         path pat;
1637
1638         botthick = 1.5 linethickness;
1639         topthick = 2.5 linethickness;
1640
1641         pickup pencircle scaled botthick;
1642
1643         slant = 3.5;
1644         space_between# = 0.6 staff_space#;
1645         clearance# = 0.2 staff_space#;
1646         height# = 1.2 staff_space#;
1647
1648         set_char_box (0, 2.0 staff_space#,
1649                       staff_space# - clearance#, height#);
1650         define_pixels (clearance, height);
1651         define_whole_pixels (space_between);
1652
1653         bot y1 = -d;
1654         top y2 = h;
1655
1656         lft x1 = 0;
1657         x2 = (y2 - y1) / slant;
1658
1659         krom = 10;
1660
1661         alpha = angle (z2 - z1);
1662         penpos1 (botthick, alpha - krom);
1663         penpos3 (botthick, alpha - krom + 90);
1664
1665         penpos2 (topthick, alpha + krom);
1666         penpos4 (topthick, alpha + krom + 90);
1667
1668         z3 = z1;
1669         z4 = z2;
1670
1671         penlabels (1, 2, 3, 4);
1672
1673         pat := z3r{(z1r - z1l)}
1674                .. z4r{z2r-z2l}
1675                .. z2r{z4l-z4r}
1676                .. z4l{z2l-z2r}
1677                .. z3l{z1l-z1r}
1678                .. z1l{z3r-z3l}
1679                .. cycle;
1680         fill pat;
1681         fill pat shifted (space_between, 0);
1682 fet_endchar;
1683
1684
1685 fet_beginchar ("Straight caesura", "caesura.straight");
1686         save slant, space_between, clearance;
1687         save thick, ne, pat;
1688         path pat;
1689         pair ne;
1690
1691         slant = 2.0;
1692         thick = 2.88 linethickness;
1693
1694         space_between# = 0.56 staff_space#;
1695         clearance# = 0.2 staff_space#;
1696
1697         set_char_box (0, 2.0 staff_space#,
1698                       staff_space# - clearance#, 1.2 staff_space#);
1699         define_whole_pixels (space_between);
1700
1701         x1 = 0;
1702         x2 = x1 + thick;
1703         y1 = y2 = -d;
1704
1705         x3 = x4 + thick;
1706         x4 = x1 + (h + d) / slant;
1707         y3 = y4 = h;
1708
1709         ne = unitvector (z4 - z1);
1710
1711         z1a = z1 + blot_diameter * ne;
1712         z1b = z1 + blot_diameter * right;
1713         z2a = z2 + blot_diameter * ne;
1714         z2b = z2 + blot_diameter * left;
1715
1716         z3a = z3 - blot_diameter * ne;
1717         z3b = z3 + blot_diameter * left;
1718         z4a = z4 - blot_diameter * ne;
1719         z4b = z4 + blot_diameter * right;
1720
1721         pat = z1a{-ne}
1722               .. {right}z1b
1723               -- z2b{right}
1724               .. {ne}z2a
1725               -- z3a{ne}
1726               .. {left}z3b
1727               -- z4b{left}
1728               .. {-ne}z4a
1729               -- cycle;
1730
1731         fill pat;
1732         fill pat shifted (space_between, 0);
1733
1734         labels(range 1 thru 4);
1735         labels(1a, 1b, 2a, 2b, 3a, 3b, 4a, 4b);
1736 fet_endchar;
1737
1738
1739 % A tick character to use instead of a comma or caesura as a breath mark.
1740 % Very common in vocal notation.
1741
1742 fet_beginchar ("Tick mark", "tickmark");
1743         save end_rad, bot_rad, pat, x_centre, x_extent;
1744         path pat;
1745
1746         end_rad = linethickness / 2;
1747         bot_rad = linethickness;
1748
1749         x_centre# = 0.6 staff_space#;
1750         x_extent# = 1.7 staff_space#;
1751
1752         define_pixels (x_centre, x_extent);
1753
1754         pickup pencircle scaled end_rad;
1755
1756         lft x1 = -x_centre;
1757         y1 = 0.8 staff_space;
1758
1759         x2 = 0;
1760         y2l = 0;
1761
1762         top rt z3 = (x_extent - x_centre, x_extent);
1763
1764         x4 = lft x1;
1765         y4 = staff_space;
1766
1767         penpos2 (0.4 staff_space, 90);
1768         penpos3 (end_rad, angle(z4 - z3) + 90);
1769         penpos1 (end_rad, angle(z2 - z1) + 90);
1770
1771         pat = z1r
1772               .. top z1
1773               .. z1l{z2 - z1}
1774               .. {z2 - (z1 + (0.3 staff_space,0))}z2l + (-bot_rad, bot_rad)
1775               .. z2l
1776               .. z2l + (bot_rad, bot_rad){z3 - (0.6 staff_space, 0) - z2}
1777               .. {z3 - z4}z3r
1778               .. rt z3
1779               .. {z4 - z3}z3l
1780               .. {z2 - (z3 - (0.6 staff_space, 0))}rt z2r
1781               .. {z1 - z2}lft z2r{z1 - z2}
1782               .. cycle;
1783         fill pat;
1784
1785         set_char_box (x_centre#, x_extent# - x_centre#, 0, x_extent#);
1786
1787         penlabels (1, 2, 3);
1788         labels (4);
1789 fet_endchar;
1790
1791
1792 fet_beginchar ("snap pizzicato (Bartok pizzicato)", "snappizzicato");
1793         save height, width, thickness, superness;
1794
1795         height# = 4/15 staffsize#;
1796         width# = height#;
1797         thickness# = 1.3 linethickness#;
1798         define_pixels (height, width);
1799         define_whole_blacker_pixels (thickness);
1800
1801         set_char_box (width# / 2, width# / 2, height# / 2, height# * 3 / 4);
1802
1803         penpos1 (thickness, 90);
1804         penpos2 (thickness, 180);
1805         penpos3 (thickness, 270);
1806         penpos4 (thickness, 0);
1807
1808         x1 = 0;
1809         y1r = height / 2;
1810         x3 = x1;
1811         y3r = -y1r;
1812         x4r = width / 2;
1813         y4 = 0;
1814         x2r = -x4r;
1815         y2 = y4;
1816
1817         penlabels (1, 2, 3, 4);
1818
1819         % mf doesn't handle pixel dropouts in outline objects, so we use
1820         % `draw' if not called by mpost
1821         if known miterlimit:
1822                 penstroke z1e
1823                           .. z2e
1824                           .. z3e
1825                           .. z4e
1826                           .. cycle;
1827         else:
1828                 pickup pencircle scaled thickness;
1829                 draw z1
1830                      .. z2
1831                      .. z3
1832                      .. z4
1833                      .. cycle;
1834         fi;
1835
1836         z5 = (0, 0);
1837         z6 = (x5, 1.5 y1r);
1838
1839         draw_gridline (z5, z6, thickness);
1840
1841         labels (5, 6);
1842 fet_endchar;
1843
1844 fet_endgroup ("scripts");