1 % Feta (not the Font-En-Tja) music font -- Accidentals
2 % This file is part of LilyPond, the GNU music typesetter.
4 % Copyright (C) 1997--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 % LilyPond is free software: you can redistribute it and/or modify
8 % it under the terms of the GNU General Public License as published by
9 % the Free Software Foundation, either version 3 of the License, or
10 % (at your option) any later version.
12 % LilyPond is distributed in the hope that it will be useful,
13 % but WITHOUT ANY WARRANTY; without even the implied warranty of
14 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 % GNU General Public License for more details.
17 % You should have received a copy of the GNU General Public License
18 % along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
22 % also show in other configuration wrt staff lines.
24 def draw_shifted_too =
26 fet_beginchar ("shifted too", "");
27 set_char_box (0, 0, 0, 0);
28 currentpicture := remember_pic;
30 draw_staff (-2, 2, 0.5);
37 % Accidentals from various sources, notably
39 % Baerenreiter edition of Schuberts `Auf dem Strom' (sharp, natural)
40 % F Hofmeister edition of Muellers `Etueden fuer Horn' (double sharp, flat)
45 % Naming for accidentals (including microtonal variants):
47 % SHARPBASE[.SLASHES.STEMS]
52 % sharp.slashslash.stem
58 fet_begingroup ("accidentals");
63 % * `stemslant' gives the direction of the stem's left boundary
64 % (needed for brushed stems, equals "up" for straight stems)
65 % * `extend' is used to make the stem longer or shorter (if negative);
66 % different kinds of accidentals need different values here
68 def draw_arrow (expr attach, stemwidth, stemslant, extend, pointingdown) =
70 save htip; % tip height
71 save wwing; % wing `radius'
72 save angle_wing_bot, angle_wing_top, angle_tip;
76 wwing := 0.26 stemwidth;
77 htip := staff_space * 0.85 + stafflinethickness - wwing;
79 % `flip' is used to reflect the arrow vertically
80 % if arrow points downward
83 flip = identity reflectedabout (origin, right);
88 z1 = attach shifted (-stemwidth / 2, 0);
89 upshift := max (0, wwing + 0.1 staff_space + extend);
90 z2 = z1 shifted (((unitvector stemslant)
91 scaled upshift) transformed flip);
93 z7 = attach shifted ((stemwidth/2),0);
94 z6 = z7 shifted (((unitvector (-xpart stemslant, ypart stemslant))
95 scaled upshift) transformed flip);
96 z2 - z3 = ( 0.38 staff_space, 0.05 htip) transformed flip;
97 z6 - z5 = (-0.38 staff_space, 0.05 htip) transformed flip;
99 z4 = attach shifted ((-0.2 stemwidth, upshift + htip)
101 z4'= attach shifted (( 0.2 stemwidth, upshift + htip)
104 % `angle_wing_bot' is the angle at which the arc
105 % from z2 to z3a enters z3a
106 % `angle_wing_top' is the angle at which the arc
107 % from z3b to z4 leaves z3b
108 % `angle_tip' is the angle at which the arc
109 % from z4 to z4' leaves z4
114 z3a = z3 shifted ((((dir angle_wing_bot) rotated -90)
115 scaled wwing) transformed flip);
116 z3b = z3 shifted ((((dir angle_wing_top) rotated 90)
117 scaled wwing) transformed flip);
119 z5a = z5 shifted ((((dir (180 - angle_wing_bot)) rotated 90)
120 scaled wwing) transformed flip);
121 z5b = z5 shifted ((((dir (180 - angle_wing_top)) rotated -90)
122 scaled wwing) transformed flip);
125 pickup pencircle scaled 1;
127 -- z2{stemslant transformed flip}
128 .. {(-dir angle_wing_bot) transformed flip}z3a
129 .. z3b{(dir angle_wing_top) transformed flip}
130 .. z4{(dir angle_tip) transformed flip}
131 .. z4'{(dir (-angle_tip)) transformed flip}
132 .. {(dir (-angle_wing_top)) transformed flip}z5b
133 .. z5a{(-dir (-angle_wing_bot)) transformed flip}
134 .. z6{((-stemslant) reflectedabout (origin, up)) transformed flip}
138 labels (range 0 thru 7, 4', 3a, 3b, 5a, 5b);
143 picture remember_pic;
145 save sharp_beamheight;
146 sharp_beamheight# := 0.3 staff_space# + stafflinethickness#;
149 % The beams of most sharps have horizontal endings (as if drawn with
150 % a square pen). [Wanske] does not mention this, so we'll just ignore
154 def draw_meta_sharp (expr width, offset) =
155 save beamwidth, beamslope;
161 define_whole_vertical_blacker_pixels (sharp_beamheight);
165 beamslope = sharp_beamheight / beamwidth;
167 pickup pencircle scaled 2 blot_diameter;
169 rt x2 - lft x1 = beamwidth;
170 z2 = z1 + whatever * (beamwidth, sharp_beamheight);
171 .5 [z1, z3] = (.5 w, offset);
173 top y2 - bot y3 = sharp_beamheight;
175 top y1 - bot y4 = sharp_beamheight;
177 ne = unitvector (z2 - z1);
178 nw_dist = (ne rotated 90) * blot_diameter;
181 ... (z1 + nw_dist){ne}
182 -- (z2 + nw_dist){ne}
185 ... (z3 - nw_dist){-ne}
186 -- (z4 - nw_dist){-ne}
194 def draw_sharp(expr arrowup, arrowdown) =
195 save stem, stemx, stemwidth;
196 save outer_space, interbeam;
197 save stemlength, extendleft, extendright, height, depth;
199 stemwidth# := stafflinethickness# + .05 staff_space#;
200 define_whole_blacker_pixels (stemwidth);
202 interbeam := 1.05 staff_space_rounded;
204 stemlength# := 1.5 staff_space#;
205 define_pixels (stemlength);
207 height# = stemlength#;
208 depth# = stemlength#;
212 height# := height# + 1.2 staff_space#;
213 extendright# := extendright# + 1.5 stafflinethickness#;
216 depth# := depth# + 1.2 staff_space#;
217 extendleft# := extendleft# + 1.5 stafflinethickness#;
219 define_pixels (extendleft, extendright);
220 set_char_box (extendleft#, 1.1 staff_space#, depth#, height#);
223 stemx := hround stem;
224 outer_space := hround ((w - stemx - stemwidth) / 2);
226 w := 2 outer_space + stemx + stemwidth;
227 d := d - feta_space_shift;
229 draw_meta_sharp (w, -.5 interbeam);
230 draw_meta_sharp (w, -.5 interbeam + vround interbeam);
232 % expand the charbox so that it encloses the whole arrow;
233 % this must not happen earlier because some commands above
234 % still rely on the old width
235 w := w + extendright;
237 pickup pencircle scaled stemwidth;
239 lft x5 = lft x6 = outer_space;
240 lft x7 = lft x8 = outer_space + stemx;
241 bot y5 = -stemlength;
242 top y6 = vround (1.5 staff_space - stem * beamslope);
243 bot y7 = -top y6 + feta_space_shift;
248 draw_gridline (z5, z6, stemwidth);
249 draw_gridline (z7, z8, stemwidth);
252 draw_arrow (z8, stemwidth, up,
253 stafflinethickness / 2 + stemwidth / 2, false);
256 draw_arrow (z5, stemwidth, up,
257 stafflinethickness / 2 + stemwidth / 2, true);
260 remember_pic := currentpicture;
262 draw_staff (-2, 2, 0);
266 fet_beginchar ("Sharp", "sharp");
267 draw_sharp (false, false);
274 fet_beginchar ("Arrowed Sharp (arrow up)", "sharp.arrowup");
275 draw_sharp (true, false);
282 fet_beginchar ("Arrowed Sharp (arrow down)", "sharp.arrowdown");
283 draw_sharp (false, true);
290 fet_beginchar ("Arrowed Sharp (arrows up and down)", "sharp.arrowboth");
291 draw_sharp (true, true);
298 fet_beginchar ("1/2 Sharp", "sharp.slashslash.stem");
299 save stem, stemwidth;
300 save outer_space, interbeam;
302 stemwidth# := stafflinethickness# + .05 staff_space#;
303 define_whole_blacker_pixels (stemwidth);
305 interbeam := 1.05 staff_space_rounded;
307 set_char_box (0, 0.7 staff_space#,
308 1.5 staff_space#, 1.5 staff_space#);
311 outer_space := hround ((w - stemwidth) / 2);
313 w := 2 outer_space + stemwidth;
314 d := d - feta_space_shift;
316 draw_meta_sharp (w, -.5 interbeam);
317 draw_meta_sharp (w, -.5 interbeam + vround interbeam);
319 pickup pencircle scaled stemwidth;
321 lft x5 = lft x6 = outer_space;
322 top y6 = vround (1.5 staff_space - .5 stem);
323 bot y5 = -top y6 + feta_space_shift;
327 draw_gridline (z5, z6, stemwidth);
329 remember_pic := currentpicture;
331 draw_staff (-2, 2, 0);
338 fet_beginchar ("Sharp (3 beams)", "sharp.slashslashslash.stemstem");
339 save stem, stemx, stemwidth;
340 save outer_space, interbeam;
341 save sharp_beamheight;
343 sharp_beamheight# := 0.22 staff_space# + stafflinethickness#;
345 stemwidth# := stafflinethickness# + .05 staff_space#;
346 define_whole_blacker_pixels (stemwidth);
348 interbeam := 1.2 staff_space_rounded;
350 set_char_box (0, 1.1 staff_space#,
351 1.5 staff_space#, 1.5 staff_space#);
354 stemx := hround stem;
355 outer_space := hround ((w - stemx - stemwidth) / 2);
357 w := 2 outer_space + stemx + stemwidth;
358 d := d - feta_space_shift;
360 draw_meta_sharp (.88 w, -.5 interbeam);
361 draw_meta_sharp (.88 w, -.5 interbeam + vround interbeam);
362 sharp_beamheight# := 1/.88 sharp_beamheight#;
363 draw_meta_sharp (w, 0);
365 pickup pencircle scaled stemwidth;
367 lft x5 = lft x6 = outer_space;
368 lft x7 = lft x8 = outer_space + stemx;
370 top y6 = vround (1.5 staff_space - stem * beamslope);
371 bot y7 = -top y6 + feta_space_shift;
376 draw_gridline (z5, z6, stemwidth);
377 draw_gridline (z7, z8, stemwidth);
379 remember_pic := currentpicture;
381 draw_staff (-2, 2, 0);
388 fet_beginchar ("1/2 Sharp (3 beams)", "sharp.slashslashslash.stem");
389 save stem, stemx, stemwidth;
390 save outer_space, interbeam;
391 save sharp_beamheight;
393 sharp_beamheight# := 0.22 staff_space# + stafflinethickness#;
395 stemwidth# := stafflinethickness# + .05 staff_space#;
396 define_whole_blacker_pixels (stemwidth);
398 interbeam := 1.2 staff_space_rounded;
400 set_char_box (0, 0.95 staff_space#,
401 1.3 staff_space#, 1.3 staff_space#);
404 outer_space := hround ((w - stemwidth) / 2);
406 w := 2 outer_space + stemwidth;
407 d := d - feta_space_shift;
409 draw_meta_sharp (.8 w, -.5 interbeam);
410 draw_meta_sharp (.8 w, -.5 interbeam + vround interbeam);
411 sharp_beamheight# := 1/.8 sharp_beamheight#;
412 draw_meta_sharp (w, 0);
414 pickup pencircle scaled stemwidth;
416 lft x5 = lft x6 = outer_space;
417 top y6 = vround (1.5 staff_space - .5 stem);
418 bot y5 = -top y6 + feta_space_shift;
421 draw_gridline (z5, z6, stemwidth);
423 remember_pic := currentpicture;
425 draw_staff (-2, 2, 0);
432 fet_beginchar ("3/4 Sharp", "sharp.slashslash.stemstemstem");
433 save stem, stemx, stemwidth;
434 save outer_space, interbeam;
436 stemwidth# := stafflinethickness# + .05 staff_space#;
437 define_whole_blacker_pixels (stemwidth);
439 interbeam := 1.05 staff_space_rounded;
441 set_char_box (0, 1.6 staff_space#,
442 1.5 staff_space#, 1.5 staff_space#);
445 stemx := hround stem;
446 outer_space := hround ((w - 2 stemx - stemwidth) / 2);
448 w := 2 outer_space + 2 stemx + stemwidth;
449 d := d - feta_space_shift;
451 draw_meta_sharp (w, -.5 interbeam);
452 draw_meta_sharp (w, -.5 interbeam + vround interbeam);
454 pickup pencircle scaled stemwidth;
456 lft x5 = lft x6 = outer_space;
457 lft x7 = lft x8 = outer_space + stemx;
458 lft x9 = lft x10 = outer_space + 2 stemx;
460 top y6 = vround (1.5 staff_space - 2 stem * beamslope);
461 bot y9 = -top y6 + feta_space_shift;
466 labels (5, 6, 7, 8, 9, 10);
468 draw_gridline (z5, z6, stemwidth);
469 draw_gridline (z7, z8, stemwidth);
470 draw_gridline (z9, z10, stemwidth);
472 remember_pic := currentpicture;
474 draw_staff (-2, 2, 0);
482 % The stems of the natural are brushed (at least, in Barenreiter SCS)
485 def draw_natural (expr arrowup, arrowdown) =
486 save stemwidth, top_stem_thick;
487 save ne, pat_top, pat_bottom;
488 save depth, height, extendleft, extendright, stemlength;
489 save brush_scale_up, brush_scale_down;
491 path pat_top, pat_bottom;
493 top_stem_thick# = stafflinethickness# + .10 staff_space#;
494 stemwidth# = 0.09 staff_space# + .5 stafflinethickness#;
495 define_whole_blacker_pixels (top_stem_thick, stemwidth);
497 stemlength# = 1.5 staff_space#;
498 define_pixels (stemlength);
500 height# = stemlength#;
501 depth# = stemlength#;
505 extendleft# := 3 stafflinethickness#;
506 height# := height# + 1.2 staff_space#;
509 extendright# := 3.15 stafflinethickness#;
510 depth# := depth# + 1.2 staff_space#;
512 define_pixels (extendright);
514 set_char_box (extendleft#, 2/3 staff_space#, depth#, height#);
516 d := d - feta_space_shift;
518 pickup pencircle scaled stemwidth;
520 brush_scale_up := 1.0;
521 brush_scale_down := 1.0;
522 % to look nice, arrowed stems must be less brushed
524 brush_scale_up := 0.85;
527 brush_scale_down := 0.85;
530 penpos1 (top_stem_thick, 0);
531 penpos3 (top_stem_thick, 0);
532 penpos2 (stemwidth, 0);
533 penpos4 (stemwidth, 0);
534 % z1' and z3' are needed for the arrowed accidentals
535 penpos1' (top_stem_thick * brush_scale_up, 0);
536 penpos3' (top_stem_thick * brush_scale_down, 0);
543 y1 = y1' = stemlength;
544 y3 = y3' = -stemlength;
545 top y2 = vround (staff_space - 3/2 stafflinethickness);
546 y4 = -y2 + feta_space_shift;
548 pat_bottom := z4r{z4r - z1r}
551 fill simple_serif (z1'l, z1'r, -30)
555 pat_top := z2r{z2r - z3r}
558 fill simple_serif (z3'l, z3'r, 30)
562 ne = (x2 - x4, stafflinethickness);
564 z11' = z3l + whatever * (z2l - z3l);
565 y11' = vround (.5 (staff_space - stafflinethickness));
566 z11 = z11' + whatever * ne;
568 z12 = directionpoint -ne of pat_top;
569 z13 = z12 + whatever * ne;
571 z14 = z11 + whatever * ne;
574 z21' = z4r + whatever * (z1r - z4r);
575 y21' = -y11' + feta_space_shift;
576 z21 = z21' + whatever * ne;
578 z22 = directionpoint -ne of pat_bottom;
579 z23 = z22 + whatever * ne;
581 z24 = z21 + whatever * ne;
595 penlabels (1, 1', 2, 3, 3', 4);
596 labels (11, 11', 12, 13, 14, 21, 21', 22, 23, 24);
599 draw_arrow (z1, top_stem_thick * brush_scale_up,
600 z1'l - z4l, stafflinethickness / 2, false);
603 draw_arrow (z3, top_stem_thick * brush_scale_down,
604 z2r - z3'r, stafflinethickness / 2, true);
605 w := w + extendright;
608 remember_pic := currentpicture;
610 draw_staff (-2, 2, 0);
614 fet_beginchar ("Natural", "natural");
615 draw_natural (false, false);
622 fet_beginchar ("Arrowed Natural (arrow up)", "natural.arrowup");
623 draw_natural (true, false);
630 fet_beginchar ("Arrowed Natural (arrow down)", "natural.arrowdown");
631 draw_natural (false, true);
638 fet_beginchar ("Arrowed Natural (arrows up and down)", "natural.arrowboth");
639 draw_natural (true, true);
647 % Dedicated to my mom. (3/10/97)
649 % Mamma, ik hou van je; kom je alsjeblieft terug?
653 % TODO: remove crook_fatness
654 % TODO: document, simplify!
657 def draw_meta_flat (expr xcenter, w, crook_fatness, arrowup, arrowdown) =
659 save bottom_overshoot, bot_crook_dir;
660 save top_stem_thick, top_stem_thick_orig;
661 save bottom_stem_thick, hair, smaller_hole;
662 save top_crook_thinness;
665 pair center, bot_crook_dir;
666 save clearing, clearing_orig;
670 % the stem shouldn't reach the top staff line.
671 %% TODO: should take from height.
673 % TODO: parameterize this
675 if w >= 0.75 staff_space:
676 smaller_hole = 0.35 stafflinethickness;
680 crook_thinness = .7 stafflinethickness + .06 staff_space;
681 top_crook_thinness = 1 stafflinethickness + .065 staff_space;
682 clearing = 1.7 stafflinethickness;
683 clearing_orig = clearing;
685 clearing := 0.5 staff_space;
687 bottom_overshoot = stafflinethickness;
689 bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
690 top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
691 top_stem_thick_orig# = top_stem_thick#;
693 % to look nice, arrowed stems should be less brushed
694 top_stem_thick# := top_stem_thick# * 0.8;
696 define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick,
697 top_stem_thick_orig);
699 if odd (top_stem_thick - bottom_stem_thick):
700 top_stem_thick := top_stem_thick - 1;
702 if odd (top_stem_thick_orig - bottom_stem_thick):
703 top_stem_thick_orig := top_stem_thick_orig - 1;
706 center = (xcenter, 0);
708 x1l = hround (xcenter - .5 top_stem_thick);
709 y1 = vround (2 staff_space - clearing);
710 x2l = hround (xcenter - .5 bottom_stem_thick);
711 y2 = -.5 staff_space - .5 stafflinethickness;
712 % z16 and the `*_orig' variables are needed for arrowed accidentals
713 % because their inner part should be unchanged from plain ones but
714 % the points z3l, z3r, and z10 depend on values that are different
715 % for arrowed accidentals
716 x16l = hround (xcenter -.5 top_stem_thick_orig);
717 y16 = vround (2 staff_space - clearing_orig);
719 penpos1 (top_stem_thick, 0);
720 penpos16 (top_stem_thick_orig, 0);
721 penpos2 (bottom_stem_thick, 0);
723 y3l = vfloor ((staff_space - stafflinethickness) / 2);
724 z3l = whatever [z2r, z1r];
726 (z16r shifted (0, clearing_orig - 1.7 stafflinethickness))]
730 % we insert z3l to get better conversion with mf2pt1
731 fill simple_serif (z1r, z1l, 30)
737 z10 = whatever [z2r, z16r] + (smaller_hole, 0);
738 y10 = -1/10 staff_space;
741 x11 = xcenter + bottom_overshoot / 3;
742 y11 = -vround (.5 (staff_space + stafflinethickness)
748 penpos4 (whatever, 53);
750 y4l - y4r = top_crook_thinness;
751 y5r = .15 staff_space;
752 x5l = hround (w + xcenter);
753 y4 = staff_space / 2;
754 x4r = .45 [x5r, x3r];
757 penpos5 (crook_fatness, -175);
759 bot_crook_dir = unitvector ((x5l, 0) - z11);
760 z8 = z11 + whatever * bot_crook_dir;
761 y8 = -staff_space / 2;
764 + whatever * bot_crook_dir
765 + crook_thinness * (bot_crook_dir rotated 90);
768 unfill z3r{z3r - z10}
771 .. z7{-bot_crook_dir}
795 draw_arrow (z1, top_stem_thick, z1l - z2l,
796 0.5 stafflinethickness, false);
799 draw_arrow ((0.5 [x2l, x2a], y2), x2a - x2l, up,
800 staff_space / 2, true);
805 def draw_arrowed_meta_flat (expr xcenter, width, crook_fatness,
806 arrowup, arrowdown) =
807 save depth, height, extendleft;
809 depth# = 0.6 staff_space#;
810 height# = 1.9 staff_space#;
811 extendleft# := 1.2 stafflinethickness#;
813 extendleft# := 3.45 stafflinethickness#;
814 height# := height# + 0.8 staff_space#;
817 extendleft# := 3.45 stafflinethickness#;
818 depth# := depth# + 1.6 staff_space#;
821 set_char_box (extendleft#, width, depth#, height#);
822 draw_meta_flat(xcenter, w, crook_fatness, arrowup, arrowdown);
826 % unfortunately, 600dpi is not enough to show the brush of the stem.
829 fet_beginchar ("Flat", "flat");
830 draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
832 penlabels (range 0 thru 11);
834 remember_pic := currentpicture;
836 draw_staff (-2, 2, 0);
843 fet_beginchar ("Arrowed Flat (arrow up)", "flat.arrowup");
844 draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
846 penlabels (range 0 thru 23);
848 remember_pic := currentpicture;
850 draw_staff (-2, 2, 0);
857 fet_beginchar ("Arrowed Flat (arrow down)", "flat.arrowdown");
858 draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
860 penlabels (range 0 thru 23);
862 remember_pic := currentpicture;
864 draw_staff (-2, 2, 0);
871 fet_beginchar ("Arrowed Flat (arrow up and down)", "flat.arrowboth");
872 draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space,
874 penlabels (range 0 thru 23);
876 remember_pic := currentpicture;
878 draw_staff (-2, 2, 0);
885 fet_beginchar ("Flat (slashed)", "flat.slash");
886 set_char_box (.4 staff_space#, .8 staff_space#,
887 0.6 staff_space#, 1.9 staff_space#);
889 draw_meta_flat (0, w, 0.31 staff_space, false, false);
893 save slope, slash_width;
898 z12 = z11 - (slash_width, slash_width * slope) / 2;
899 z13 = z11 + (slash_width, slash_width * slope) / 2;
900 penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
901 penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
903 z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
904 z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
918 remember_pic := currentpicture;
920 draw_staff (-2, 2, 0);
924 fet_beginchar ("Flat (slashed twice)", "flat.slashslash");
925 set_char_box (.4 staff_space#, .8 staff_space#,
926 0.6 staff_space#, 1.9 staff_space#);
928 draw_meta_flat (0, w, 0.31 staff_space, false, false);
932 save slope, slash_width;
937 z12 = z11 - (slash_width, slash_width * slope) / 2;
938 z13 = z11 + (slash_width, slash_width * slope) / 2;
939 penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
940 penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
942 z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
943 z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
958 z22 = z21 - (slash_width, slash_width * slope) / 2;
959 z23 = z21 + (slash_width, slash_width * slope) / 2;
960 penpos22 (1.5 stafflinethickness, angle (z23 - z22) - 90);
961 penpos23 (1.5 stafflinethickness, angle (z23 - z22) - 90);
963 z24 = z22 - .75 stafflinethickness * unitvector (z23 - z22);
964 z25 = z23 + .75 stafflinethickness * unitvector (z23 - z22);
978 remember_pic := currentpicture;
980 draw_staff (-2, 2, 0);
984 fet_beginchar ("Flatflat (mirrored)", "mirroredflat.flat");
985 set_char_box (0, 1.6 staff_space#,
986 0.6 staff_space#, 1.9 staff_space#);
988 % This is a modified version of `draw_meta_flat'.
990 save crook_thinness, crook_fatness;
991 save bottom_overshoot, bot_crook_dir;
992 save top_stem_thick, bottom_stem_thick, hair, smaller_hole;
993 save top_crook_thinness;
996 pair center, bot_crook_dir;
1005 % the stem shouldn't reach the top staff line.
1006 %% TODO: should take from height.
1008 % TODO: parameterize this
1010 if wid >= 0.75 staff_space:
1011 smaller_hole = 0.35 stafflinethickness;
1015 clearing = 1.7 stafflinethickness;
1016 crook_thinness = .7 stafflinethickness + .06 staff_space;
1017 crook_fatness = 0.31 staff_space;
1018 top_crook_thinness = 1 stafflinethickness + .065 staff_space;
1019 bottom_overshoot = stafflinethickness;
1021 bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
1022 top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
1023 define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick);
1025 if odd (top_stem_thick - bottom_stem_thick):
1026 top_stem_thick := top_stem_thick - 1;
1031 x1l = hround (-.5 top_stem_thick);
1032 y1 = vround (2 staff_space - clearing);
1033 x2l = hround (-.5 bottom_stem_thick);
1034 y2 = -.5 staff_space - .5 stafflinethickness;
1036 penpos1 (top_stem_thick, 0);
1037 penpos2 (bottom_stem_thick, 0);
1039 y3l = vfloor ((staff_space - stafflinethickness) / 2);
1040 z3l = whatever [z2r, z1r];
1041 z3r = .3 [z2r, z1r] + (smaller_hole, 0);
1042 x3r := hceiling x3r;
1044 z10 = whatever [z2r, z1r] + (smaller_hole, 0);
1045 y10 = -1/10 staff_space;
1046 x10 := hceiling x10;
1048 x11 = bottom_overshoot / 3;
1049 y11 = -vround (.5 (staff_space + stafflinethickness)
1050 + bottom_overshoot);
1052 penpos4 (whatever, 53);
1054 y4l - y4r = top_crook_thinness;
1055 y5r = .15 staff_space;
1057 y4 = staff_space / 2;
1058 x4r = .45 [x5r, x3r];
1061 penpos5 (crook_fatness, -175);
1063 bot_crook_dir = unitvector ((x5l, 0) - z11);
1064 z8 = z11 + whatever * bot_crook_dir;
1065 y8 = -staff_space / 2;
1068 + whatever * bot_crook_dir
1069 + crook_thinness * (bot_crook_dir rotated 90);
1072 pat := z3r{z3r - z10}
1075 .. z7{-bot_crook_dir}
1080 unfill pat xscaled -1;
1083 .. z8{bot_crook_dir}
1088 -- simple_serif (z1r, z1l, 30)
1089 -- reverse pat xscaled -1 shifted (-feta_eps, 0)
1092 currentpicture := currentpicture shifted (w/2, 0);
1094 remember_pic := currentpicture;
1096 draw_staff (-2, 2, 0);
1103 fet_beginchar ("Semi flat", "mirroredflat");
1104 set_char_box (1.2 stafflinethickness#, .8 staff_space#,
1105 0.6 staff_space#, 1.9 staff_space#);
1107 draw_meta_flat (0, w, 0.31 staff_space, false, false);
1108 currentpicture := currentpicture xscaled -1 shifted (w - b, 0);
1112 fet_beginchar ("Semi flat", "mirroredflat.backslash");
1113 set_char_box (.4 staff_space#, .8 staff_space#,
1114 0.6 staff_space#, 1.9 staff_space#);
1116 draw_meta_flat (0, w, 0.31 staff_space, false, false);
1120 save slope, slash_width;
1125 z12 = z11 - (slash_width, slash_width * slope) / 2;
1126 z13 = z11 + (slash_width, slash_width * slope) / 2;
1127 penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90);
1128 penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90);
1130 z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12);
1131 z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12);
1142 currentpicture := currentpicture xscaled -1 shifted (w - b, 0);
1148 fet_beginchar ("Double Flat", "flatflat");
1149 save left_wid, overlap, right_wid;
1155 set_char_box (1.2 stafflinethickness#,
1156 (left_wid + right_wid - overlap) * staff_space#,
1157 .6 staff_space#, 1.9 staff_space#);
1158 draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space,
1160 draw_meta_flat (hround ((left_wid - overlap) * staff_space),
1161 right_wid * staff_space, 1/3 staff_space,
1166 fet_beginchar ("3/4 Flat", "flatflat.slash");
1167 save left_wid, overlap, right_wid;
1173 set_char_box (1.2 stafflinethickness#,
1174 (left_wid + right_wid - overlap) * staff_space#,
1175 .6 staff_space#, 1.9 staff_space#);
1176 draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space,
1178 draw_meta_flat (hround ((left_wid - overlap) * staff_space),
1179 right_wid * staff_space, 1/3 staff_space,
1182 %% maybe we should clip part of the stems?
1183 %% or make the 1st flat smaller?
1185 pickup pencircle scaled 2 stafflinethickness;
1187 z12 = round (-.25 w - b, .55 staff_space) + feta_offset;
1188 z13 = round (.75 w, 1.45 staff_space) + feta_offset;
1189 penpos12 (2 stafflinethickness, angle (z13 - z12) - 90);
1190 penpos13 (2 stafflinethickness, angle (z13 - z12) - 90);
1192 z14 = z12 - stafflinethickness * unitvector (z13 - z12);
1193 z15 = z13 + stafflinethickness * unitvector (z13 - z12);
1207 remember_pic := currentpicture;
1209 draw_staff (-2, 2, 0);
1216 fet_beginchar ("Double Sharp", "doublesharp");
1217 save klaverblad, klaversteel;
1221 klaversteel = 1/15 staff_space;
1222 klaverblad = .4 staff_space - .5 stafflinethickness;
1224 set_char_box (0, staff_space#, .5 staff_space#, .5 staff_space#);
1226 z1 = (klaversteel, 0);
1227 z2 = (w / 2 - klaverblad / 10, h - klaverblad);
1229 z4 = z2 reflectedabout ((0, 0), (1, 1));
1230 z5 = z1 reflectedabout ((0, 0), (1, 1));
1232 labels (1, 2, 3, 4, 5);
1234 pickup pencircle scaled blot_diameter;
1236 x2 := hfloor (rt x2) - blot_diameter / 2;
1237 x3 := hfloor (rt x3) - blot_diameter / 2;
1238 y3 := vfloor (top y3) - blot_diameter / 2;
1239 y4 := vfloor (top y4) - blot_diameter / 2;
1241 pat = (rt z1){dir45}
1248 .. {dir 225}(top z5);
1250 -- reverse pat xscaled -1 shifted (-feta_eps, 0);
1252 % assure symmetry -- it's more important to center the glyph on the
1253 % staff line than centering it between staff lines, so we use
1254 % feta_shift, not feta_space_shift.
1255 h := h + feta_shift;
1257 fill pat shifted (0, feta_shift)
1258 -- reverse pat yscaled -1 shifted (0, -feta_eps)
1262 currentpicture := currentpicture shifted (hround (w / 2), 0);
1264 remember_pic := currentpicture;
1266 draw_staff (-2, 2, 0);
1276 leftindent := .2 staff_space;
1278 set_char_box (0, .5 staff_space# + stafflinethickness#,
1279 staff_space#, staff_space#);
1281 d := d - feta_shift;
1283 z1 = (leftindent, h);
1284 z2 = (w - stafflinethickness, .5 (h - d));
1285 z3 = (leftindent, -d);
1287 penpos1 (stafflinethickness, 35);
1288 penpos2 (.1 staff_space + stafflinethickness, 0);
1289 penpos3 (stafflinethickness, -35);
1292 .. simple_serif (z3l, z3r, 90)
1294 .. simple_serif (z1r, z1l, 90)
1300 fet_beginchar ("Right Parenthesis", "rightparen");
1302 penlabels (1, 2, 3);
1304 remember_pic := currentpicture;
1306 draw_staff (-2, 2, 0);
1313 fet_beginchar ("Left Parenthesis", "leftparen");
1316 currentpicture := currentpicture xscaled -1;
1318 set_char_box (charwd, charbp, chardp, charht);
1321 fet_endgroup ("accidentals");