]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-toevallig.mf
Add draw_arrow() helper function used for arrowed microtone accidentals
[lilypond.git] / mf / feta-toevallig.mf
1 %
2 % feta-toevallig.mf -- implement Accidentals
3 %
4 % (c) 1997--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
5 %
6
7
8 %
9 % also show in other configuration wrt staff lines.
10 %
11 def draw_shifted_too =
12 if test > 0:
13         fet_beginchar ("shifted too", "");
14                 set_char_box (0, 0, 0, 0);
15                 currentpicture := remember_pic;
16
17                 draw_staff (-2, 2, 0.5);
18         fet_endchar;
19 fi;
20 enddef;
21
22
23 %
24 % Accidentals from various sources, notably
25 %
26 %   Baerenreiter edition of Schuberts `Auf dem Strom' (sharp, natural)
27 %   F Hofmeister edition of Muellers `Etueden fuer Horn' (double sharp, flat)
28 %
29
30
31 %
32 % Naming for accidentals (including microtonal variants):
33 %
34 %   SHARPBASE[.SLASHES.STEMS]
35 %   FLATBASE[.MODIFIER]
36 %  
37 % Examples:
38 %
39 %   sharp.slashslash.stem
40 %   mirroredflat.flat
41 %
42 %
43
44
45 fet_begingroup ("accidentals");
46
47 %
48 % Draw an arrow
49 %
50 % * "stemslant" gives the direction of the stem's left boundary
51 %   (needed for brushed stems, equals "up" for straight stems)
52 % * "extend" is used to make the stem longer or shorter (if negative);
53 %   different kinds of accidentals need different values here
54 %
55 def draw_arrow (expr attach, stemwidth, stemslant, extend, pointingdown) =
56 begingroup;
57         save htip;  % tip height
58         save wwing; % wing "radius"
59         save angle_wing_bot, angle_wing_top, angle_tip;
60         save upshift;
61         clearxy;
62
63         wwing:=0.26 stemwidth;
64         htip:=staff_space*0.85 + stafflinethickness - wwing;
65
66         % "flip" is used to reflect the arrow vertically if arrow points downward
67         transform flip;
68         if pointingdown:
69                 flip=identity reflectedabout (origin, right);
70         else:
71                 flip=identity;
72         fi;
73
74         z1=attach shifted ((-stemwidth/2),0);
75         upshift:=max(0, wwing + 0.1 staff_space + extend);
76         z2=z1 shifted (((unitvector stemslant) scaled upshift) transformed flip);
77
78         z7=attach shifted ((stemwidth/2),0);
79         z6=z7 shifted (((unitvector (-xpart stemslant, ypart stemslant))
80                         scaled upshift) transformed flip);
81         (z2-z3)= (0.38 staff_space, 0.05 htip) transformed flip;
82         (z6-z5)=(-0.38 staff_space, 0.05 htip) transformed flip;
83
84         z4 =attach shifted ((-0.2 stemwidth, upshift+htip) transformed flip);
85         z4'=attach shifted (( 0.2 stemwidth, upshift+htip) transformed flip);
86
87         % angle_wing_bot is the angle at which the arc from z2 to z3a enters z3a
88         % angle_wing_top is the angle at which the arc from z3b to z4 leaves z3b
89         % angle_tip is the angle at which the arc from z4 to z4' leaves z4
90         angle_wing_bot=30;
91         angle_wing_top=55;
92         angle_tip=68;
93
94         z3a=z3 shifted ((((dir angle_wing_bot) rotated (-90))
95                          scaled wwing) transformed flip);
96         z3b=z3 shifted ((((dir angle_wing_top) rotated 90)
97                          scaled wwing) transformed flip);
98
99         z5a=z5 shifted ((((dir (180-angle_wing_bot)) rotated 90)
100                          scaled wwing) transformed flip);
101         z5b=z5 shifted ((((dir (180-angle_wing_top)) rotated (-90))
102                          scaled wwing) transformed flip);
103
104         % Draw the arrow
105         pickup pencircle scaled 1;
106         fill z1
107              -- z2{stemslant transformed flip}
108              .. {(-dir angle_wing_bot) transformed flip}z3a
109              .. z3b{(dir angle_wing_top) transformed flip}
110              .. z4{(dir angle_tip) transformed flip}
111              .. z4'{(dir (-angle_tip)) transformed flip}
112              ..{(dir (-angle_wing_top)) transformed flip}z5b
113              ..z5a{(-dir (-angle_wing_bot)) transformed flip}
114              ..z6{((-stemslant) reflectedabout (origin, up)) transformed flip}
115              -- z7
116              --cycle;
117
118         labels(range 0 thru 7,4',3a,3b,5a,5b);
119 endgroup;
120 enddef;
121
122 save remember_pic;
123 picture remember_pic;
124
125 save sharp_beamheight;
126 sharp_beamheight# := 0.3 staff_space# + stafflinethickness#;
127
128 %
129 % The beams of most sharps have horizontal endings (as if drawn with
130 % a square pen).  [Wanske] does not mention this, so we'll just ignore
131 % this fact.
132 %
133
134 def draw_meta_sharp (expr width, offset) =
135         save beamwidth, beamslope;
136         save ne, nw_dist;
137         pair ne, nw_dist;
138
139         beamwidth := width;
140
141         define_whole_vertical_blacker_pixels (sharp_beamheight);
142
143         clearxy;
144
145         beamslope = sharp_beamheight / beamwidth;
146
147         pickup pencircle scaled 2 blot_diameter;
148
149         rt x2 - lft x1 = beamwidth;
150         z2 = z1 + whatever * (beamwidth, sharp_beamheight);
151         .5 [z1, z3] = (.5 w, offset);
152         x3 = x2;
153         top y2 - bot y3 = sharp_beamheight;
154         x4 = x1;
155         top y1 - bot y4 = sharp_beamheight;
156
157         ne = unitvector (z2 - z1);
158         nw_dist = (ne rotated 90) * blot_diameter;
159
160         fill lft z1{up}
161              ... (z1 + nw_dist){ne}
162              -- (z2 + nw_dist){ne}
163              ... rt z2{down}
164              -- rt z3{down}
165              ... (z3 - nw_dist){-ne}
166              -- (z4 - nw_dist){-ne}
167              ... lft z4{up}
168              -- cycle;
169
170         labels (1, 2, 3, 4);
171 enddef;
172
173
174 fet_beginchar ("Sharp", "sharp");
175         save stem, stemx, stemwidth;
176         save outer_space, interbeam;
177
178         stemwidth# := stafflinethickness# + .05 staff_space#;
179         define_whole_blacker_pixels (stemwidth);
180
181         interbeam := 1.05 staff_space_rounded;
182
183         set_char_box (0, 1.1 staff_space#,
184                       1.5 staff_space#, 1.5 staff_space#);
185
186         stem := 7 / 16 * w;
187         stemx := hround stem;
188         outer_space := hround ((w - stemx - stemwidth) / 2);
189
190         w := 2 outer_space + stemx + stemwidth;
191         d := d - feta_space_shift;
192
193         draw_meta_sharp (w, -.5 interbeam);
194         draw_meta_sharp (w, -.5 interbeam + vround interbeam);
195
196         pickup pencircle scaled stemwidth;
197
198         lft x5 = lft x6 = outer_space;
199         lft x7 = lft x8 = outer_space + stemx;
200         bot y5 = -d;
201         top y6 = vround (1.5 staff_space - stem * beamslope);
202         bot y7 = -top y6 + feta_space_shift;
203         top y8 = h;
204
205         labels (5, 6, 7, 8);    
206
207         draw_gridline (z5, z6, stemwidth);
208         draw_gridline (z7, z8, stemwidth);
209
210         remember_pic := currentpicture;
211
212         draw_staff (-2, 2, 0);
213 fet_endchar;
214
215
216 draw_shifted_too;
217
218
219 fet_beginchar ("1/2 Sharp", "sharp.slashslash.stem");
220         save stem, stemwidth;
221         save outer_space, interbeam;
222
223         stemwidth# := stafflinethickness# + .05 staff_space#;
224         define_whole_blacker_pixels (stemwidth);
225
226         interbeam := 1.05 staff_space_rounded;
227
228         set_char_box (0, 0.7 staff_space#,
229                       1.5 staff_space#, 1.5 staff_space#);
230
231         stem := 7 / 16 * w;
232         outer_space := hround ((w - stemwidth) / 2);
233
234         w := 2 outer_space + stemwidth;
235         d := d - feta_space_shift;
236
237         draw_meta_sharp (w, -.5 interbeam);
238         draw_meta_sharp (w, -.5 interbeam + vround interbeam);
239
240         pickup pencircle scaled stemwidth;
241
242         lft x5 = lft x6 = outer_space;
243         top y6 = vround (1.5 staff_space - .5 stem);
244         bot y5 = -top y6 + feta_space_shift;
245
246         labels (5, 6);
247
248         draw_gridline (z5, z6, stemwidth);
249
250         remember_pic := currentpicture;
251
252         draw_staff (-2, 2, 0);
253 fet_endchar;
254
255
256 draw_shifted_too;
257
258
259 fet_beginchar ("Sharp (3 beams)", "sharp.slashslashslash.stemstem");
260         save stem, stemx, stemwidth;
261         save outer_space, interbeam;
262         save sharp_beamheight;
263
264         sharp_beamheight# := 0.22 staff_space# + stafflinethickness#;
265
266         stemwidth# := stafflinethickness# + .05 staff_space#;
267         define_whole_blacker_pixels (stemwidth);
268
269         interbeam := 1.2 staff_space_rounded;
270
271         set_char_box (0, 1.1 staff_space#,
272                       1.5 staff_space#, 1.5 staff_space#);
273
274         stem := 7 / 16 * w;
275         stemx := hround stem;
276         outer_space := hround ((w - stemx - stemwidth) / 2);
277
278         w := 2 outer_space + stemx + stemwidth;
279         d := d - feta_space_shift;
280
281         draw_meta_sharp (.88 w, -.5 interbeam);
282         draw_meta_sharp (.88 w, -.5 interbeam + vround interbeam);
283         sharp_beamheight# := 1/.88 sharp_beamheight#;
284         draw_meta_sharp (w, 0);
285
286         pickup pencircle scaled stemwidth;
287
288         lft x5 = lft x6 = outer_space;
289         lft x7 = lft x8 = outer_space + stemx;
290         bot y5 = -d;
291         top y6 = vround (1.5 staff_space - stem * beamslope);
292         bot y7 = -top y6 + feta_space_shift;
293         top y8 = h;
294
295         labels (5, 6, 7, 8);    
296
297         draw_gridline (z5, z6, stemwidth);
298         draw_gridline (z7, z8, stemwidth);
299
300         remember_pic := currentpicture;
301
302         draw_staff (-2, 2, 0);
303 fet_endchar;
304
305
306 draw_shifted_too;
307
308
309 fet_beginchar ("1/2 Sharp (3 beams)", "sharp.slashslashslash.stem");
310         save stem, stemx, stemwidth;
311         save outer_space, interbeam;
312         save sharp_beamheight;
313
314         sharp_beamheight# := 0.22 staff_space# + stafflinethickness#;
315
316         stemwidth# := stafflinethickness# + .05 staff_space#;
317         define_whole_blacker_pixels (stemwidth);
318
319         interbeam := 1.2 staff_space_rounded;
320
321         set_char_box (0, 0.95 staff_space#,
322                       1.3 staff_space#, 1.3 staff_space#);
323
324         stem := 7 / 16 * w;
325         outer_space := hround ((w - stemwidth) / 2);
326
327         w := 2 outer_space + stemwidth;
328         d := d - feta_space_shift;
329
330         draw_meta_sharp (.8 w, -.5 interbeam);
331         draw_meta_sharp (.8 w, -.5 interbeam + vround interbeam);
332         sharp_beamheight# := 1/.8 sharp_beamheight#;
333         draw_meta_sharp (w, 0);
334
335         pickup pencircle scaled stemwidth;
336
337         lft x5 = lft x6 = outer_space;
338         top y6 = vround (1.5 staff_space - .5 stem);
339         bot y5 = -top y6 + feta_space_shift;
340         labels (5, 6);
341
342         draw_gridline (z5, z6, stemwidth);
343
344         remember_pic := currentpicture;
345
346         draw_staff (-2, 2, 0);
347 fet_endchar;
348
349
350 draw_shifted_too;
351
352
353 fet_beginchar ("3/4 Sharp", "sharp.slashslash.stemstemstem");
354         save stem, stemx, stemwidth;
355         save outer_space, interbeam;
356
357         stemwidth# := stafflinethickness# + .05 staff_space#;
358         define_whole_blacker_pixels (stemwidth);
359
360         interbeam := 1.05 staff_space_rounded;
361
362         set_char_box (0, 1.6 staff_space#,
363                       1.5 staff_space#, 1.5 staff_space#);
364
365         stem := 9 / 32 * w;
366         stemx := hround stem;
367         outer_space := hround ((w - 2 stemx - stemwidth) / 2);
368
369         w := 2 outer_space + 2 stemx + stemwidth;
370         d := d - feta_space_shift;
371
372         draw_meta_sharp (w, -.5 interbeam);
373         draw_meta_sharp (w, -.5 interbeam + vround interbeam);
374
375         pickup pencircle scaled stemwidth;
376
377         lft x5 = lft x6 = outer_space;
378         lft x7 = lft x8 = outer_space + stemx;
379         lft x9 = lft x10 = outer_space + 2 stemx;
380         bot y5 = -d;
381         top y6 = vround (1.5 staff_space - 2 stem * beamslope);
382         bot y9 = -top y6 + feta_space_shift;
383         top y10 = h;
384         y7 = .5 [y5, y9];
385         y8 = .5 [y6, y10];
386
387         labels (5, 6, 7, 8, 9, 10);
388
389         draw_gridline (z5, z6, stemwidth);
390         draw_gridline (z7, z8, stemwidth);
391         draw_gridline (z9, z10, stemwidth);
392
393         remember_pic := currentpicture;
394
395         draw_staff (-2, 2, 0);
396 fet_endchar;
397
398
399 draw_shifted_too;
400
401
402 %
403 % The stems of the natural are brushed (at least, in Barenreiter SCS)
404 %
405
406 fet_beginchar ("Natural", "natural");
407         save stemwidth, top_stem_thick;
408         save ne, pat_top, pat_bottom;
409         pair ne;
410         path pat_top, pat_bottom;
411
412         top_stem_thick# = stafflinethickness# + .10 staff_space#;
413         stemwidth# = 0.09 staff_space# + .5 stafflinethickness#;
414         define_whole_blacker_pixels (top_stem_thick, stemwidth);
415
416         set_char_box (0, 2/3 staff_space#,
417                       1.5 staff_space#, 1.5 staff_space#);
418
419         d := d - feta_space_shift;
420
421         pickup pencircle scaled stemwidth;
422
423         penpos1 (top_stem_thick, 0);
424         penpos3 (top_stem_thick, 0);
425         penpos2 (stemwidth, 0);
426         penpos4 (stemwidth, 0);
427
428         x2r = w;
429         x4l = 0;
430         x3 = x2;
431         x1 = x4;
432
433         y1 = h;
434         y3 = -d;
435         top y2 = vround (staff_space - 3/2 stafflinethickness);
436         y4 = -y2 + feta_space_shift;
437
438         pat_bottom := z4r{z4r - z1r}
439                       .. bot z4
440                       .. z4l{z1l - z4l};
441         fill simple_serif (z1l, z1r, -30)
442              -- pat_bottom
443              -- cycle;
444
445         pat_top := z2r{z2r - z3r}
446                    .. top z2
447                    .. z2l{z3l - z2l};
448         fill simple_serif (z3l, z3r, 30)
449              -- pat_top
450              -- cycle;
451
452         ne = (x2 - x4, stafflinethickness);
453
454         z11' = z3l + whatever * (z2l - z3l);
455         y11' = vround (.5 (staff_space - stafflinethickness));
456         z11 = z11' + whatever * ne;
457         x11 = x12;
458         z12 = directionpoint -ne of pat_top;
459         z13 = z12 + whatever * ne;
460         x13 = x1;
461         z14 = z11 + whatever * ne;
462         x14 = x1;
463
464         z21' = z4r + whatever * (z1r - z4r);
465         y21' = -y11' + feta_space_shift;
466         z21 = z21' + whatever * ne;
467         x21 = x22;
468         z22 = directionpoint -ne of pat_bottom;
469         z23 = z22 + whatever * ne;
470         x23 = x3;
471         z24 = z21 + whatever * ne;
472         x24 = x3;
473
474         fill z11
475              -- z12
476              -- z13
477              -- z14
478              -- cycle;
479         fill z21
480              -- z22
481              -- z23
482              -- z24
483              -- cycle;
484
485         penlabels (1, 2, 3, 4);
486         labels (11, 11', 12, 13, 14, 21, 21', 22, 23, 24);
487
488         remember_pic := currentpicture;
489
490         draw_staff (-2, 2, 0);
491 fet_endchar;
492
493
494 draw_shifted_too;
495
496
497 %
498 % Dedicated to my mom.    (3/10/97)
499 %
500 % Mamma, ik hou van je; kom je alsjeblieft terug?
501 %    -- HW
502 %
503 %
504 % TODO: remove crook_fatness
505 % TODO: document, simplify!
506 %
507
508 def draw_meta_flat (expr xcenter, w, crook_fatness) =
509         save crook_thinness;
510         save bottom_overshoot, bot_crook_dir;
511         save top_stem_thick, bottom_stem_thick, hair, smaller_hole;
512         save top_crook_thinness;
513         save zwiep;
514         save center;
515         pair center, bot_crook_dir;
516         save clearing;
517
518         clearxy;
519
520         % the stem shouldn't reach the top staff line.
521         %% TODO: should take from height.
522         %
523         % TODO: parameterize this
524         %
525         if w >= 0.75 staff_space:
526                 smaller_hole = 0.35 stafflinethickness;
527         else:
528                 smaller_hole = 0;
529         fi;
530         clearing = 1.7 stafflinethickness;
531         crook_thinness = .7 stafflinethickness + .06 staff_space;
532         top_crook_thinness = 1 stafflinethickness + .065 staff_space;
533         bottom_overshoot = stafflinethickness;
534
535         bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
536         top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
537         define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick);
538
539         if odd (top_stem_thick - bottom_stem_thick):
540                 top_stem_thick := top_stem_thick - 1;
541         fi;
542
543         center = (xcenter, 0);
544
545         x1l = hround (xcenter - .5 top_stem_thick);
546         y1 = vround (2 staff_space - clearing);
547         x2l = hround (xcenter - .5 bottom_stem_thick);
548         y2 = -.5 staff_space - .5 stafflinethickness;
549
550         penpos1 (top_stem_thick, 0);
551         penpos2 (bottom_stem_thick, 0);
552
553         y3l = vfloor ((staff_space - stafflinethickness) / 2);
554         z3l = whatever [z2r, z1r];
555         z3r = .3 [z2r, z1r] + (smaller_hole, 0);
556         x3r := hceiling x3r;
557
558         % we insert z3l to get better conversion with mf2pt1
559         fill simple_serif (z1r, z1l, 30)
560              -- z2l
561              -- z2r
562              -- z3l
563              -- cycle;
564
565         z10 = whatever [z2r, z1r] + (smaller_hole, 0);
566         y10 = -1/10 staff_space;
567         x10 := hceiling x10;
568
569         x11 = xcenter + bottom_overshoot / 3;
570         y11 = -vround (.5 (staff_space + stafflinethickness)
571                        + bottom_overshoot);
572
573         penpos4 (whatever, 53);
574
575         y4l - y4r = top_crook_thinness;
576         y5r = .15 staff_space;
577         x5l = hround (w + xcenter);
578         y4 = staff_space / 2;
579         x4r = .45 [x5r, x3r];
580         y4l := vround y4l;
581
582         penpos5 (crook_fatness, -175);
583
584         bot_crook_dir = unitvector ((x5l, 0) - z11);
585         z8 = z11 + whatever * bot_crook_dir;
586         y8 = -staff_space / 2;
587
588         z7 = z8
589              + whatever * bot_crook_dir
590              + crook_thinness * (bot_crook_dir rotated 90);
591         x7 = .1 [x3r, x8];
592
593         unfill z3r{z3r - z10}
594                .. z4r{right}
595                .. z5r{down}
596                .. z7{-bot_crook_dir}
597                & z7
598                .. z10{z3r - z10}
599                -- cycle;
600
601         fill z2l{down}
602              .. z11{right}
603              .. z8{bot_crook_dir}
604              .. z5l{up}
605              .. z4l{left}
606              .. z3l
607              -- cycle;
608 enddef;
609
610
611 %
612 % unfortunately, 600dpi is not enough to show the brush of the stem.
613 %
614
615 fet_beginchar ("Flat", "flat");
616         set_char_box (1.2 stafflinethickness#, .8 staff_space#,
617                       0.6 staff_space#, 1.9 staff_space#);
618
619         draw_meta_flat (0, w, 0.31 staff_space);
620         penlabels (range 0 thru 11);
621
622         remember_pic := currentpicture;
623
624         draw_staff (-2, 2, 0);
625 fet_endchar;
626
627
628 draw_shifted_too;
629
630
631 fet_beginchar ("Flat (slashed)", "flat.slash");
632         set_char_box (.4 staff_space#, .8 staff_space#,
633                       0.6 staff_space#, 1.9 staff_space#);
634
635         draw_meta_flat (0, w, 0.31 staff_space);
636
637         clearxy;
638
639         save slope, slash_width;
640         slope = 0.5;
641         slash_width = w;
642
643         z11 = (0, h / 2);
644         z12 = z11 - (slash_width, slash_width * slope) / 2;
645         z13 = z11 + (slash_width, slash_width * slope) / 2;
646         penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
647         penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
648
649         z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
650         z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
651
652         fill z13r
653              .. z15
654              .. z13l
655              -- z12l
656              .. z14
657              .. z12r
658              -- z13r
659              .. cycle;
660
661         penlabels (12, 13);
662         labels (14, 15);
663
664         remember_pic := currentpicture;
665
666         draw_staff (-2, 2, 0);
667 fet_endchar;
668
669
670 fet_beginchar ("Flat (slashed twice)", "flat.slashslash");
671         set_char_box (.4 staff_space#, .8 staff_space#,
672                       0.6 staff_space#, 1.9 staff_space#);
673
674         draw_meta_flat (0, w, 0.31 staff_space);
675
676         clearxy;
677
678         save slope, slash_width;
679         slope = 0.5;
680         slash_width = w;
681
682         z11 = (0, 5/12 h);
683         z12 = z11 - (slash_width, slash_width * slope) / 2;
684         z13 = z11 + (slash_width, slash_width * slope) / 2;
685         penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
686         penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
687
688         z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
689         z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
690
691         fill z13r
692              .. z15
693              .. z13l
694              -- z12l
695              .. z14
696              .. z12r
697              -- z13r
698              .. cycle;
699
700         penlabels (12, 13);
701         labels (14, 15);
702
703         z21 = (0, 2/3 h);
704         z22 = z21 - (slash_width, slash_width * slope) / 2;
705         z23 = z21 + (slash_width, slash_width * slope) / 2;
706         penpos22 (1.5 stafflinethickness, angle (z23 - z22) - 90);
707         penpos23 (1.5 stafflinethickness, angle (z23 - z22) - 90);
708
709         z24 = z22 - .75 stafflinethickness * unitvector (z23 - z22);
710         z25 = z23 + .75 stafflinethickness * unitvector (z23 - z22);
711
712         fill z23r
713              .. z25
714              .. z23l
715              -- z22l
716              .. z24
717              .. z22r
718              -- z23r
719              .. cycle;
720
721         penlabels (22, 23);
722         labels (24, 25);
723
724         remember_pic := currentpicture;
725
726         draw_staff (-2, 2, 0);
727 fet_endchar;
728
729
730 fet_beginchar ("Flatflat (mirrored)", "mirroredflat.flat");
731         set_char_box (0, 1.6 staff_space#, 
732                       0.6 staff_space#, 1.9 staff_space#);
733
734         % This is a modified version of `draw_meta_flat'.
735
736         save crook_thinness, crook_fatness;
737         save bottom_overshoot, bot_crook_dir;
738         save top_stem_thick, bottom_stem_thick, hair, smaller_hole;
739         save top_crook_thinness;
740         save zwiep;
741         save center;
742         pair center, bot_crook_dir;
743         save clearing, wid;
744         save pat;
745         path pat;
746
747         clearxy;
748
749         wid = w / 2;
750
751         % the stem shouldn't reach the top staff line.
752         %% TODO: should take from height.
753         %
754         % TODO: parameterize this
755         %
756         if wid >= 0.75 staff_space:
757                 smaller_hole = 0.35 stafflinethickness;
758         else:
759                 smaller_hole = 0;
760         fi;
761         clearing = 1.7 stafflinethickness;
762         crook_thinness = .7 stafflinethickness + .06 staff_space;
763         crook_fatness = 0.31 staff_space;
764         top_crook_thinness = 1 stafflinethickness + .065 staff_space;
765         bottom_overshoot = stafflinethickness;
766
767         bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
768         top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
769         define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick);
770
771         if odd (top_stem_thick - bottom_stem_thick):
772                 top_stem_thick := top_stem_thick - 1;
773         fi;
774
775         center = (0, 0);
776
777         x1l = hround (-.5 top_stem_thick);
778         y1 = vround (2 staff_space - clearing);
779         x2l = hround (-.5 bottom_stem_thick);
780         y2 = -.5 staff_space - .5 stafflinethickness;
781
782         penpos1 (top_stem_thick, 0);
783         penpos2 (bottom_stem_thick, 0);
784
785         y3l = vfloor ((staff_space - stafflinethickness) / 2);
786         z3l = whatever [z2r, z1r];
787         z3r = .3 [z2r, z1r] + (smaller_hole, 0);
788         x3r := hceiling x3r;
789
790         z10 = whatever [z2r, z1r] + (smaller_hole, 0);
791         y10 = -1/10 staff_space;
792         x10 := hceiling x10;
793
794         x11 = bottom_overshoot / 3;
795         y11 = -vround (.5 (staff_space + stafflinethickness)
796                        + bottom_overshoot);
797
798         penpos4 (whatever, 53);
799
800         y4l - y4r = top_crook_thinness;
801         y5r = .15 staff_space;
802         x5l = hround (wid);
803         y4 = staff_space / 2;
804         x4r = .45 [x5r, x3r];
805         y4l := vround y4l;
806
807         penpos5 (crook_fatness, -175);
808
809         bot_crook_dir = unitvector ((x5l, 0) - z11);
810         z8 = z11 + whatever * bot_crook_dir;
811         y8 = -staff_space / 2;
812
813         z7 = z8
814              + whatever * bot_crook_dir
815              + crook_thinness * (bot_crook_dir rotated 90);
816         x7 = .1 [x3r, x8];
817
818         pat := z3r{z3r - z10}
819                .. z4r{right}
820                .. z5r{down}
821                .. z7{-bot_crook_dir}
822                & z7
823                .. z10{z3r - z10}
824                -- cycle;
825         unfill pat;
826         unfill pat xscaled -1;
827
828         pat := z11{right}
829                .. z8{bot_crook_dir}
830                .. z5l{up}
831                .. z4l{left}
832                .. z3l;
833         fill pat
834              -- simple_serif (z1r, z1l, 30)
835              -- reverse pat xscaled -1 shifted (-feta_eps, 0)
836              -- cycle;
837
838         currentpicture := currentpicture shifted (w/2, 0);
839
840         remember_pic := currentpicture;
841
842         draw_staff (-2, 2, 0);
843 fet_endchar;
844
845
846 draw_shifted_too;
847
848
849 fet_beginchar ("Semi flat", "mirroredflat");
850         set_char_box (1.2 stafflinethickness#, .8 staff_space#,
851                       0.6 staff_space#, 1.9 staff_space#);
852
853         draw_meta_flat (0, w, 0.31 staff_space);
854         currentpicture := currentpicture xscaled -1 shifted (w - b, 0);
855 fet_endchar;
856
857
858 fet_beginchar ("Semi flat", "mirroredflat.backslash");
859         set_char_box (.4 staff_space#, .8 staff_space#,
860                       0.6 staff_space#, 1.9 staff_space#);
861
862         draw_meta_flat (0, w, 0.31 staff_space);
863
864         clearxy;
865
866         save slope, slash_width;
867         slope = 0.5;
868         slash_width = w;
869
870         z11 = (0, h / 2);
871         z12 = z11 - (slash_width, slash_width * slope) / 2;
872         z13 = z11 + (slash_width, slash_width * slope) / 2;
873         penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
874         penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
875
876         z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
877         z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
878
879         fill z13r
880              .. z15
881              .. z13l
882              -- z12l
883              .. z14
884              .. z12r
885              -- z13r
886              .. cycle;
887
888         currentpicture := currentpicture xscaled -1 shifted (w - b, 0);
889
890         labels (1, 2, 3);
891 fet_endchar;
892
893
894 fet_beginchar ("Double Flat", "flatflat");
895         save left_wid, overlap, right_wid;
896
897         left_wid = .7;
898         right_wid = .8;
899         overlap = .05;
900
901         set_char_box (1.2 stafflinethickness#,
902                       (left_wid + right_wid - overlap) * staff_space#,
903                       .6 staff_space#, 1.9 staff_space#);
904         draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space);
905         draw_meta_flat (hround ((left_wid - overlap) * staff_space),
906                         right_wid * staff_space, 1/3 staff_space);
907 fet_endchar;
908
909
910 fet_beginchar ("3/4 Flat", "flatflat.slash");
911         save left_wid, overlap, right_wid;
912
913         left_wid = .7;
914         right_wid = .8;
915         overlap = .05;
916
917         set_char_box (1.2 stafflinethickness#,
918                       (left_wid + right_wid - overlap) * staff_space#,
919                       .6 staff_space#, 1.9 staff_space#);
920         draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space);
921         draw_meta_flat (hround ((left_wid - overlap) * staff_space),
922                         right_wid * staff_space, 1/3 staff_space);
923
924         %% maybe we should clip part of the stems?
925         %% or make the 1st flat smaller?
926         %% or reverse it?
927         pickup pencircle scaled 2 stafflinethickness;
928
929         z12 = round (-.25 w - b, .55 staff_space) + feta_offset;
930         z13 = round (.75 w, 1.45 staff_space) + feta_offset;
931         penpos12 (2 stafflinethickness, angle (z13 - z12) - 90);
932         penpos13 (2 stafflinethickness, angle (z13 - z12) - 90);
933
934         z14 = z12 - stafflinethickness * unitvector (z13 - z12);
935         z15 = z13 + stafflinethickness * unitvector (z13 - z12);
936
937         fill z13r
938              .. z15
939              .. z13l
940              -- z12l
941              .. z14
942              .. z12r
943              -- z13r
944              .. cycle;
945
946         penlabels (12, 13);
947         labels (14, 15);
948
949         remember_pic := currentpicture;
950
951         draw_staff (-2, 2, 0);
952 fet_endchar;
953
954
955 draw_shifted_too;
956
957
958 fet_beginchar ("Double Sharp", "doublesharp");
959         save klaverblad, klaversteel;
960         save pat;
961         path pat;
962
963         klaversteel = 1/15 staff_space;
964         klaverblad = .4 staff_space - .5 stafflinethickness;
965
966         set_char_box (0, staff_space#, .5 staff_space#, .5 staff_space#);
967
968         z1 = (klaversteel, 0);
969         z2 = (w / 2 - klaverblad / 10, h - klaverblad);
970         z3 = (w / 2, h);
971         z4 = z2 reflectedabout ((0, 0), (1, 1));
972         z5 = z1 reflectedabout ((0, 0), (1, 1));
973
974         labels (1, 2, 3, 4, 5);
975
976         pickup pencircle scaled blot_diameter;
977
978         x2 := hfloor (rt x2) - blot_diameter / 2;
979         x3 := hfloor (rt x3) - blot_diameter / 2;
980         y3 := vfloor (top y3) - blot_diameter / 2;
981         y4 := vfloor (top y4) - blot_diameter / 2;
982
983         pat = (rt z1){dir45}
984               .. {right}(bot z2)
985               .. rt z2
986               -- rt z3{z3 - z2}
987               .. top z3{z4 - z3}
988               -- top z4{z4 - z3}
989               .. (lft z4){down}
990               .. {dir 225}(top z5);
991         pat := pat
992                -- reverse pat xscaled -1 shifted (-feta_eps, 0);
993
994         % assure symmetry -- it's more important to center the glyph on the
995         % staff line than centering it between staff lines, so we use
996         % feta_shift, not feta_space_shift.
997         h := h + feta_shift;
998
999         fill pat shifted (0, feta_shift)
1000              -- reverse pat yscaled -1 shifted (0, -feta_eps)
1001              -- cycle;
1002
1003         % ugh
1004         currentpicture := currentpicture shifted (hround (w / 2), 0);
1005
1006         remember_pic := currentpicture;
1007
1008         draw_staff (-2, 2, 0);
1009 fet_endchar;
1010
1011
1012 draw_shifted_too;
1013
1014
1015 def draw_paren =
1016         save leftindent;
1017
1018         leftindent := .2 staff_space;
1019
1020         set_char_box (0, .5 staff_space# + stafflinethickness#,
1021                       staff_space#, staff_space#);
1022
1023         d := d - feta_shift;
1024
1025         z1 = (leftindent, h);
1026         z2 = (w - stafflinethickness, .5 (h - d));
1027         z3 = (leftindent, -d);
1028
1029         penpos1 (stafflinethickness, 35);
1030         penpos2 (.1 staff_space + stafflinethickness, 0);
1031         penpos3 (stafflinethickness, -35);
1032
1033         fill z2l{down}
1034              .. simple_serif (z3l, z3r, 90)
1035              .. z2r{up}
1036              .. simple_serif (z1r, z1l, 90)
1037              .. z2l{down}
1038              -- cycle;
1039 enddef;
1040
1041
1042 fet_beginchar ("Right Parenthesis", "rightparen");
1043         draw_paren;
1044         penlabels (1, 2, 3);
1045
1046         remember_pic := currentpicture;
1047
1048         draw_staff (-2, 2, 0);
1049 fet_endchar;
1050
1051
1052 draw_shifted_too;
1053
1054
1055 fet_beginchar ("Left Parenthesis", "leftparen");
1056         draw_paren;
1057
1058         currentpicture := currentpicture xscaled -1;
1059
1060         set_char_box (charwd, charbp, chardp, charht);
1061 fet_endchar;
1062
1063 fet_endgroup ("accidentals");