]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-schrift.mf
* mf/feta-accordion.mf, mf/feta-klef.mf, mf/feta-pendaal.mf,
[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_size;
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
34         dot_size# = 8/6 crook_fatness#;
35         define_whole_blacker_pixels (dot_size);
36
37         penpos1 (crook_thinness, 0);
38         penpos2 (crook_fatness, -90);
39         z1 = (-radius, 0);
40         z2 = (0, radius);
41
42         pat := z2l{left}
43                .. z1l{dir (-alpha - 90)}
44                .. {dir (90 - alpha)}z1r
45                .. {right}z2r;
46         pat := pat
47                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
48                -- cycle;
49         fill pat;
50
51         pickup pencircle scaled dot_size;
52         x4 = 0;
53         bot y4 = vround (-crook_thinness / 2);
54         drawdot z4;
55 enddef;
56
57
58 fet_beginchar ("fermata up", "ufermata");
59         draw_fermata;
60         penlabels (1, 2, 4);
61 fet_endchar;
62
63
64 fet_beginchar ("fermata down", "dfermata");
65         draw_fermata;
66         y_mirror_char;
67 fet_endchar;
68
69
70 def draw_short_fermata =
71         save fat_factor, thinness, dot_size;
72         save left_dist, right_dist, se, ne;
73         pair left_dist, right_dist, se, ne;
74
75         set_char_box (staff_space#, staff_space#, 0, 2.2 staff_space#);
76
77         dot_size# = 0.266 staff_space# + 2.666 linethickness#;
78         define_whole_blacker_pixels (dot_size);
79
80         fat_factor = .11;
81         thinness = 1.5 linethickness;
82
83         pickup pencircle scaled thinness;
84
85         rt x2 = w;
86         lft x5 = -b;
87         bot y5 = 0;
88         top y3 = h;
89         y1 = y2 = y5;
90
91         x3 = 0;
92         z1 - z4 = whatever * (charwd, -charht);
93         z4 = fat_factor [z3, z5];
94
95         ne = unitvector (z3 - z5);
96         se = unitvector (z2 - z3);
97
98         left_dist = (ne rotated 90) * 0.5 thinness;
99         right_dist = (se rotated 90) * 0.5 thinness;
100
101         fill bot z5{right}
102              .. (z5 - left_dist){ne}
103              -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
104                   ((z1 - right_dist) -- (z4 - right_dist)))
105              -- (z1 - right_dist){se}
106              .. bot z1{right}
107              -- bot z2{right}
108              .. (z2 + right_dist){-se}
109              -- (z3 + right_dist){-se}
110              .. top z3
111              .. (z3 + left_dist){-ne}
112              -- (z5 + left_dist){-ne}
113              .. cycle;
114
115         pickup pencircle scaled dot_size;
116
117         x1 - 2x6 = x2;
118         bot y6 = -d;
119
120         drawdot z6;
121 enddef;
122
123 fet_beginchar ("short fermata up", "ushortfermata");
124         draw_short_fermata;
125         labels (1, 2, 3, 4, 5, 6);
126 fet_endchar;
127
128
129 fet_beginchar ("short fermata down", "dshortfermata");
130         draw_short_fermata;
131         xy_mirror_char;
132 fet_endchar;
133
134
135 def draw_long_fermata =
136         save stemthick, beamheight, dot_size, wd;
137         save pat;
138         path pat;
139
140         wd# = 2.5 staff_space#;
141         stemthick = hround (1.5 linethickness);
142         beamheight = 0.3 staff_space + linethickness;
143         dot_size# = 0.266 staff_space# + 2.666 * linethickness#;
144         define_pixels (wd);
145         define_whole_blacker_pixels (dot_size);
146
147         set_char_box (wd# / 2, wd# / 2, 0, 3/2 staff_space#);
148
149         pickup pencircle scaled blot_diameter;
150
151         top y1 = h;
152         lft x1 = -b;
153
154         pat := top z1{left}
155                .. {down}lft z1;
156
157         pickup pencircle scaled stemthick;
158
159         x2 = -b + stemthick;
160         y2 = h - beamheight;
161         lft x3 = -b;
162         bot y3 = -d;
163
164         pat := pat
165                -- lft z3
166                .. bot z3
167                .. rt z3
168                -- z2;
169         pat := pat
170                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
171                -- cycle;
172
173         fill pat;
174
175         pickup pencircle scaled dot_size;
176
177         x4 = 0;
178         bot y4 = -d;
179
180         drawdot z4;
181 enddef;
182
183
184 fet_beginchar ("long fermata up", "ulongfermata");
185         draw_long_fermata;
186         labels (1, 2, 3, 4);
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_size;
200         save opat, ipat;
201         path opat, ipat;
202
203         ihwd# = 1.0 staff_space#;
204         ohwd# = 1.5 staff_space#;
205         iht# = 0.9 staff_space#;
206         oht# = 1.6 staff_space#;
207         define_pixels (ihwd, ohwd, iht, oht)
208
209         stemthick = hround (1.5 linethickness);
210         ibeamheight# = 0.3 staff_space#;
211         obeamheight# = 0.5 staff_space#;
212         define_pixels (ibeamheight, obeamheight);
213
214         dot_size# = (iht# - ibeamheight#) * 8/10;
215         define_whole_blacker_pixels (dot_size);
216
217         set_char_box (ohwd#, ohwd#, 0, oht#);
218
219         pickup pencircle scaled blot_diameter;
220
221         top y1 = oht;
222         lft x1 = -ohwd;
223         top y11 = iht;
224         lft x11 = -ihwd;
225
226         opat := top z1{left}
227                 .. {down}lft z1;
228         ipat := top z11{left}
229                 .. {down}lft z11;
230
231         pickup pencircle scaled stemthick;
232
233         x2 = -ohwd + stemthick;
234         y2 = oht - obeamheight;
235         lft x3 = -ohwd;
236         bot y3 = 0;
237         x12 = -ihwd + stemthick;
238         y12 = iht - ibeamheight;
239         lft x13 = -ihwd;
240         bot y13 = 0;
241
242         opat := opat
243                 -- lft z3
244                 .. bot z3
245                 .. rt z3
246                 -- z2;
247         opat := opat
248                 -- reverse opat xscaled -1 shifted (-feta_eps, 0)
249                 -- cycle;
250         ipat := ipat
251                 -- lft z13
252                 .. bot z13
253                 .. rt z13
254                 -- z12;
255         ipat := ipat
256                 -- reverse ipat xscaled -1 shifted (-feta_eps, 0)
257                 -- cycle;
258
259         fill opat;
260         fill ipat;
261
262         pickup pencircle scaled dot_size;
263
264         x4 = 0;
265         bot y4 = -d;
266
267         drawdot z4;
268 enddef;
269
270
271 fet_beginchar ("very long fermata up", "uverylongfermata");
272         draw_very_long_fermata;
273         labels (1, 2, 3, 11, 12, 13, 4);
274 fet_endchar;
275
276
277 fet_beginchar ("very long fermata down", "dverylongfermata");
278         draw_very_long_fermata;
279         y_mirror_char;
280 fet_endchar;
281
282
283 %
284 % Thumbs are used in cello music.
285 % TODO : thumbs should look like the finger-font and should be placed in
286 % the same way in the score.
287 %
288
289 fet_beginchar ("Thumb", "thumb");
290         save thin, height, width, thick, depth;
291         height# = 5/4 width#;
292         height# = staff_space#;
293         depth# = 1.6 (height# / 2);
294
295         set_char_box (width# / 2, width# / 2, depth#, height# / 2);
296
297         define_pixels (height, width);
298
299         thin = .6 linethickness + 0.06 staff_space;
300         2 thick + 0.5 (height - 2 thin) = width;
301
302         penpos1 (thick, 0);
303         penpos2 (thin, 90);
304         penpos3 (thick, 180);
305         penpos4 (thin, 270);
306         z1r = (w, 0);
307         z2r = (0, h);
308         z3r = (-w, 0);
309         z4r = (0, -h);
310
311         penlabels (1, 2, 3, 4);
312
313         penstroke z1e{up}
314                   .. z2e{left}
315                   .. z3e{down}
316                   .. z4e{right}
317                   .. cycle;
318
319         save brush_thick;
320         y5 = -d + brush_thick / 2;
321         brush_thick = 0.9 thick;
322         x5 = 0;
323
324         labels (5);
325
326         draw_brush (z4r, 1.4 thin, z5, brush_thick);
327 fet_endchar;
328
329
330 %
331 % FIXME: rounded endings
332 %
333 % `\accent' is TeX reserved.
334 %
335
336 def draw_accent (expr bottom_left, top_right, thickness, diminish) =
337         pickup pencircle scaled thickness;
338
339         lft x1 = xpart bottom_left;
340         top y1 = ypart top_right;
341         lft x6 = xpart bottom_left;
342         bot y6 = ypart bottom_left;
343
344         rt z4 = (xpart top_right, (ypart top_right + ypart bottom_left) / 2);
345         x5 = x3 = (xpart top_right + xpart bottom_left) / 2
346                   - linethickness + 0.1 staff_space;
347         z3 = whatever [z1, z4];
348         z5 = whatever [z6, z4];
349
350         penpos1 (thickness, angle (z3 - z1) + 90);
351         penpos3 (thickness, angle (z3 - z1) + 90);
352         penpos4 (thickness, 90);
353         penpos5 (thickness, angle (z6 - z5) + 90);
354         penpos6 (thickness, angle (z6 - z5) + 90);
355
356         x4 - x7 = diminish * thickness;
357         y7 = y4;
358
359         fill z1l
360              -- z3l
361              -- z7
362              -- z5l
363              -- z6l
364              .. lft z6{down}
365              .. bot z6
366              .. z6r
367              -- z4l
368              ..tension 0.8.. rt z4
369              ..tension 0.8.. z4r
370              -- z1r
371              .. top z1
372              .. lft z1{down}
373              .. cycle;
374 enddef;
375
376
377 fet_beginchar ("> accent", "sforzato");
378         set_char_box (.9 staff_space#, .9 staff_space#,
379                       .5 staff_space#, .5 staff_space#);
380
381         draw_accent ((-w, -d), (w, h),
382                      0.05 staff_space + linethickness, 0.6);
383         penlabels (1, 3, 4, 5, 6);
384         labels (7);
385 fet_endchar;
386
387
388 fet_beginchar ("espr", "espr");
389         set_char_box (1.9 staff_space#, 1.9 staff_space#,
390                       .5 staff_space#, .5 staff_space#);
391
392         draw_accent ((w - 1.78 staff_space, -d), (w, h),
393                      0.05 staff_space + linethickness, 0.6);
394         addto currentpicture also currentpicture xscaled -1;
395 fet_endchar;
396
397
398 fet_beginchar ("staccato dot", "staccato");
399         save radius;
400         radius# = 0.20 * staff_space#;
401         define_whole_pixels (radius);
402
403         pickup pencircle scaled 2 radius;
404         drawdot (0, 0);
405
406         set_char_box (radius#, radius#, radius#, radius#);
407 fet_endchar;
408
409
410 def draw_staccatissimo =
411         save radius, height;
412         height# = .8 staff_space#;
413         radius# = linethickness# + .1 staff_space#;
414         define_whole_blacker_pixels (radius);
415         define_pixels (height);
416
417         draw_brush ((0, 0), linethickness, (0, height), 2 radius);
418
419         set_char_box (radius#, radius#,
420                       blot_diameter# / 2, height# + radius#);
421 enddef;
422
423
424 fet_beginchar ("staccatissimo/martellato up", "ustaccatissimo");
425         draw_staccatissimo;
426 fet_endchar;
427
428
429 fet_beginchar ("staccatissimo/martellato down", "dstaccatissimo");
430         draw_staccatissimo;
431         y_mirror_char;
432 fet_endchar;
433
434
435 fet_beginchar ("portato/single tenuto", "tenuto");
436         save thick;
437         thick# = 1.6 linethickness#;
438         define_whole_blacker_pixels (thick);
439
440         set_char_box (.6 staff_space#, .6 staff_space#,
441                       thick# / 2, thick# / 2);
442
443         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
444 fet_endchar;
445
446
447 def draw_portato =
448         save thick, dot_size;
449         thick# = 1.4 linethickness#;
450         dot_size# = 2.4 linethickness# + 0.08 staff_space#;
451         define_whole_blacker_pixels (thick, dot_size);
452
453         set_char_box (.6 staff_space#, .6 staff_space#,
454                       thick# / 2, .5 staff_space# + .5 dot_size#);
455
456         draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
457
458         pickup pencircle scaled dot_size;
459         drawdot (0, h);
460 enddef;
461
462
463 fet_beginchar ("portato/tenuto with staccato", "uportato");
464         draw_portato;
465 fet_endchar;
466
467
468 fet_beginchar ("portato/tenuto with staccato", "dportato");
469         draw_portato;
470         y_mirror_char
471 fet_endchar;
472
473
474 def draw_marcato =
475         save fat_factor, thinness;
476         save left_dist, right_dist, ne, se;
477         pair left_dist, right_dist, ne, se;
478
479         set_char_box (staff_space# / 2, staff_space# / 2,
480                       0, 1.1 staff_space#);
481
482         fat_factor = .3;
483         thinness = linethickness;
484
485         pickup pencircle scaled thinness;
486
487         rt x2 = w;
488         lft x5 = -b;
489         bot y5 = 0;
490         top y3 = h;
491         y1 = y2 = y5;
492
493         x3 =0;
494         z1 - z4 = whatever * (charwd, -charht);
495         z4 = fat_factor [z3, z5];
496
497         ne = unitvector (z3 - z5);
498         se = unitvector (z2 - z3);
499
500         left_dist = (ne rotated 90) * 0.5 thinness;
501         right_dist = (se rotated 90) * 0.5 thinness;
502
503         fill bot z5{right}
504              .. (z5 - left_dist){ne}
505              -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
506                   ((z1 - right_dist) -- (z4 - right_dist)))
507              -- (z1 - right_dist){se}
508              .. bot z1{right}
509              -- bot z2{right}
510              .. (z2 + right_dist){-se}
511              -- (z3 + right_dist){-se}
512              .. top z3
513              .. (z3 + left_dist){-ne}
514              -- (z5 + left_dist){-ne}
515              .. cycle;
516 enddef;
517
518
519 fet_beginchar ("marcato up", "umarcato");
520         draw_marcato;
521         labels (1, 2, 3, 4, 5);
522 fet_endchar;
523
524
525 %
526 % The down marcato char (not very much used).
527 % Contrary to what some MF/TeX `gurus' believe
528 % it is *point*-symmetric with the "up" version
529 %
530
531 fet_beginchar ("marcato down", "dmarcato");
532         draw_marcato;
533         xy_mirror_char;
534 fet_endchar;
535
536
537 %
538 % used in french horn music todo
539 %
540 % TODO: too light at 20pt
541 %
542
543 fet_beginchar ("open (unstopped)", "open");
544         save thin, height, width, thick;
545
546         height# = 5/4 width#;
547         height# = staff_space#;
548         thin = .6 linethickness + 0.06 staff_space;
549
550         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
551
552         define_pixels (width, height);
553
554         2 thick + 0.6 (height - 2 thin) = width;
555
556         penpos1 (thick, 0);
557         penpos2 (thin, 90);
558         penpos3 (thick, 180);
559         penpos4 (thin, 270);
560         z1r = (w, 0);
561         z2r = (0, h);
562         z3r = (-w, 0);
563         z4r = (0, -h);
564
565         penlabels (1, 2, 3, 4);
566
567         penstroke z1e{up}
568                   .. z2e{left}
569                   .. z3e{down}
570                   .. z4e{right}
571                   .. cycle;
572 fet_endchar;
573
574
575 fet_beginchar ("plus (stopped)", "stopped");
576         save hthick, vthick, size, outer_hsize, outer_vsize;
577
578         hthick# = vthick# = 2 linethickness#;
579         size# = 1.1 staff_space#;
580         define_whole_blacker_pixels (vthick);
581         define_whole_vertical_blacker_pixels (hthick);
582
583         set_char_box (size# / 2, size# / 2, size# / 2, size# / 2);
584
585         outer_hsize = hround ((b + w - vthick) / 2);
586         outer_vsize = vround ((h + d - hthick) / 2);
587         w := b := (2 outer_hsize + vthick) / 2;
588         h := d := (2 outer_vsize + hthick) / 2;
589
590         draw_rounded_block ((-b, -d + outer_vsize),
591                             (w, -d + outer_vsize + hthick), hthick);
592         draw_rounded_block ((-b + outer_hsize, -d),
593                             (-b + outer_hsize + vthick, h), vthick);
594 fet_endchar;
595
596
597 fet_beginchar ("Upbow", "upbow");
598         save ht, wd, thick;
599
600         thick = 1.4 linethickness;
601         wd# = 1.3 staff_space#;
602         ht# = 1.6 wd#;
603
604         set_char_box (wd# / 2, wd# / 2, 0, ht#);
605
606         draw_accent ((-h, -w), (0, w), thick, 0.9);
607         currentpicture := currentpicture rotated -90;
608 fet_endchar;
609
610
611 fet_beginchar ("Downbow", "downbow");
612         save stemthick, beamheight, wd;
613         save pat;
614         path pat;
615
616         wd# = 1.5 staff_space#;
617         define_pixels (wd);
618
619         stemthick = hround (1.2 linethickness);
620
621         set_char_box (wd# / 2, wd# / 2, 0, 4/3 staff_space#);
622
623         beamheight = 4/10 h;
624
625         pickup pencircle scaled blot_diameter;
626
627         top y1 = h;
628         lft x1 = -b;
629
630         pat := top z1{left}
631                .. {down}lft z1;
632
633         pickup pencircle scaled stemthick;
634
635         x2 = -b + stemthick;
636         y2 = h - beamheight;
637         lft x3 = -b;
638         bot y3 = -d;
639
640         pat := pat
641                -- lft z3
642                .. bot z3
643                .. rt z3
644                -- z2;
645         pat := pat
646                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
647                -- cycle;
648
649         fill pat;
650
651         labels (1, 2, 3);
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 shifted (-feta_eps, -feta_eps)
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 shifted (-feta_eps, -feta_eps);
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{z7 - 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{z7' - z7}
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{z7 - z7'}
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
913         set_char_box (radius#, radius#, radius#, 2/3 staff_space#);
914
915         thickness := hround (1.5 linethickness);
916
917         pickup pencircle scaled thickness;
918
919         rt x1 = b;
920         top y1 = h;
921
922         x2 =x1;
923         y2 = 0;
924
925         x3 = 0;
926         bot y3 = -d;
927
928         pat := top z3{right}
929                .. lft z2{up}
930                -- lft z1
931                .. top z1
932                .. rt z1
933                -- rt z2{down}
934                .. bot z3{left};
935         pat := pat
936                -- reverse pat xscaled -1 shifted (-feta_eps, 0)
937                -- cycle;
938         fill pat;
939 enddef;
940
941
942 fet_beginchar ("left heel", "upedalheel");
943         draw_heel;
944         labels (1, 2, 3);
945 fet_endchar;
946
947
948 fet_beginchar ("right heel", "dpedalheel");
949         draw_heel;
950         y_mirror_char;
951 fet_endchar;
952
953
954 def draw_toe =
955         save ht, wd, thickness;
956
957         thickness := 1.5 linethickness;
958         ht# := 1.5 staff_space#;
959         wd# := 1/3 ht#;
960         define_pixels (ht, wd);
961
962         set_char_box (wd#, wd#, 0, ht#);
963         draw_accent ((-h, -w), (0, w), thickness, 0.9);
964         currentpicture := currentpicture rotated -90;
965 enddef;
966
967
968 fet_beginchar ("left toe", "upedaltoe");
969         draw_toe;
970 fet_endchar;
971
972
973 fet_beginchar ("right toe", "dpedaltoe");
974         draw_toe;
975         y_mirror_char;
976 fet_endchar;
977
978
979 fet_beginchar ("Flageolet", "flageolet");
980         save height, width, thickness, superness;
981
982         height# = 4/15 staffsize#;
983         width# = height#;
984         thickness# = blot_diameter#;
985         define_pixels (height, width);
986         define_whole_blacker_pixels (thickness);
987
988         set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
989
990         penpos1 (thickness, 90);
991         penpos2 (thickness, 180);
992         penpos3 (thickness, 270);
993         penpos4 (thickness, 0);
994
995         x1 = 0;
996         y1r = h;
997         x4r = w;
998         x2r = -x4r;
999         y2 = 0;
1000         y4 = y2;
1001         x3 = x1;
1002         y3r = -y1r;
1003
1004         penlabels (1, 2, 3, 4);
1005
1006         % mf doesn't handle pixel dropouts in outline objects, so we use
1007         % `draw' if not called by mpost
1008         if known miterlimit:
1009                 penstroke z1e
1010                           .. z2e
1011                           .. z3e
1012                           .. z4e
1013                           .. cycle;
1014         else:
1015                 pickup pencircle scaled thickness;
1016                 draw z1
1017                      .. z2
1018                      .. z3
1019                      .. z4
1020                      .. cycle;
1021         fi;
1022 fet_endchar;
1023
1024
1025 %
1026 % TODO:  ARGRGHGH code dup.
1027 %
1028
1029 fet_beginchar ("Segno", "segno");
1030         save thin, thick, ball_diam, darkness, pointheight;
1031         save wd, ht, thick_nibangle, ball_nib_thick;
1032         save turndir;
1033         pair turndir;
1034
1035         ht# = 3 staff_space#;
1036         wd# = 2 staff_space#;
1037         darkness = .08 staff_space + 0.4 linethickness;
1038
1039         set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2);
1040
1041         thick_nibangle = 30;
1042         thick = 3 darkness;
1043         thin = darkness;
1044         ball_nib_thick = 2.7 darkness;
1045         ball_diam = ball_nib_thick + (w - ball_nib_thick) / 10;
1046         pointheight = 2 linethickness;
1047
1048         y3l = h;
1049         2 x3 = x2 + x4;
1050         x4 = 0;
1051         y4 = y2;
1052         y2l = .6 h;
1053         x2l = -b;
1054         z1 = (0, 0);
1055
1056         penpos1 (thick, 2 thick_nibangle);
1057         penpos2 (thick, thick_nibangle);
1058         penpos3 (thin, -90);
1059         penpos4 (ball_nib_thick, 180 - thick_nibangle);
1060
1061         save swoosh, ploop;
1062         path swoosh, ploop;
1063
1064         swoosh := z1l{curl 0}
1065                   .. z2l
1066                   .. z3l{right}
1067                   .. {down}z4l
1068                   -- z4r
1069                   .. z3r{left}
1070                   .. z2r{down};
1071         fill swoosh
1072              .. (swoosh scaled -1)
1073              .. cycle;
1074
1075         y5r = y4;
1076         x5r = x4l - ball_diam / 2;
1077         z6r = z5r;
1078
1079         penpos5 (1.6 ball_diam / 2, 100);
1080         penpos6 (ball_diam / 2, 240);
1081
1082         ploop := z4l{down}
1083                  .. z5l
1084                  .. z6l
1085                  -- cycle;
1086         fill ploop;
1087         fill ploop scaled -1;
1088
1089         penpos7 (2 thin, 0);
1090         z7l = (-b, -d);
1091         penpos8 (2 thin, 0);
1092         z8r = (w, h);
1093
1094         penstroke z7e
1095                   -- z8e;
1096
1097         pickup pencircle scaled 2 thin;
1098         drawdot (-x2r, pointheight);
1099         drawdot (x2r, -pointheight);
1100
1101         penlabels (range 1 thru 8);
1102 fet_endchar;
1103
1104
1105 fet_beginchar ("Coda", "coda");
1106         save stickout, thin, thick, codawidth, codaheight;
1107
1108         stickout# = 0.35 staff_space#;
1109         codawidth# = 2/3 staff_space#;
1110         codaheight# = staff_space#;
1111         define_pixels (codawidth, codaheight);
1112
1113         set_char_box (codawidth# + stickout#, codawidth# + stickout#,
1114                       codaheight# + stickout#, codaheight# + stickout#);
1115
1116         thin = 1.2 linethickness;
1117         0.1 (codaheight - 2 thin) = (codawidth - 2 thick);
1118
1119         penpos1 (thick, 0);
1120         penpos2 (thin, -90);
1121         penpos3 (thick, -180);
1122         penpos4 (thin, -270);
1123
1124         x1l = -codawidth;
1125         y2l = codaheight;
1126         y1 = 0;
1127         x2 = 0;
1128         z3 = -z1;
1129         z4 = -z2;
1130
1131         penlabels (1, 2, 3, 4);
1132
1133         penstroke z1e{up}
1134                   .. z2e{right}
1135                   .. z3e{down}
1136                   .. z4e{left}
1137                   .. cycle;
1138
1139         draw_gridline ((0, -h), (0, h), thin);
1140         draw_gridline ((-w, 0), (w, 0), thin);
1141 fet_endchar;
1142
1143
1144 fet_beginchar ("Varied Coda", "varcoda");
1145         save thin, thick, codawidth, codaheight;
1146         thin# = 1.2 linethickness#;
1147         thick# = 1.0 linethickness# + 0.25 staff_space#;
1148         codawidth# = 2/3 staff_space#;
1149         codaheight# = staff_space#;
1150         define_pixels (thin, thick, codawidth, codaheight);
1151
1152         set_char_box (codawidth# + thick#, codawidth# + thick#,
1153                       codaheight# + thick#, codaheight# + thick#);
1154
1155         x1 = -codawidth;
1156         y1 = y2 - thin;
1157         x2 = codawidth;
1158         y2 = codaheight;
1159         draw_block (z1, z2);
1160
1161         x3 = x1;
1162         y3 = -codaheight;
1163         x4 = x1 + thick;
1164         y4 = y2;
1165         draw_block (z3, z4);
1166
1167         labels (1, 2, 3, 4);
1168
1169         addto currentpicture also currentpicture scaled -1;
1170
1171         draw_gridline ((0, -h), (0, h), thin);
1172         draw_gridline ((-w, 0), (w, 0), thin);
1173 fet_endchar;
1174
1175
1176 def draw_comma =
1177         save alpha, thick, thin, ht;
1178
1179         alpha := 35;
1180         thin# = 1.2 linethickness#;
1181         thick# = 3 linethickness#;
1182         ht# = .6 staff_space#;
1183         define_pixels (thin, thick, ht);
1184
1185         set_char_box (0, .5 staff_space#, ht#, ht#);
1186
1187         penpos1 (thick, alpha);
1188         penpos2 (thick, alpha + 90);
1189         penpos3 (thin, 180 - alpha);
1190         penpos4 (thin, 90 - alpha);
1191
1192         x3r = 0;
1193         x1l = x3l;
1194         y2r = -y4l = h;
1195         z1 = z2;
1196         z3 = z4;
1197
1198         fill z1l{dir (alpha + 90)}
1199              .. z2r{dir alpha}
1200              .. z1r{dir (alpha - 90)}
1201              .. z3l{dir (270 - alpha)}
1202              .. z4l{dir (180 - alpha)}
1203              .. z3r{dir (90-alpha)}
1204              .. cycle;
1205 enddef;
1206
1207
1208 fet_beginchar ("Right Comma", "rcomma");
1209         draw_comma;
1210         penlabels (1, 2, 3, 4);
1211 fet_endchar;
1212
1213
1214 fet_beginchar ("Left Comma", "lcomma");
1215         draw_comma;
1216         xy_mirror_char;
1217 fet_endchar;
1218
1219
1220 def draw_varcomma =
1221         save thick, thin, ht, wd, alpha;
1222
1223         alpha := 35;
1224         thin# = 1.2 linethickness#;
1225         thick# = 3 linethickness#;
1226         ht# = .6 staff_space#;
1227         wd# = .25 staff_space#;
1228         define_pixels (thin, thick, ht, alpha);
1229
1230         set_char_box (wd#, wd#, ht#, ht#);
1231
1232         z1 = (-b, -d);
1233         z2 = (w, h);
1234
1235         draw_brush (z1, thin, z2, thick);
1236 enddef;
1237
1238
1239 fet_beginchar ("Right Varied Comma", "rvarcomma");
1240         draw_varcomma;
1241         labels (1, 2);
1242 fet_endchar;
1243
1244
1245 fet_beginchar ("Left Varied Comma", "lvarcomma");
1246         draw_varcomma;
1247         xy_mirror_char;
1248 fet_endchar;
1249
1250
1251 thick# := 1/24 designsize;
1252 define_blacker_pixels (thick);
1253
1254 rthin := 0.075 * staff_space + 0.5 linethickness;
1255 rthick := 2 thick + rthin;
1256
1257
1258 def draw_arpeggio =
1259         save alpha;
1260         save ne, nw, se, sw;
1261         save x, y;
1262         pair ne,nw,se,sw;
1263
1264         alpha := -40;
1265
1266         nw = dir (alpha + 180);
1267         ne = dir (alpha + 90);
1268         se = dir alpha;
1269         sw = dir (alpha - 90);
1270
1271         penpos1 (rthin, alpha + 90);
1272         penpos2 (5/4 rthick, alpha);
1273         penpos3 (3/4 rthick, alpha);
1274         penpos4 (5/4 rthick, alpha);
1275         penpos5 (rthin, alpha + 90);
1276
1277         z1 = (width / 2, height) - overshoot * se;
1278         z2 = 2 [z4, (width / 2, height / 2)];
1279         z3 = 1/2 [z2, z4];
1280         x4 = 2/8 staff_space;
1281         y4 = rthin;
1282
1283         z5 = 2 [z1, (width / 2, height / 2)];
1284         z6 = z2l + 1/2 rthin * sw;
1285         z7 = z4l + 1/2 rthin * sw + 1/2 rthin * se;
1286         z8 = 2 [z6, (width / 2, height / 2)];
1287         z9 = 2 [z7, (width / 2, height / 2)];
1288
1289         fill z1l{se}
1290              -- z6
1291              .. z3l
1292              .. z7{se}
1293              -- z5l
1294              .. z5r{nw}
1295              -- z8
1296              .. z3r
1297              .. z9{nw}
1298              -- z1r
1299              .. cycle;
1300 enddef;
1301
1302
1303 fet_beginchar ("Arpeggio", "arpeggio");
1304         save height, overshoot, width;
1305         height# = staff_space#;
1306         width# = 0.8 height#;
1307         overshoot# = 0.25 staff_space#;
1308         define_pixels (height, overshoot, width);
1309
1310         set_char_box (0, width#, 0, height#);
1311         draw_arpeggio;
1312         penlabels (range 1 thru 9);
1313
1314         draw_staff (-2, 2, 0.0);
1315 fet_endchar;
1316
1317
1318 %
1319 % Extendable Trill symbol.
1320 % Not yet used
1321 % Rename me to Trill, rename Trill to Tr?
1322 %
1323
1324 fet_beginchar ("Trill_element", "trill_element");
1325         save height, overshoot;
1326         height# = staff_space#;
1327         width# = 0.8 height#;
1328         overshoot# = 0.25 staff_space#;
1329         define_pixels (height, overshoot, width);
1330
1331         set_char_box (0, height#, 0, width#);
1332         draw_arpeggio;
1333
1334         currentpicture := currentpicture shifted -(width / 2, height / 2);
1335         currentpicture := currentpicture rotated 90;
1336         currentpicture := currentpicture shifted (height / 2, width / 2);
1337 fet_endchar;
1338
1339
1340 %
1341 % Arpeggio arrow by Chris Jackson <chris@fluffhouse.org.uk>
1342 %
1343
1344 def draw_arpeggio_arrow =
1345         save thinness, height, width, overshoot;
1346         save nw, ne, se, sw;
1347         save alpha;
1348         save before_left, before_right, after_left, after_right;
1349         save u_left, v_left, u_right, v_right;
1350         pair nw, ne, se, sw;
1351         path before_left, before_right, after_left, after_right;
1352
1353         height# = staff_space#;
1354         width# = 0.8 height#;
1355         overshoot# = 0.25 staff_space#;
1356         define_pixels (height, overshoot, width);
1357
1358         set_char_box (0, width#, 0, height#);
1359
1360         alpha := -40;
1361         nw = dir (alpha + 180);
1362         ne = dir (alpha + 90);
1363         se = dir alpha;
1364         sw = dir (alpha - 90);
1365
1366         penpos1 (rthin, alpha + 90);
1367         penpos2 (5/4 rthick, alpha);
1368         penpos3 (5/4 rthick, 0);
1369
1370         z1 = (width / 2, height) - overshoot * se; % numbering is consistent
1371                                                    % with the arpeggio symbol
1372         z2 = 2 [z4, (width / 2, height / 2)];
1373         z3 = (0.5 width, 0.5 height);
1374         z4 = (0.25 staff_space, rthin);
1375         z6 = z2l + 1/2 rthin * sw;
1376         z9 = (width / 2, height) + overshoot * se;
1377
1378         pickup pencircle scaled vround (0.5 rthin);
1379
1380         bot z10 = (0.5 w, 0);
1381         lft z11 = (-0.3 w, 0.8 h);
1382         rt z12 = (1.3 w, 0.8 h);
1383
1384         before_left := z1l
1385                        -- z6{z6 - z1l}
1386                        .. {down}z3l;
1387         after_left := (z3 + (0, -0.25 rthin / cosd (angle (nw))))
1388                       -- (z11 + 0.25 rthin * ne);
1389         (u_left, v_left) = before_left intersectiontimes after_left;
1390
1391         before_right := (z12 + 0.25 rthin * nw)
1392                         -- (z3 + (0, -0.25 rthin / cosd (angle (nw))));
1393         after_right := z3r{up}
1394                        .. z9{z1r - z9}
1395                        -- z1r;
1396         (u_right, v_right) = before_right intersectiontimes after_right;
1397
1398         fill subpath (0, u_left) of before_left
1399              .. subpath (v_left, infinity) of after_left
1400              .. top z11
1401              .. lft z11
1402              .. {dir -50}(z11 + 0.25 rthin * sw)
1403              .. (z10 + 0.25 rthin * sw){dir -70}
1404              .. bot z10
1405              .. {dir 70}(z10 + 0.25 rthin * se)
1406              .. (z12 + 0.25 rthin * se){dir 50}
1407              .. rt z12
1408              .. top z12
1409              .. subpath (0, u_right) of before_right
1410              .. subpath (v_right, infinity) of after_right
1411              .. cycle;
1412
1413         % mf doesn't handle pixel dropouts in outline objects, so we use
1414         % `draw' if not called by mpost
1415         if not known miterlimit:
1416                 pickup pencircle scaled 0.7 rthin;
1417                 draw z1
1418                      -- (z9 + 0.5 rthin * dir (alpha - 90));
1419         fi;
1420 enddef;
1421
1422
1423 fet_beginchar ("Arpeggio arrow down", "arpeggio.arrow.M1");
1424         draw_arpeggio_arrow;
1425         penlabels (range 1 thru 12);
1426 fet_endchar;
1427
1428
1429 fet_beginchar ("Arpeggio arrow up", "arpeggio.arrow.1");
1430         draw_arpeggio_arrow;
1431         currentpicture := currentpicture scaled -1
1432                                          shifted (w - feta_eps, h - feta_eps);
1433 fet_endchar;
1434
1435
1436 % Hmm
1437 input feta-slag;
1438
1439
1440 % railroad tracks.
1441 %
1442 % I actually have no clue how they should look, so we use a slightly curvy
1443 % and tapered shape.
1444 %
1445
1446 fet_beginchar ("Caesura", "caesura");
1447         save slant, space_between, clearance;
1448         save alpha, pat;
1449         save botthick, topthick;
1450         save krom;
1451         path pat;
1452
1453         botthick = 1.5 linethickness;
1454         topthick = 2.5 linethickness;
1455
1456         pickup pencircle scaled botthick;
1457
1458         slant = 3.5;
1459         space_between# = 0.6 staff_space#;
1460         clearance# = 0.2 staff_space#;
1461         height# = 1.2 staff_space#;
1462
1463         set_char_box (0, 2.0 staff_space#,
1464                       staff_space# - clearance#, height#);
1465         define_pixels (clearance, height);
1466         define_whole_pixels (space_between);
1467
1468         bot y1 = -d;
1469         top y2 = h;
1470
1471         lft x1 = 0;
1472         x2 = (y2 - y1) / slant;
1473
1474         krom = 10;
1475
1476         alpha = angle (z2 - z1);
1477         penpos1 (botthick, alpha - krom);
1478         penpos3 (botthick, alpha - krom + 90);
1479
1480         penpos2 (topthick, alpha + krom);
1481         penpos4 (topthick, alpha + krom + 90);
1482
1483         z3 = z1;
1484         z4 = z2;
1485
1486         penlabels (1, 2, 3, 4);
1487
1488         pat := z3r{(z1r - z1l)}
1489                .. z4r{z2r-z2l}
1490                .. z2r{z4l-z4r}
1491                .. z4l{z2l-z2r}
1492                .. z3l{z1l-z1r}
1493                .. z1l{z3r-z3l}
1494                .. cycle;
1495         fill pat;
1496         fill pat shifted (space_between, 0);
1497 fet_endchar;
1498
1499
1500 fet_endgroup ("scripts");