]> git.donarmstrong.com Git - lilypond.git/blob - mf/feta-noteheads.mf
change longas similarly to how breves were changed
[lilypond.git] / mf / feta-noteheads.mf
1 % Feta (not the Font-En-Tja) music font -- implement noteheads
2 % This file is part of LilyPond, the GNU music typesetter.
3 %
4 % Copyright (C) 1997--2011 Jan Nieuwenhuizen <janneke@gnu.org>
5 % & Han-Wen Nienhuys <hanwen@xs4all.nl>
6 % & Juergen Reuter <reuter@ipd.uka.de>
7 %
8 %
9 % LilyPond is free software: you can redistribute it and/or modify
10 % it under the terms of the GNU General Public License as published by
11 % the Free Software Foundation, either version 3 of the License, or
12 % (at your option) any later version.
13 %
14 % LilyPond is distributed in the hope that it will be useful,
15 % but WITHOUT ANY WARRANTY; without even the implied warranty of
16 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 % GNU General Public License for more details.
18 %
19 % You should have received a copy of the GNU General Public License
20 % along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
21
22 test_outlines := 0;
23
24
25 save remember_pic;
26 picture remember_pic;
27
28
29 % Most beautiful noteheads are pronounced, not circular,
30 % and not even symmetric.
31 % These examples are inspired by [Wanske]; see literature list.
32
33
34
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 % NOTE HEAD VARIABLES
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38
39 save half_notehead_width, whole_notehead_width;
40 save solfa_noteheight;
41
42 numeric whole_notehead_width;
43 numeric half_notehead_width;
44
45 fet_begingroup ("noteheads");
46
47
48 %
49 % solfa heads should not overlap on chords.
50 %
51 solfa_noteheight# := staff_space# - stafflinethickness#;
52
53 def undraw_inside_ellipse (expr ellipticity, tilt, superness, clearance) =
54 begingroup
55         save pat;
56         path pat;
57
58         pat := superellipse ((ellipticity, 0), (0, 1.0),
59                              (-ellipticity, 0), (0, -1.0),
60                              superness);
61         pat := pat rotated tilt;
62
63         save top_point, right_point;
64         pair top_point, right_point;
65
66         top_point := directionpoint left of pat;
67         right_point := directionpoint up of pat;
68
69         save height, scaling;
70
71         height# = staff_space# + stafflinethickness# - clearance;
72         scaling# = height# / (2 ypart (top_point));
73         define_pixels (scaling);
74         pat := pat scaled scaling shifted (w / 2, .5 (h - d));
75
76         if test_outlines = 1:
77                 draw pat;
78         else:
79                 unfill pat;
80         fi
81 endgroup;
82 enddef;
83
84
85 def draw_longa (expr up) =
86         save stemthick, fudge;
87
88         stemthick# = 2 stafflinethickness#;
89         define_whole_blacker_pixels (stemthick);
90
91         % Longas of smaller design sizes should have their lines farther
92         % apart (the overlap with notehead ellipsoid should be smaller).
93         fudge = hround (blot_diameter
94                         * min (max (-0.15,
95                                     (0.9
96                                      - (20 / (design_size + 4)))),
97                                0.3));
98
99         draw_outside_ellipse (1.80, 0, 0.707, 0);
100         undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#);
101
102         set_char_box (stemthick#,
103                       width# + stemthick#,
104                       noteheight# / 2,
105                       noteheight# / 2);
106
107         pickup pencircle scaled stemthick;
108
109         % Longas of smaller design sizes should have their lines longer.
110         line_length := min (max (0.7, (64/60 - (design_size / 60))), 0.85);
111
112         % Line lengths between 0.72 and 0.77 are not nice
113         % because they are neither separate nor connected
114         % when there is an interval of fourth.
115         if line_length < 0.75:
116                 quanted_line_length := min (0.72, line_length);
117         else:
118                 quanted_line_length := max (0.77, line_length);
119         fi;
120
121         if up:
122                 bot y1 = -quanted_line_length * staff_space;
123                 top y2 = quanted_line_length * staff_space;
124                 rt x1 - fudge = 0;
125                 x1 = x2;
126
127                 fudge + lft x3 = width;
128                 x4 = x3;
129                 top y4 = h + 3.0 staff_space;
130                 y3 = y1;
131         else:
132                 bot y1 = -d - 3.0 staff_space;
133                 top y2 = quanted_line_length * staff_space;
134                 rt x1 - fudge = 0;
135                 x1 = x2;
136
137                 fudge + lft x3 = width;
138                 x4 = x3;
139                 y4 = y2;
140                 bot y3 = -quanted_line_length * staff_space;
141         fi;
142
143         draw_gridline (z1, z2, stemthick);
144         draw_gridline (z3, z4, stemthick);
145
146         labels (1, 2, 3, 4);
147 enddef;
148
149
150 fet_beginchar ("Longa notehead", "uM2");
151         draw_longa (true);
152
153         draw_staff (-2, 2, 0);
154 fet_endchar;
155
156
157 fet_beginchar ("Longa notehead", "dM2");
158         draw_longa (false);
159
160         draw_staff (-2, 2, 0);
161 fet_endchar;
162
163
164 if test > 0:
165         fet_beginchar ("Longa notehead", "uM2");
166                 draw_longa (true);
167
168                 draw_staff (-2, 2, 0.5);
169         fet_endchar;
170
171
172         fet_beginchar ("Longa notehead", "dM2");
173                 draw_longa (false);
174
175                 draw_staff (-2, 2, 0.5);
176         fet_endchar;
177 fi;
178
179
180 def draw_brevis (expr linecount, line_thickness_multiplier) =
181         save stemthick, fudge, gap;
182
183         stemthick# = line_thickness_multiplier * 2 * stafflinethickness#;
184         define_whole_blacker_pixels (stemthick);
185
186         % double-lined breves of smaller design sizes should have
187         % bigger gap between the lines.
188         gap# := (0.95 - 0.008 * design_size) * stemthick#;
189
190         % Breves of smaller design sizes should have their lines farther
191         % apart (the overlap with notehead ellipsoid should be smaller).
192         fudge = hround (blot_diameter
193                         * min (max (-0.15,
194                                     (0.8
195                                      - (20 / (design_size + 4))
196                                      + .1 linecount)),
197                                0.3));
198
199         draw_outside_ellipse (1.80, 0, 0.707, 0);
200         undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#);
201
202         set_char_box (stemthick# * linecount + gap# * (linecount - 1),
203                       width# + stemthick# * linecount + gap# * (linecount - 1),
204                       noteheight# / 2,
205                       noteheight# / 2);
206
207         define_pixels (gap);
208         pickup pencircle scaled stemthick;
209
210         % Breves of smaller design sizes should have their lines longer.
211         line_length := min (max (0.7, (64/60 - (design_size / 60))), 0.85);
212
213         % Line lengths between 0.72 and 0.77 are not nice
214         % because they are neither separate nor connected
215         % when there is an interval of fourth.
216         if line_length < 0.75:
217                 quanted_line_length := min (0.72, line_length);
218         else:
219                 quanted_line_length := max (0.77, line_length);
220         fi;
221
222         bot y1 = -quanted_line_length * staff_space;
223         top y2 = quanted_line_length * staff_space;
224         rt x1 - fudge = 0;
225         x1 = x2;
226
227         fudge + lft x3 = width;
228         x4 = x3;
229         y4 = y2;
230         y3 = y1;
231
232         for i := 0 step 1 until linecount - 1:
233                 line_distance := i * (gap + stemthick);
234                 draw_gridline (z1 - (line_distance, 0),
235                                z2 - (line_distance, 0),
236                                stemthick);
237                 draw_gridline (z3 + (line_distance, 0),
238                                z4 + (line_distance, 0),
239                                stemthick);
240         endfor;
241 enddef;
242
243
244 fet_beginchar ("Brevis notehead", "sM1");
245         draw_brevis (1, 1);
246
247         draw_staff (-2, 2, 0);
248 fet_endchar;
249
250
251 if test > 0:
252         fet_beginchar ("Brevis notehead", "sM1");
253                 draw_brevis(1, 1);
254
255                 draw_staff (-2, 2, 0.5);
256         fet_endchar;
257 fi;
258
259
260 fet_beginchar ("Double-lined brevis notehead", "sM1double");
261         draw_brevis (2, 0.8);
262
263         draw_staff (-2, 2, 0);
264 fet_endchar;
265
266
267 if test > 0:
268         fet_beginchar ("Double-lined brevis notehead", "sM1double");
269                 draw_brevis (2, 0.8);
270
271                 draw_staff (-2, 2, 0.5);
272         fet_endchar;
273 fi;
274
275
276 fet_beginchar ("Whole notehead", "s0");
277         draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0, 0.707, 0);
278         undraw_inside_ellipse (1.30, 125 - puff_up_factor * 10,
279                                0.68, 2 stafflinethickness#);
280
281         whole_notehead_width# := charwd;
282
283         draw_staff (-2, 2, 0);
284 fet_endchar;
285
286
287 if test > 0:
288         fet_beginchar ("Whole notehead", "s0");
289                 draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0,
290                                       0.707, 0);
291                 undraw_inside_ellipse (1.30, 125 - puff_up_factor * 10,
292                                        0.68, 2 stafflinethickness#);
293
294                 draw_staff (-2, 2, 0.5);
295         fet_endchar;
296 fi;
297
298
299 fet_beginchar ("Half notehead", "s1");
300         draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17);
301         undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#);
302
303         half_notehead_width# := charwd;
304
305         draw_staff (-2, 2, 0);
306 fet_endchar;
307
308
309 if test > 0:
310         fet_beginchar ("Half notehead", "s1");
311                 draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34,
312                                       0.66, 0.17);
313                 undraw_inside_ellipse (3.25, 33, 0.81,
314                                        2.5 stafflinethickness#);
315
316                 draw_staff (-2, 2, 0.5);
317         fet_endchar;
318 fi;
319
320
321 fet_beginchar ("Quarter notehead", "s2");
322         draw_quarter_path;
323         draw_staff (-2, 2, 0);
324 fet_endchar;
325
326
327 if test > 0:
328         fet_beginchar ("Quarter notehead", "s2");
329                 draw_outside_ellipse (1.49 - puff_up_factor / 3.0, 31,
330                                       0.707, 0);
331
332                 draw_staff (-2, 2, 0.5);
333         fet_endchar;
334 fi;
335
336
337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338
339
340 fet_beginchar ("Whole diamondhead", "s0diamond");
341         draw_outside_ellipse (1.80, 0, 0.495, 0);
342         undraw_inside_ellipse (1.30, 125, 0.6,
343                                .4 staff_space# + stafflinethickness#);
344
345         draw_staff (-2, 2, 0);
346 fet_endchar;
347
348
349 if test > 0:
350         fet_beginchar ("Whole diamondhead", "s0diamond");
351                 draw_outside_ellipse (1.80, 0, 0.495, 0);
352                 undraw_inside_ellipse (1.30, 125, 0.6,
353                                        .4 staff_space# + stafflinethickness#);
354
355                 draw_staff (-2, 2, 0.5);
356         fet_endchar;
357 fi;
358
359
360 fet_beginchar ("Half diamondhead", "s1diamond");
361         draw_outside_ellipse (1.50, 34, 0.49, 0.17);
362         undraw_inside_ellipse (3.5, 33, 0.80,
363                                .3 staff_space# + 1.5 stafflinethickness#);
364
365         draw_staff (-2, 2, 0);
366 fet_endchar;
367
368
369 if test > 0:
370         fet_beginchar ("Half diamondhead", "s1diamond");
371                 draw_outside_ellipse (1.50, 34, 0.49, 0.17);
372                 undraw_inside_ellipse (3.5, 33, 0.80,
373                                        .3 staff_space#
374                                        + 1.5 stafflinethickness#);
375
376                 draw_staff (-2, 2, 0.5);
377         fet_endchar;
378 fi;
379
380
381 fet_beginchar ("Quarter diamondhead", "s2diamond");
382         draw_outside_ellipse (1.80, 35, 0.495, -0.25);
383
384         draw_staff (-2, 2, 0);
385 fet_endchar;
386
387
388 if test > 0:
389         fet_beginchar ("Quarter diamondhead", "s2diamond");
390                 draw_outside_ellipse (1.80, 35, 0.495, -0.25);
391
392                 draw_staff (-2, 2, 0.5);
393         fet_endchar;
394 fi;
395
396
397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
398
399
400 vardef penposx@# (expr d) =
401 begingroup;
402         save pat;
403         path pat;
404
405         pat = top z@#
406               .. lft z@#
407               .. bot z@#
408               .. rt z@#
409               .. cycle;
410         z@#l = pat intersectionpoint (z@# -- infinity * dir (d + 180));
411         z@#r = pat intersectionpoint (z@# -- infinity * dir (d));
412 endgroup
413 enddef;
414
415
416 %
417 % UGH: xs not declared as argument.
418 %
419 def define_triangle_shape (expr stemdir) =
420         save triangle_a, triangle_b, triangle_c;
421         save triangle_out_a, triangle_out_b, triangle_out_c;
422         save triangle_in, triangle_out;
423         save width, depth, height;
424         save origin, left_up_dir;
425         save exact_left_point, exact_right_point, exact_down_point;
426
427         path triangle_a, triangle_b, triangle_c;
428         path triangle_out_a, triangle_out_b, triangle_out_c;
429         path triangle_in, triangle_out;
430         pair origin, left_up_dir;
431         pair exact_down_point, exact_left_point, exact_right_point;
432
433         save pen_thick;
434         pen_thick# = stafflinethickness# + .1 staff_space#;
435         define_pixels (llap);
436         define_blacker_pixels (pen_thick);
437
438         left_up_dir = llap# * dir (90 + tilt);
439
440         xpart (left_up_dir) * xs - (pen_thick# * xs) / 2 + xpart origin = 0;
441         ypart origin = 0;
442
443         exact_left_point := origin + (left_up_dir xscaled xs);
444         exact_down_point := origin + (left_up_dir rotated 120 xscaled xs);
445         exact_right_point := origin + (left_up_dir rotated 240 xscaled xs);
446
447         height# = ypart (exact_left_point + origin) + pen_thick# / 2;
448         depth# = -ypart (exact_down_point + origin) + pen_thick# / 2;
449         width# = xpart (exact_right_point - exact_left_point)
450                  + pen_thick# * xs;
451
452         set_char_box (0, width#, depth#, height#);
453
454         % Formerly, the shape has simply been drawn with an elliptical pen
455         % (`scaled pen_thick xscaled xs'), but the envelope of such a curve
456         % is of 6th degree.  For the sake of mf2pt1, we approximate it.
457
458         pickup pencircle scaled pen_thick xscaled xs;
459
460         z0 = (hround_pixels (xpart origin), 0);
461
462         z1 = z1' = z0 + llap * dir (90 + tilt) xscaled xs;
463         z2 = z2' = z0 + llap * dir (90 + tilt + 120) xscaled xs;
464         z3 = z3' = z0 + llap * dir (90 + tilt + 240) xscaled xs;
465
466         z12 = caveness [.5[z1, z2], z3];
467         z23 = caveness [.5[z2, z3], z1];
468         z31 = caveness [.5[z3, z1], z2];
469
470         triangle_a = z1 .. z12 .. z2;
471         triangle_b = z2 .. z23 .. z3;
472         triangle_c = z3 .. z31 .. z1;
473
474         penposx1 (angle (direction 0 of triangle_a) - 90);
475         penposx2 (angle (direction 0 of triangle_b) - 90);
476         penposx3 (angle (direction 0 of triangle_c) - 90);
477
478         penposx1' (angle (direction infinity of triangle_c) + 90);
479         penposx2' (angle (direction infinity of triangle_a) + 90);
480         penposx3' (angle (direction infinity of triangle_b) + 90);
481
482         penposx12 (angle (z12 - z0));
483         penposx23 (angle (z23 - z0));
484         penposx31 (angle (z31 - z0));
485
486         z10 = (z0 -- z1) intersectionpoint (z1l .. z12l .. z2'r);
487         z20 = (z0 -- z2) intersectionpoint (z2l .. z23l .. z3'r);
488         z30 = (z0 -- z3) intersectionpoint (z3l .. z31l .. z1'r);
489
490         triangle_in = z10
491                       .. z12l
492                       .. z20
493                       & z20
494                       .. z23l
495                       .. z30
496                       & z30
497                       .. z31l
498                       .. z10
499                       & cycle;
500
501         triangle_out_a = z1r .. z12r .. z2'l;
502         triangle_out_b = z2r .. z23r .. z3'l;
503         triangle_out_c = z3r .. z31r .. z1'l;
504
505         triangle_out = top z1
506                        .. lft z1
507                        .. z1r{direction 0 of triangle_out_a}
508                        & triangle_out_a
509                        & {direction infinity of triangle_out_a}z2'l
510                        .. lft z2
511                        .. bot z2
512                        .. z2r{direction 0 of triangle_out_b}
513                        & triangle_out_b
514                        & {direction infinity of triangle_out_b}z3'l
515                        .. rt z3
516                        .. top z3
517                        .. z3r{direction 0 of triangle_out_c}
518                        & triangle_out_c
519                        & {direction infinity of triangle_out_c}z1'l
520                        .. cycle;
521
522         labels (0, 10, 20, 30);
523         penlabels (1, 1', 2, 2', 3, 3', 12, 23, 31);
524
525         % attachment Y
526         if stemdir = 1:
527                 charwy := ypart exact_right_point;
528                 charwx := xpart exact_right_point + .5 pen_thick# * xs;
529         else:
530                 charwy := -ypart exact_down_point;
531                 charwx := width# - (xpart exact_down_point - .5 pen_thick# * xs);
532         fi
533 enddef;
534
535
536 def draw_whole_triangle_head =
537         save hei, xs;
538         save llap;
539         save tilt;
540
541         tilt = 40;
542         llap# = 3/4 noteheight#;
543
544         xs = 1.5;
545         caveness := 0.1;
546         define_triangle_shape (1);
547         fill triangle_out;
548         unfill triangle_in;
549 enddef;
550
551
552 fet_beginchar ("Whole trianglehead", "s0triangle");
553         draw_whole_triangle_head;
554
555         draw_staff (-2, 2, 0);
556 fet_endchar;
557
558
559 if test > 0:
560         fet_beginchar ("Whole trianglehead", "s0triangle");
561                 draw_whole_triangle_head;
562
563                 draw_staff (-2, 2, 0.5);
564         fet_endchar;
565 fi;
566
567
568 def draw_small_triangle_head (expr dir) =
569         save hei, xs;
570         save llap;
571         save tilt;
572
573         tilt = 40;
574         llap# = 2/3 noteheight#;
575         xs = 1.2;
576         caveness := 0.1;
577         define_triangle_shape (dir);
578
579         pickup feta_fillpen;
580
581         filldraw triangle_out;
582         unfilldraw triangle_in;
583 enddef;
584
585
586 fet_beginchar ("Half trianglehead (downstem)", "d1triangle");
587         draw_small_triangle_head (-1);
588
589         draw_staff (-2, 2, 0);
590 fet_endchar;
591
592
593 fet_beginchar ("Half trianglehead (upstem)", "u1triangle");
594         draw_small_triangle_head (1);
595
596         draw_staff (-2, 2, 0.5);
597 fet_endchar;
598
599
600 def draw_closed_triangle_head (expr dir) =
601         save hei, xs;
602         save llap;
603         save tilt;
604
605         tilt = 40;
606         llap# = 2/3 noteheight#;
607         xs = 1.0;
608         caveness := 0.1;
609         define_triangle_shape (dir);
610         fill triangle_out;
611 enddef;
612
613
614 fet_beginchar ("Quarter trianglehead (upstem)", "u2triangle");
615         draw_closed_triangle_head (1);
616
617         draw_staff (-2, 2, 0);
618 fet_endchar;
619
620
621 fet_beginchar ("Quarter trianglehead (downstem)", "d2triangle");
622         draw_closed_triangle_head (-1);
623
624         draw_staff (-2, 2, 0.5);
625 fet_endchar;
626
627
628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 %
630 % Slash heads are for indicating improvisation.  They are
631 % twice as high as normal heads.
632 %
633 def draw_slash (expr hwid_hash) =
634         save exact_height;
635         save ne, nw_dist;
636         pair ne, nw_dist;
637         exact_height = staff_space# + stafflinethickness# / 2;
638
639         set_char_box (0, 2 exact_height / slash_slope + hwid_hash,
640                       exact_height, exact_height);
641
642         charwx := charwd;
643         charwy := charht;
644
645         clearxy;
646
647         d := d - feta_shift;
648
649         pickup pencircle scaled blot_diameter;
650
651         bot y1 = -d;
652         top y2 = h;
653         lft x1 = 0;
654         lft x2 = 2 h / slash_slope;
655
656         rt x3 = w;
657         y3 = y2;
658         y4 = y1;
659         x3 - x2 = x4 - x1;
660
661         ne = unitvector (z3 - z4);
662         nw_dist = (ne rotated 90) * 0.5 blot_diameter;
663
664         fill bot z1{left}
665              .. (z1 + nw_dist){ne}
666              -- (z2 + nw_dist){ne}
667              .. top z2{right}
668              -- top z3{right}
669              .. (z3 - nw_dist){-ne}
670              -- (z4 - nw_dist){-ne}
671              .. bot z4{left}
672              -- cycle;
673
674         if hwid_hash > 2 slash_thick#:
675                 save th;
676
677                 th = slash_thick - blot_diameter;
678                 y6 = y7;
679                 y5 = y8;
680                 y3 - y7 = th;
681                 y5 - y1 = th;
682                 z6 - z5 = whatever * ne;
683                 z8 - z7 = whatever * ne;
684
685                 z5 = z1 + whatever * ne + th * (ne rotated -90);
686                 z8 = z4 + whatever * ne + th * (ne rotated 90);
687
688                 unfill z5
689                        -- z6
690                        -- z7
691                        -- z8
692                        -- cycle;
693         fi
694         labels (range 1 thru 10);
695 enddef;
696
697
698 fet_beginchar ("Whole slashhead", "s0slash");
699         draw_slash (4 slash_thick# + 0.5 staff_space#);
700
701         draw_staff (-2, 2, 0);
702 fet_endchar;
703
704
705 fet_beginchar ("Half slashhead", "s1slash");
706         draw_slash (3.0 slash_thick# + 0.15 staff_space#);
707
708         draw_staff (-2, 2, 0);
709 fet_endchar;
710
711
712 fet_beginchar ("Quarter slashhead", "s2slash");
713         draw_slash (1.5 slash_thick#);
714
715         draw_staff (-2, 2, 0);
716 fet_endchar;
717
718
719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
720 %
721 % `thick' is the distance between the NE/SW parallel lines in the cross
722 % (distance between centres of lines) in multiples of stafflinethickness
723 %
724 def draw_cross (expr thick) =
725         save ne, nw;
726         save ne_dist, nw_dist, rt_dist, up_dist;
727         save crz_in, crz_out;
728         save thickness;
729         pair ne, nw;
730         pair ne_dist, nw_dist, rt_dist, up_dist;
731         path crz_in, crz_out;
732
733         pen_thick# := 1.2 stafflinethickness#;
734         thickness# := thick * stafflinethickness#;
735         define_pixels (thickness);
736         define_blacker_pixels (pen_thick);
737
738         pickup pencircle scaled pen_thick;
739
740         h := h - feta_shift;
741
742         top y3 = h;
743         ne = unitvector ((1, (2 h - pen_thick) / (w - pen_thick)));
744         rt x4 = w / 2;
745         y5 = 0;
746         z4 - z5 = whatever * ne;
747         x6 = 0;
748         z6 - z3 = whatever * ne;
749         z3 - z4 = whatever * (ne yscaled -1);
750
751         z4 - z3 = whatever * (ne) + (ne rotated -90) * thickness;
752
753
754         x1 = charwd / 2 - .5 pen_thick#;
755         z1 = whatever * ne
756              + thick / 2 * stafflinethickness# * (ne rotated -90);
757
758         % labels (1, 2, 3, 4, 5, 6);
759
760         nw = unitvector (z3 - z4);
761
762         up_dist = up * 0.5 pen_thick / cosd (angle (ne));
763         rt_dist = right * 0.5 pen_thick / sind (angle (ne));
764         nw_dist = (ne rotated 90) * 0.5 pen_thick;
765         ne_dist = (nw rotated -90) * 0.5 pen_thick;
766
767         x4' := x4;
768         x5' := x5;
769         y6' := y6;
770
771         x4 := hround (x4' + .5 pen_thick) - .5 pen_thick;
772         x5 := hfloor (x5' + xpart rt_dist) - xpart rt_dist;
773         y6 := vfloor (y6' + ypart up_dist) - ypart up_dist;
774
775         crz_out = (z6 + up_dist)
776                   -- (z3 + nw_dist){ne}
777                   .. (top z3)
778                   .. (z3 + ne_dist){-nw}
779                   -- (z4 + ne_dist){-nw}
780                   .. (rt z4)
781                   .. (z4 - nw_dist){-ne}
782                   -- (z5 + rt_dist);
783         crz_out := crz_out shifted (0, feta_shift)
784                    -- reverse crz_out yscaled -1 shifted (0, -feta_eps);
785         fill crz_out
786              -- reverse crz_out xscaled -1 shifted (-feta_eps, 0)
787              -- cycle;
788
789         if (thick > 1):
790                 x4 := hround (x4' - xpart rt_dist) + xpart rt_dist;
791                 x5 := hceiling (x5' - .5 pen_thick) + .5 pen_thick;
792                 y6 := vfloor (y6' - .5 pen_thick) + .5 pen_thick;
793
794                 crz_in = (bot z6){right}
795                          .. (z6 - nw_dist){ne}
796                          -- (z3 - up_dist)
797                          -- (z4 - rt_dist)
798                          -- (z5 + nw_dist){-ne}
799                          .. {down}(lft z5);
800                 crz_in := crz_in shifted (0, feta_shift)
801                           -- reverse crz_in yscaled -1 shifted (0, -feta_eps);
802                 unfill crz_in
803                        -- reverse crz_in xscaled -1 shifted (-feta_eps, 0)
804                        -- cycle;
805         fi
806
807         % ugh
808         currentpicture := currentpicture shifted (hround (w / 2), 0);
809
810         charwx := charwd;
811         charwy := y1 + feta_shift;
812
813         z12 = (charwx * hppp, y1 * vppp);
814
815         labels (12);
816 enddef;
817
818
819 fet_beginchar ("Whole Crossed notehead", "s0cross");
820         save wid, hei;
821
822         wid# := black_notehead_width# + 4 stafflinethickness#;
823         hei# := noteheight# + stafflinethickness#;
824
825         set_char_box (0, wid#, hei# / 2, hei# / 2);
826
827         draw_cross (3.75);
828
829         remember_pic := currentpicture;
830
831         draw_staff (-2, 2, 0);
832 fet_endchar;
833
834
835 if test > 0:
836         fet_beginchar ("Whole Crossed notehead", "s0cross");
837                 save wid, hei;
838
839                 wid# := black_notehead_width# + 4 stafflinethickness#;
840                 hei# := noteheight# + stafflinethickness#;
841
842                 set_char_box (0, wid#, hei# / 2, hei# / 2);
843
844                 currentpicture := remember_pic;
845
846                 draw_staff (-2, 2, 0.5);
847         fet_endchar;
848 fi;
849
850
851 fet_beginchar ("Half Crossed notehead", "s1cross");
852         save wid, hei;
853
854         wid# := black_notehead_width# + 2 stafflinethickness#;
855         hei# := noteheight# + stafflinethickness# / 2;
856
857         set_char_box (0, wid#, hei# / 2, hei# / 2);
858
859         draw_cross (3.0);
860
861         remember_pic := currentpicture;
862
863         draw_staff (-2, 2, 0);
864 fet_endchar;
865
866
867 if test > 0:
868         fet_beginchar ("Half Crossed notehead", "s1cross");
869                 save wid, hei;
870
871                 wid# := black_notehead_width# + 2 stafflinethickness#;
872                 hei# := noteheight# + stafflinethickness# / 2;
873
874                 set_char_box (0, wid#, hei# / 2, hei# / 2);
875
876                 currentpicture := remember_pic;
877
878                 draw_staff (-2, 2, 0.5);
879         fet_endchar;
880 fi;
881
882
883 fet_beginchar ("Crossed notehead", "s2cross");
884         wid# := black_notehead_width#;
885         hei# := noteheight#;
886         set_char_box (0, wid#, hei# / 2, hei# / 2);
887
888         draw_cross (1.0);
889
890         remember_pic := currentpicture;
891
892         draw_staff (-2, 2, 0);
893 fet_endchar;
894
895
896 if test > 0:
897         fet_beginchar ("Crossed notehead", "s2cross");
898                 wid# := black_notehead_width#;
899                 hei# := noteheight#;
900                 set_char_box (0, wid#, hei# / 2, hei# / 2);
901
902                 currentpicture := remember_pic;
903
904                 draw_staff (-2, 2, 0.5);
905         fet_endchar;
906 fi;
907
908
909 fet_beginchar ("X-Circled notehead", "s2xcircle");
910         save wid, hei;
911         save cthick, cxd, cyd, dy;
912
913         wid# := black_notehead_width# * sqrt (sqrt2);
914         hei# := noteheight# * sqrt (sqrt2);
915
916         set_char_box (0, wid#, hei# / 2, hei# / 2);
917
918         d := d - feta_space_shift;
919
920         cthick# := (1.2 + 1/4) * stafflinethickness#;
921         define_blacker_pixels (cthick);
922
923         cxd := w - cthick;
924         cyd := h + d - cthick / 2;
925
926         dy = .5 (h - d);
927
928         pickup pencircle scaled cthick;
929
930         fill fullcircle xscaled (cxd + cthick)
931                         yscaled (cyd + cthick)
932                         shifted (w / 2, dy);
933         unfill fullcircle xscaled (cxd - cthick)
934                           yscaled (cyd - cthick)
935                           shifted (w / 2, dy);
936
937         xpos := .5 cxd / sqrt2;
938         ypos := .5 cyd / sqrt2;
939
940         pickup penrazor scaled cthick rotated (angle (xpos, ypos) + 90);
941         draw (-xpos + w / 2, -ypos + dy)
942              -- (xpos + w / 2, ypos + dy);
943
944         pickup penrazor scaled cthick rotated (angle (xpos, -ypos) + 90);
945         draw (-xpos + w / 2, ypos + dy)
946              -- (xpos + w / 2, -ypos + dy);
947
948         charwx := charwd;
949         charwy := 0;
950
951         z12 = (charwx * hppp, charwy * vppp);
952         labels (12);
953
954         remember_pic := currentpicture;
955
956         draw_staff (-2, 2, 0);
957 fet_endchar;
958
959
960 if test > 0:
961         fet_beginchar ("X-Circled notehead", "s2xcircle");
962                 save wid, hei;
963                 save cthick, cxr, cyr;
964
965                 wid# := black_notehead_width# * sqrt (sqrt2);
966                 hei# := noteheight# * sqrt (sqrt2);
967
968                 set_char_box (0, wid#, hei# / 2, hei# / 2);
969
970                 currentpicture := remember_pic;
971
972                 draw_staff (-2, 2, 0.5);
973         fet_endchar;
974 fi;
975
976
977 %%%%%%%%
978 %
979 % SOLFA SHAPED NOTES
980 %
981 %
982 % Note: For whole and half notes, the `fill' curve (p_out) is offset from
983 %       the points that specify the outer geometry, because we need to add
984 %       the rounding.  In contrast, the inner curve is not offset, because
985 %       there is no rounding.
986 %
987 %       This means that to get a line of thick_factor * pen_thickness,
988 %       we need to offset the inner curve by
989 %
990 %         (thick_factor - 0.5) * pen_thickness
991 %
992 %       or by
993 %
994 %         (2 * thick_factor - 1) * half_pen_thickness
995 %
996 save solfa_pen_thick;
997 solfa_pen_thick# = 1.3 stafflinethickness#;
998 define_blacker_pixels (solfa_pen_thick);
999
1000 save solfa_pen_radius;
1001 solfa_pen_radius = 0.5 solfa_pen_thick;
1002
1003 save solfa_base_notewidth;
1004 solfa_base_notewidth# := black_notehead_width#;
1005
1006 solfa_whole_width := 1.0;
1007 solfa_half_width := 1.0;
1008 solfa_quarter_width := 1.0;
1009
1010
1011 %%% Do head
1012 %
1013 % Triangle with base parallel to staff lines.
1014 %
1015
1016 def draw_do_head (expr width_factor, dir, thickness_factor) =
1017         save p_in, p_out;
1018         save left_dist, right_dist, bottom_dist;
1019         path p_in, p_out;
1020         pair left_dist, right_dist, bottom_dist;
1021
1022         set_char_box (0, width_factor * solfa_base_notewidth#,
1023                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
1024
1025         bottom_thick_factor := 2 * thickness_factor - 1;
1026         % no different thickness for left side if we want uniform thickness
1027         if thickness_factor = 1:
1028                 left_thick_factor := 1;
1029         else:
1030                 left_thick_factor := 0.7 * bottom_thick_factor;
1031         fi
1032
1033         save pen_radius;
1034         pen_radius := min (solfa_pen_radius,
1035                            (h + d) / (3 * (1 + bottom_thick_factor)));
1036
1037         pickup pencircle scaled (2 * pen_radius);
1038
1039         bot y1 = -d;
1040         y1 = y2;
1041         lft x1 = 0;
1042         rt x2 = w;
1043         top y3 = h;
1044         x3 = .5 [x1, x2];
1045
1046         left_dist = (unitvector (z3 - z1) rotated 90) * pen_radius;
1047         right_dist = (unitvector (z2 - z3) rotated 90) * pen_radius;
1048         bottom_dist = (0,1) * pen_radius;
1049
1050         save pa, pb, pc;
1051         path pa, pb, pc;
1052         save point_a, point_b, point_c;
1053         pair point_a, point_b, point_c;
1054
1055         pa := (z1 - left_thick_factor * left_dist)
1056               -- (z3 - left_thick_factor * left_dist);
1057         pb := (z1 + bottom_thick_factor * bottom_dist)
1058               -- (z2 + bottom_thick_factor * bottom_dist);
1059         pc := (z2 - right_dist)
1060               -- (z3 - right_dist);
1061
1062         point_a := pa intersectionpoint pb;
1063         point_b := pb intersectionpoint pc;
1064         point_c := pc intersectionpoint pa;
1065
1066         p_in := point_a
1067                 -- point_b
1068                 -- point_c
1069                 -- cycle;
1070
1071         p_out := bot z1
1072                  -- bot z2{right}
1073                  .. rt z2{up}
1074                  .. (z2 + right_dist){z3 - z2}
1075                  -- (z3 + right_dist){z3 - z2}
1076                  .. top z3{left}
1077                  .. (z3 + left_dist){z1 - z3}
1078                  -- (z1 + left_dist){z1 - z3}
1079                  .. lft z1{down}
1080                  .. {right}cycle;
1081
1082         labels (1, 2, 3);
1083
1084         charwx := charwd;
1085         charwy := -chardp + 0.5 stafflinethickness#;
1086         if dir = -1:
1087                 charwy := -charwy;
1088         fi;
1089 enddef;
1090
1091 save do_weight;
1092 do_weight := 2;
1093
1094
1095 fet_beginchar ("Whole dohead", "s0do");
1096         draw_do_head (solfa_whole_width, 1, do_weight);
1097         fill p_out;
1098         unfill p_in;
1099 fet_endchar;
1100
1101
1102 fet_beginchar ("Half dohead", "d1do");
1103         draw_do_head (solfa_half_width, -1, do_weight);
1104         fill p_out;
1105         unfill p_in;
1106 fet_endchar;
1107
1108
1109 fet_beginchar ("Half dohead", "u1do");
1110         draw_do_head (solfa_half_width, 1, do_weight);
1111         fill p_out;
1112         unfill p_in;
1113 fet_endchar;
1114
1115
1116 fet_beginchar ("Quarter dohead", "d2do");
1117         draw_do_head (solfa_quarter_width, -1, do_weight);
1118         fill p_out;
1119 fet_endchar;
1120
1121
1122 fet_beginchar ("Quarter dohead", "u2do");
1123         draw_do_head (solfa_quarter_width, 1, do_weight);
1124         fill p_out;
1125 fet_endchar;
1126
1127
1128 fet_beginchar ("Whole thin dohead", "s0doThin");
1129         draw_do_head (solfa_whole_width, 1, 1);
1130         fill p_out;
1131         unfill p_in;
1132 fet_endchar;
1133
1134
1135 fet_beginchar ("Half thin dohead", "d1doThin");
1136         draw_do_head (solfa_half_width, -1, 1);
1137         fill p_out;
1138         unfill p_in;
1139 fet_endchar;
1140
1141
1142 fet_beginchar ("Half thin dohead", "u1doThin");
1143         draw_do_head (solfa_half_width, 1, 1);
1144         fill p_out;
1145         unfill p_in;
1146 fet_endchar;
1147
1148
1149 fet_beginchar ("Quarter thin dohead", "d2doThin");
1150         draw_do_head (solfa_quarter_width, -1, 1);
1151         fill p_out;
1152 fet_endchar;
1153
1154
1155 fet_beginchar ("Quarter thin dohead", "u2doThin");
1156         draw_do_head (solfa_quarter_width, 1, 1);
1157         fill p_out;
1158 fet_endchar;
1159
1160
1161 %
1162 % re - flat top, curved bottom:
1163 %
1164 %   (0,h/2) {dir -90}
1165 %   .. (w/2,-h/2)
1166 %   .. {dir 90} (w,h/2)
1167 %   -- cycle;
1168 %
1169 % (broader along the base and with more vertical sides for half and
1170 % whole notes)
1171 %
1172 % Note: According to some shape-note singers, there should be no size
1173 %       differences for half and whole notes, contrary to the comment above.
1174 %       Consequently, we have made them all the same width.
1175 %
1176 % stem attachment: h/2
1177 %
1178 def draw_re_head (expr width_factor, dir, thickness_factor) =
1179         save p_in, p_out;
1180         path p_in, p_out;
1181
1182         set_char_box (0, width_factor * solfa_base_notewidth#,
1183                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
1184
1185         save offset;
1186         offset = (2 * thickness_factor - 1);
1187
1188         save curve_start;
1189         curve_start = 0.7;
1190
1191         save pen_radius;
1192
1193         pen_radius := min (solfa_pen_radius,
1194                            (h + d) * (1-curve_start) / (1+ offset));
1195
1196         pickup pencircle scaled (2 * pen_radius);
1197
1198         lft x1 = 0;
1199         top y1 = h;
1200         x2 = x1;
1201         y2 = curve_start [y3, y1];
1202         bot y3 = -d;
1203         x3 = .5 [x2, x4];
1204         rt x4 = w;
1205         y4 = y2;
1206         y5 = y1;
1207         x5 = x4;
1208
1209         labels (range 1 thru 5);
1210
1211         p_in := (z1 + pen_radius * (1, -1 * offset))
1212                 -- rt z2{down}
1213                 .. ((top z3) + (0, offset * pen_radius))
1214                 .. lft z4{up}
1215                 -- (z5 + pen_radius * (-1, -1 * offset))
1216                 -- cycle;
1217
1218         p_out := lft z1
1219                  -- lft z2{down}
1220                  .. bot z3
1221                  .. rt z4{up}
1222                  -- rt z5{up}
1223                  .. top z5{left}
1224                  -- top z1{left}
1225                  .. {down}cycle;
1226
1227         charwx := charwd;
1228         charwy := curve_start [-chardp, charht];
1229
1230         if dir = -1:
1231                 charwy := -charwy;
1232         fi;
1233 enddef;
1234
1235
1236 save re_weight;
1237 re_weight := 2;
1238
1239 fet_beginchar ("Whole rehead", "s0re");
1240         draw_re_head (solfa_whole_width, 1, re_weight);
1241         fill p_out;
1242         unfill p_in;
1243 fet_endchar;
1244
1245
1246 fet_beginchar ("Half up rehead", "u1re");
1247         draw_re_head (solfa_half_width, 1, re_weight);
1248         fill p_out;
1249         unfill p_in;
1250 fet_endchar;
1251
1252
1253 fet_beginchar ("Half down rehead", "d1re");
1254         draw_re_head (solfa_half_width, -1, re_weight);
1255         fill p_out;
1256         unfill p_in;
1257 fet_endchar;
1258
1259
1260 fet_beginchar ("Quarter up rehead", "u2re");
1261         draw_re_head (solfa_quarter_width, 1, re_weight);
1262         fill p_out;
1263 fet_endchar;
1264
1265
1266 fet_beginchar ("Quarter down rehead", "d2re");
1267         draw_re_head (solfa_quarter_width, -1, re_weight);
1268         fill p_out;
1269 fet_endchar;
1270
1271
1272 fet_beginchar ("Whole thin rehead", "s0reThin");
1273         draw_re_head (solfa_whole_width, 1, 1);
1274         fill p_out;
1275         unfill p_in;
1276 fet_endchar;
1277
1278
1279 fet_beginchar ("Half up thin rehead", "u1reThin");
1280         draw_re_head (solfa_half_width, 1, 1);
1281         fill p_out;
1282         unfill p_in;
1283 fet_endchar;
1284
1285
1286 fet_beginchar ("Half down thin rehead", "d1reThin");
1287         draw_re_head (solfa_half_width, -1, 1);
1288         fill p_out;
1289         unfill p_in;
1290 fet_endchar;
1291
1292
1293 fet_beginchar ("Quarter thin rehead", "u2reThin");
1294         draw_re_head (solfa_quarter_width, 1, 1);
1295         fill p_out;
1296 fet_endchar;
1297
1298
1299 fet_beginchar ("Quarter thin rehead", "d2reThin");
1300         draw_re_head (solfa_quarter_width, -1, 1);
1301         fill p_out;
1302 fet_endchar;
1303
1304
1305 %%%% mi head -- diamond shape
1306 %
1307 % two versions, depending on whether the `strong' lines are on the nw & se
1308 % or the ne & sw
1309 %
1310 def draw_mi_head (expr width_factor, thickness_factor, mirror) =
1311         save path_out, path_in;
1312         save ne_dist, se_dist, ne, se;
1313         save path_a, path_b, path_c, path_d;
1314         path path_out, path_in;
1315         pair ne_dist, se_dist, ne, se;
1316         path path_a, path_b, path_c, path_d;
1317         save inner_path;
1318         path inner_path;
1319
1320         set_char_box (0, width_factor * solfa_base_notewidth#,
1321                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
1322
1323         save offset;
1324         offset := 2 * thickness_factor - 1;
1325
1326         save note_diagonal;
1327
1328         note_diagonal := w / 2 ++ (h + d) / 2;
1329
1330         save pen_radius;
1331
1332         pen_radius := min (solfa_pen_radius,
1333                            .3 * note_diagonal / (1 + offset));
1334
1335         pickup pencircle scaled (2 * pen_radius);
1336
1337         lft x1 = 0;
1338         y1 = 0;
1339         bot y2 = -d;
1340         x2 = .5 [x1, x3];
1341         rt x3 = w;
1342         x4 = x2;
1343         y3 = y1;
1344         top y4 = h;
1345
1346         % inner sides are parallel to outer sides
1347         z6 - z5 = whatever * (z2 - z1);
1348         z8 - z7 = whatever * (z4 - z3);
1349         z8 - z5 = whatever * (z4 - z1);
1350         z7 - z6 = whatever * (z3 - z2);
1351
1352         ne = unitvector (z4 - z1);
1353         se = unitvector (z2 - z1);
1354
1355         ne_dist = (ne rotated 90) * pen_radius;
1356         se_dist = (se rotated 90) * pen_radius;
1357
1358         path_a := (z1 + se_dist)
1359                   -- (z2 + se_dist);
1360         path_b := (z2 + (ne_dist * offset))
1361                   -- (z3 + (ne_dist * offset));
1362         path_c := (z3 - se_dist)
1363                   -- (z4 - se_dist);
1364         path_d := (z4 - (ne_dist * offset))
1365                   -- (z1 - (ne_dist * offset));
1366
1367         z5 = path_a intersectionpoint path_d;
1368         z7 = path_b intersectionpoint path_c;
1369
1370         labels (range 1 thru 8);
1371
1372         inner_path := z5
1373                       -- z6
1374                       -- z7
1375                       -- z8
1376                       -- cycle;
1377
1378         if mirror:
1379                 path_in := inner_path;
1380         else:
1381                 path_in := inner_path reflectedabout (z2, z4);
1382         fi
1383
1384         path_out := lft z1 {down}
1385                     .. (z1 - se_dist){se}
1386                     -- (z2 - se_dist){se}
1387                     .. bot z2 {right}
1388                     .. (z2 - ne_dist){ne}
1389                     -- (z3 - ne_dist){ne}
1390                     .. rt z3 {up}
1391                     .. (z3 + se_dist){-se}
1392                     -- (z4 + se_dist){-se}
1393                     .. top z4 {left}
1394                     .. (z4 + ne_dist){-ne}
1395                     -- (z1 + ne_dist){-ne}
1396                     .. cycle;
1397 enddef;
1398
1399
1400 save mi_weight, mi_width;
1401 mi_weight := 2;
1402 mi_width := 1.2;
1403
1404 fet_beginchar ("Whole mihead", "s0mi");
1405         draw_mi_head (mi_width * solfa_whole_width, mi_weight, false);
1406         fill path_out;
1407         unfill path_in;
1408 fet_endchar;
1409
1410
1411 fet_beginchar ("Half mihead", "s1mi");
1412         draw_mi_head (mi_width * solfa_quarter_width, mi_weight, false);
1413         fill path_out;
1414         unfill path_in;
1415 fet_endchar;
1416
1417
1418 fet_beginchar ("Quarter mihead", "s2mi");
1419         draw_mi_head (mi_width * solfa_quarter_width, mi_weight, false);
1420         fill path_out;
1421 fet_endchar;
1422
1423
1424 fet_beginchar ("Whole mirror mihead", "s0miMirror");
1425         draw_mi_head (mi_width * solfa_whole_width, mi_weight, true);
1426         fill path_out;
1427         unfill path_in;
1428 fet_endchar;
1429
1430
1431 fet_beginchar ("Half  mirror mihead", "s1miMirror");
1432         draw_mi_head (mi_width * solfa_quarter_width, mi_weight, true);
1433         fill path_out;
1434         unfill path_in;
1435 fet_endchar;
1436
1437
1438 fet_beginchar ("Quarter mirror mihead", "s2miMirror");
1439         draw_mi_head (mi_width * solfa_quarter_width, mi_weight, true);
1440         fill path_out;
1441 fet_endchar;
1442
1443
1444 fet_beginchar ("Whole thin mihead", "s0miThin");
1445         draw_mi_head (mi_width * solfa_whole_width, 1, false);
1446         fill path_out;
1447         unfill path_in;
1448 fet_endchar;
1449
1450
1451 fet_beginchar ("Half thin mihead", "s1miThin");
1452         draw_mi_head (mi_width * solfa_quarter_width, 1, false);
1453         fill path_out;
1454         unfill path_in;
1455 fet_endchar;
1456
1457
1458 fet_beginchar ("Quarter thin mihead", "s2miThin");
1459         draw_mi_head (mi_width * solfa_quarter_width, 1, false);
1460         fill path_out;
1461 fet_endchar;
1462
1463
1464 %%%% fa head
1465 %
1466 % Right triangle, hypotenuse from nw to se corner.  Stem attaches on
1467 % vertical side in direction of horizontal side.
1468 %
1469 def draw_fa_head (expr width_factor, thickness_factor) =
1470         set_char_box (0, width_factor * solfa_base_notewidth#,
1471                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
1472
1473         save p_down_in, p_down_out, p_up_in, p_up_out, nw_dist, nw;
1474         path p_down_in, p_down_out, p_up_in, p_up_out;
1475         save path_a, path_b, path_c;
1476         path path_a, path_b, path_c;
1477         pair nw_dist, nw;
1478
1479         save offset;
1480         offset := 2 * thickness_factor - 1;
1481
1482         save pen_radius;
1483         pen_radius := min (solfa_pen_radius,
1484                            .33 * (h + d) / (1 + offset));
1485
1486         pickup pencircle scaled (2 * pen_radius);
1487
1488         lft x1 = 0;
1489         top y1 = h;
1490
1491         rt x2 = w;
1492         y2 = y1;
1493         bot y3 = -d;
1494         x3 = x2;
1495
1496         y4 = y3;
1497         x4 = x1;
1498
1499         labels (1, 2, 3, 4);
1500
1501         nw = unitvector (z1 - z3);
1502         nw_dist = (nw rotated 90) * pen_radius;
1503
1504         path_a := (z1 - (0,1) * offset * pen_radius)
1505                   -- (z2 - (0,1) * offset * pen_radius);
1506         path_b := (z2 - (1,0) * pen_radius)
1507                   -- (z3 - (1,0) * pen_radius);
1508         path_c := (z3 - nw_dist)
1509                   -- (z1 - nw_dist);
1510
1511         p_up_in := (path_a intersectionpoint path_b)
1512                    -- (path_b intersectionpoint path_c)
1513                    -- (path_c intersectionpoint path_a)
1514                    -- cycle;
1515
1516         p_up_out := lft z1{down}
1517                     .. (z1 + nw_dist){-nw}
1518                     -- (z3 + nw_dist){-nw}
1519                     .. bot z3{right}
1520                     .. rt z3{up}
1521                     -- rt z2{up}
1522                     .. top z2{left}
1523                     -- top z1{left}
1524                     .. cycle;
1525
1526         p_down_in := p_up_in rotated 180 shifted (w, 0);
1527         p_down_out := p_up_out rotated 180 shifted (w, 0);
1528
1529         charwy := 0.0;
1530         charwx := charwd;
1531 enddef;
1532
1533 save fa_weight;
1534 fa_weight := 1.75;
1535
1536 fet_beginchar ("Whole fa up head", "u0fa");
1537         draw_fa_head (solfa_whole_width, fa_weight);
1538         fill p_up_out;
1539         unfill p_up_in;
1540 fet_endchar;
1541
1542
1543 fet_beginchar ("Whole fa down head", "d0fa");
1544         draw_fa_head (solfa_whole_width, fa_weight);
1545         fill p_down_out;
1546         unfill p_down_in;
1547 fet_endchar;
1548
1549
1550 fet_beginchar ("half fa up head", "u1fa");
1551         draw_fa_head (solfa_half_width, fa_weight);
1552         fill p_up_out;
1553         unfill p_up_in;
1554 fet_endchar;
1555
1556
1557 fet_beginchar ("Half fa down head", "d1fa");
1558         draw_fa_head (solfa_half_width, fa_weight);
1559         fill p_down_out;
1560         unfill p_down_in;
1561 fet_endchar;
1562
1563
1564 fet_beginchar ("Quarter fa up head", "u2fa");
1565         draw_fa_head (solfa_quarter_width, fa_weight);
1566         fill p_up_out;
1567 fet_endchar;
1568
1569
1570 fet_beginchar ("Quarter fa down head", "d2fa");
1571         draw_fa_head (solfa_quarter_width, fa_weight);
1572         fill p_down_out;
1573 fet_endchar;
1574
1575
1576 fet_beginchar ("Whole thin fa up head", "u0faThin");
1577         draw_fa_head (solfa_whole_width, 1);
1578         fill p_up_out;
1579         unfill p_up_in;
1580 fet_endchar;
1581
1582
1583 fet_beginchar ("Whole thin fa down head", "d0faThin");
1584         draw_fa_head (solfa_whole_width, 1);
1585         fill p_down_out;
1586         unfill p_down_in;
1587 fet_endchar;
1588
1589
1590 fet_beginchar ("half thin fa up head", "u1faThin");
1591         draw_fa_head (solfa_half_width, 1);
1592         fill p_up_out;
1593         unfill p_up_in;
1594 fet_endchar;
1595
1596
1597 fet_beginchar ("Half thin fa down head", "d1faThin");
1598         draw_fa_head (solfa_half_width, 1);
1599         fill p_down_out;
1600         unfill p_down_in;
1601 fet_endchar;
1602
1603
1604 fet_beginchar ("Quarter thin fa up head", "u2faThin");
1605         draw_fa_head (solfa_quarter_width, 1);
1606         fill p_up_out;
1607 fet_endchar;
1608
1609
1610 fet_beginchar ("Quarter thin fa down head", "d2faThin");
1611         draw_fa_head (solfa_quarter_width, 1);
1612         fill p_down_out;
1613 fet_endchar;
1614
1615
1616
1617 %%%% sol head
1618 %
1619 % Note: sol head is the same shape as a standard music head, and doesn't
1620 %       vary from style to style.  However, width is constant with duration,
1621 %       so we can't just use the standard note font.
1622 %
1623 def draw_sol_head (expr filled) =
1624         draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17);
1625         if not filled:
1626           undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#);
1627         fi
1628         draw_staff (-2, 2, 0);
1629 enddef;
1630
1631 fet_beginchar ("Whole solhead", "s0sol");
1632         draw_sol_head ( false);
1633 fet_endchar;
1634
1635
1636 fet_beginchar ("Half solhead", "s1sol");
1637         draw_sol_head ( false);
1638 fet_endchar;
1639
1640
1641 fet_beginchar ("Quarter solhead", "s2sol");
1642         draw_sol_head ( true);
1643 fet_endchar;
1644
1645
1646 %%%% la head
1647 %
1648 %   Rectangle head
1649 %
1650 def draw_la_head (expr width_factor, thickness_factor) =
1651         set_char_box (0, width_factor * solfa_base_notewidth#,
1652                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
1653         save p_in, p_out;
1654         path p_in, p_out;
1655
1656         save offset;
1657         offset := 2 * thickness_factor - 1;
1658
1659         save pen_radius;
1660         pen_radius := min (solfa_pen_radius,
1661                            .35 * (h + d) / (1 + offset));
1662
1663         pickup pencircle scaled (2 * pen_radius);
1664
1665         lft x1 = 0;
1666         top y1 = h;
1667
1668         rt x2 = w;
1669         y2 = y1;
1670         bot y3 = -d;
1671         x3 = x2;
1672
1673         y4 = y3;
1674         x4 = x1;
1675
1676         labels (range 1 thru 4);
1677
1678         p_in := (z1 + pen_radius * (1, -offset))
1679                 -- (z2 + pen_radius * (-1, -offset))
1680                 -- (z3 + pen_radius * (-1, offset))
1681                 -- (z4 + pen_radius * (1, offset))
1682                 -- cycle;
1683
1684         p_out := top z1
1685                  -- top z2{right}
1686                  .. rt z2{down}
1687                  -- rt z3{down}
1688                  .. bot z3{left}
1689                  -- bot z4{left}
1690                  .. lft z4{up}
1691                  -- lft z1{up}
1692                  .. cycle;
1693 enddef;
1694
1695
1696 save la_weight;
1697 la_weight := 2;
1698
1699 fet_beginchar ("Whole lahead", "s0la");
1700         draw_la_head (solfa_whole_width, la_weight);
1701         fill p_out;
1702         unfill p_in;
1703 fet_endchar;
1704
1705
1706 fet_beginchar ("Half lahead", "s1la");
1707         draw_la_head (solfa_half_width, la_weight);
1708         fill p_out;
1709         unfill p_in;
1710 fet_endchar;
1711
1712
1713 fet_beginchar ("Quarter lahead", "s2la");
1714         draw_la_head (solfa_quarter_width, la_weight);
1715         fill p_out;
1716 fet_endchar;
1717
1718
1719 fet_beginchar ("Whole thin lahead", "s0laThin");
1720         draw_la_head (solfa_whole_width, 1);
1721         fill p_out;
1722         unfill p_in;
1723 fet_endchar;
1724
1725
1726 fet_beginchar ("Half thin lahead", "s1laThin");
1727         draw_la_head (solfa_half_width, 1);
1728         fill p_out;
1729         unfill p_in;
1730 fet_endchar;
1731
1732
1733 fet_beginchar ("Quarter lahead", "s2laThin");
1734         draw_la_head (solfa_quarter_width, 1);
1735         fill p_out;
1736 fet_endchar;
1737
1738
1739 %%%% ti head
1740 %
1741 %   `Snow-cone', V with rounded top.
1742 %
1743 def draw_ti_head (expr width_factor, dir, thickness_factor) =
1744         set_char_box (0, width_factor * solfa_base_notewidth#,
1745                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
1746         save p_in, p_out, p_top, p_top_in;
1747         path p_in, p_out, p_top, p_top_in;
1748         save cone_height;
1749         cone_height = 0.64;
1750
1751         save offset;
1752         offset := 2 * thickness_factor - 1;
1753
1754         save pen_radius;
1755         pen_radius := min (solfa_pen_radius,
1756                            .4 * (h + d) / (1 + offset));
1757
1758         pickup pencircle scaled (2 * pen_radius);
1759
1760         x1 = .5 [x2, x4];
1761         bot y1 = -d;
1762         lft x2 = 0;
1763         y2 = cone_height [y1, y3];
1764         rt x4 = w;
1765         y4 = y2;
1766         x3 = x1;
1767         top y3 = h;
1768         x5 = x1;
1769         y5 = y1 + offset * pen_radius;
1770
1771         labels (range 1 thru 4);
1772
1773         save nw_dist, sw_dist, nw, sw;
1774         pair nw_dist, sw_dist, nw, sw;
1775
1776         nw = unitvector (z2 - z1);
1777         sw = unitvector (z1 - z4);
1778
1779         nw_dist = (nw rotated 90) * pen_radius;
1780         sw_dist = (sw rotated 90) * pen_radius;
1781
1782         p_top := (z2 + nw * pen_radius)
1783                  .. (top z3){right}
1784                  .. (z4 - sw * pen_radius);
1785
1786         p_top_in := (z2 - nw * offset * pen_radius)
1787                     .. (z3 - (0,1) * pen_radius) {right}
1788                     .. (z4 + sw * offset * pen_radius);
1789
1790         save path_a, path_b;
1791         path path_a, path_b;
1792         path_a := z2
1793                   -- z5;
1794         path_b := z5
1795                   -- z4;
1796
1797         z6 = path_a intersectionpoint p_top_in;
1798         z7 = path_b intersectionpoint p_top_in;
1799
1800         p_in := z5
1801                 -- z6
1802                 .. bot z3
1803                 .. z7
1804                 -- cycle;
1805
1806         p_out := bot z1
1807                  .. (z1 + nw_dist)
1808                  -- (z2 + nw_dist)
1809                  .. lft z2
1810                  .. (z2 + nw * pen_radius){direction 0 of p_top}
1811                  & p_top
1812                  & {direction infinity of p_top}(z4 - sw * pen_radius)
1813                  .. rt z4
1814                  .. (z4 + sw_dist)
1815                  -- (z1 + sw_dist)
1816                  .. cycle;
1817
1818         charwx := charwd;
1819         charwy := cone_height [-chardp, charht];
1820         if dir = -1:
1821                 charwy := -charwy;
1822         fi;
1823 enddef;
1824
1825
1826 save ti_weight;
1827 ti_weight := 2;
1828
1829 fet_beginchar ("Whole up tihead", "s0ti");
1830         draw_ti_head (solfa_whole_width, 1, ti_weight);
1831         fill p_out;
1832         unfill p_in;
1833 fet_endchar;
1834
1835
1836 fet_beginchar ("Half up tihead", "u1ti");
1837         draw_ti_head (solfa_half_width, 1, ti_weight);
1838         fill p_out;
1839         unfill p_in;
1840 fet_endchar;
1841
1842
1843 fet_beginchar ("Half down tihead", "d1ti");
1844         draw_ti_head (solfa_half_width, -1, ti_weight);
1845         fill p_out;
1846         unfill p_in;
1847 fet_endchar;
1848
1849
1850 fet_beginchar ("Quarter up tihead", "u2ti");
1851         draw_ti_head (solfa_quarter_width, 1, ti_weight);
1852         fill p_out;
1853 fet_endchar;
1854
1855
1856 fet_beginchar ("Quarter down tihead", "d2ti");
1857         draw_ti_head (solfa_quarter_width, -1, ti_weight);
1858         fill p_out;
1859 fet_endchar;
1860
1861
1862 fet_beginchar ("Whole thin up tihead", "s0tiThin");
1863         draw_ti_head (solfa_whole_width, 1, 1);
1864         fill p_out;
1865         unfill p_in;
1866 fet_endchar;
1867
1868
1869 fet_beginchar ("Half thin up tihead", "u1tiThin");
1870         draw_ti_head (solfa_half_width, 1, 1);
1871         fill p_out;
1872         unfill p_in;
1873 fet_endchar;
1874
1875
1876 fet_beginchar ("Half thin down tihead", "d1tiThin");
1877         draw_ti_head (solfa_half_width, -1, 1);
1878         fill p_out;
1879         unfill p_in;
1880 fet_endchar;
1881
1882
1883 fet_beginchar ("Quarter thin up tihead", "u2tiThin");
1884         draw_ti_head (solfa_quarter_width, 1, 1);
1885         fill p_out;
1886 fet_endchar;
1887
1888
1889 fet_beginchar ("Quarter thin down tihead", "d2tiThin");
1890         draw_ti_head (solfa_quarter_width, -1, 1);
1891         fill p_out;
1892 fet_endchar;
1893
1894
1895 %%%%%%   Funk shape note heads
1896 %
1897 %  Funk heads are narrower than Aiken and Sacred Harp, so we need a new
1898 %  width.
1899 %
1900 funk_notehead_width := 0.75;
1901
1902
1903 %%%%%%   Funk do head
1904 %          Parabolic on one side, vertical line on other
1905 %          Has up and down shapes for *all* notes
1906 %
1907 def draw_Funk_do_head (expr width_factor, thickness_factor) =
1908         set_char_box (0, width_factor * solfa_base_notewidth#,
1909                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
1910
1911         save offset;
1912         offset := 2 * thickness_factor - 1;
1913
1914         save pen_radius;
1915         pen_radius := min (solfa_pen_radius,
1916                            .3 * (h + d) / (1 + offset));
1917
1918         pickup pencircle scaled (2 * pen_radius);
1919
1920         rt x1 = w;
1921         bot y1 = -d;
1922
1923         lft x2 = 0;
1924         y2 = 0.5 [y1, y3];
1925
1926         x3 = x1;
1927         top y3 = h;
1928
1929         x4 = x1 - pen_radius;
1930         y4 = y1 + offset * pen_radius;
1931
1932         y5 = y2;
1933         x5 = x2 + pen_radius;
1934
1935         x6 = x4;
1936         y6 = y3 - offset * pen_radius;
1937
1938         save p_up_in, p_up_out, p_down_in, p_down_out;
1939         path p_up_in, p_up_out, p_down_in, p_down_out;
1940
1941         p_down_in := z4{left}
1942                      ... z5{up}
1943                      ... z6{right}
1944                      -- cycle;
1945
1946         p_down_out := bot z1{left}
1947                       .. lft z2{up}
1948                       .. top z3{right}
1949                       .. rt z3{down}
1950                       -- rt z1{down}
1951                       .. cycle;
1952
1953         p_up_in := p_down_in rotated 180 shifted (w,0);
1954         p_up_out := p_down_out rotated 180 shifted (w,0);
1955
1956 enddef;
1957
1958
1959 save funk_do_weight;
1960 funk_do_weight := 1.7;
1961
1962 fet_beginchar ("Whole up Funk dohead", "u0doFunk");
1963         draw_Funk_do_head (funk_notehead_width, funk_do_weight);
1964         fill p_up_out;
1965         unfill p_up_in;
1966 fet_endchar;
1967
1968
1969 fet_beginchar ("Whole down Funk dohead", "d0doFunk");
1970         draw_Funk_do_head (funk_notehead_width, funk_do_weight);
1971         fill p_down_out;
1972         unfill p_down_in;
1973 fet_endchar;
1974
1975
1976 fet_beginchar ("Half up Funk dohead", "u1doFunk");
1977         draw_Funk_do_head (funk_notehead_width, funk_do_weight);
1978         fill p_up_out;
1979         unfill p_up_in;
1980 fet_endchar;
1981
1982
1983 fet_beginchar ("Half down Funk dohead", "d1doFunk");
1984         draw_Funk_do_head (funk_notehead_width, funk_do_weight);
1985         fill p_down_out;
1986         unfill p_down_in;
1987 fet_endchar;
1988
1989
1990 fet_beginchar ("Quarter up Funk dohead", "u2doFunk");
1991         draw_Funk_do_head (funk_notehead_width, funk_do_weight);
1992         fill p_up_out;
1993 fet_endchar;
1994
1995
1996 fet_beginchar ("Quarter down Funk dohead", "d2doFunk");
1997         draw_Funk_do_head (funk_notehead_width, funk_do_weight);
1998         fill p_down_out;
1999 fet_endchar;
2000
2001
2002 %%%%%%  Funk re head
2003 %       Arrowhead shape.
2004 %       Has up and down shapes for *all* notes
2005 %
2006 def draw_Funk_re_head (expr width_factor, thickness_factor) =
2007         set_char_box (0, width_factor * solfa_base_notewidth#,
2008                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
2009
2010         save offset;
2011         offset := 2 * thickness_factor - 1;
2012
2013         save pen_radius;
2014         pen_radius := min (solfa_pen_radius,
2015                            .3 * (h + d) / (1 + offset));
2016
2017         pickup pencircle scaled (2 * pen_radius);
2018
2019         save curve_in;
2020         curve_in := 0.9;
2021
2022         lft x1 = 0;
2023         y1 := 0.5 [y2, y4];
2024
2025         rt x2 = w;
2026         top y2 = h;
2027
2028         x3 := curve_in [x1, x2];
2029         y3 := y1;
2030
2031         x4 = x2;
2032         bot y4 = -d;
2033
2034         z6 = lft z3;
2035
2036         save ne, se, ne_perp, se_perp;
2037         pair ne, se, ne_perp, se_perp;
2038
2039         ne := unitvector (z2 - z1);
2040         se := unitvector (z4 - z1);
2041         ne_perp := ne rotated 90;
2042         se_perp := se rotated 90;
2043
2044         save path_a, path_b, path_c, path_d;
2045         path path_a, path_b, path_c, path_d;
2046         save arrow_a_perp, arrow_b_perp;
2047         pair arrow_a_perp, arrow_b_perp;
2048
2049
2050         path_d := z2 .. z3{down} .. z4;
2051         arrow_a_perp = unitvector (direction 0 of path_d rotated 90)
2052                        * pen_radius;
2053         arrow_b_perp = unitvector (direction 2 of path_d rotated 90)
2054                        * pen_radius;
2055
2056         path_b := (z1 + se_perp * pen_radius)
2057                   -- z4 + se_perp * offset * pen_radius;
2058         path_a := (z1 - ne_perp * pen_radius)
2059                   -- z2 - ne_perp * offset * pen_radius;
2060         path_c := z2 - arrow_a_perp
2061                   .. z6{down}
2062                   .. z4 - arrow_b_perp;
2063
2064         z5 = path_a intersectionpoint path_b;
2065         z7 = path_a intersectionpoint path_c;
2066         z8 = path_b intersectionpoint path_c;
2067
2068         save p_up_in, p_down_in, p_up_out, p_down_out;
2069         path p_up_in, p_down_in, p_up_out, p_down_out;
2070
2071         p_down_in := z5
2072                      -- z7
2073                      .. z6{down}
2074                      .. z8
2075                      -- cycle;
2076
2077         p_down_out := lft z1{up}
2078                       .. (z1 + ne_perp * pen_radius){ne}
2079                       -- (z2 + ne_perp * pen_radius){ne}
2080                       .. top z2 {right}
2081                       .. rt z2{down}
2082                       .. (z2 + arrow_a_perp)
2083                       .. rt z3{down}
2084                       .. (z4 + arrow_b_perp)
2085                       .. rt z4{down}
2086                       .. bot z4 {left}
2087                       .. z4 - se_perp * pen_radius
2088                       -- z1 - se_perp * pen_radius
2089                       .. cycle;
2090
2091         p_up_in := p_down_in rotated 180 shifted (w, 0);
2092         p_up_out := p_down_out rotated 180 shifted (w, 0);
2093
2094 enddef;
2095
2096
2097 save funk_re_weight;
2098 funk_re_weight = 1.7;
2099
2100 fet_beginchar ("Whole up Funk rehead", "u0reFunk");
2101         draw_Funk_re_head (funk_notehead_width, funk_re_weight);
2102         fill p_up_out;
2103         unfill p_up_in;
2104 fet_endchar;
2105
2106
2107 fet_beginchar ("Whole down Funk rehead", "d0reFunk");
2108         draw_Funk_re_head (funk_notehead_width, funk_re_weight);
2109         fill p_down_out;
2110         unfill p_down_in;
2111 fet_endchar;
2112
2113
2114 fet_beginchar ("Half up Funk rehead", "u1reFunk");
2115         draw_Funk_re_head (funk_notehead_width, funk_re_weight);
2116         fill p_up_out;
2117         unfill p_up_in;
2118 fet_endchar;
2119
2120
2121 fet_beginchar ("Half down Funk rehead", "d1reFunk");
2122         draw_Funk_re_head (funk_notehead_width, funk_re_weight);
2123         fill p_down_out;
2124         unfill p_down_in;
2125 fet_endchar;
2126
2127
2128 fet_beginchar ("Quarter up Funk rehead", "u2reFunk");
2129         draw_Funk_re_head (funk_notehead_width, funk_re_weight);
2130         fill p_up_out;
2131 fet_endchar;
2132
2133
2134 fet_beginchar ("Quarter down Funk rehead", "d2reFunk");
2135         draw_Funk_re_head (funk_notehead_width, funk_re_weight);
2136         fill p_down_out;
2137 fet_endchar;
2138
2139
2140 %%%%%%  Funk mi head
2141 %       Diamond shape
2142 %       Has up and down shapes for all hollow notes
2143 %
2144 save funk_mi_width, funk_mi_weight;
2145 funk_mi_width := 1.2;
2146 funk_mi_weight := 1.9;
2147
2148 fet_beginchar ("Whole up Funk mihead", "u0miFunk");
2149         draw_mi_head (funk_mi_width * funk_notehead_width,
2150                       funk_mi_weight, false);
2151         fill path_out;
2152         unfill path_in;
2153 fet_endchar;
2154
2155
2156 fet_beginchar ("Whole down Funk mihead", "d0miFunk");
2157         draw_mi_head (funk_mi_width * funk_notehead_width,
2158                       funk_mi_weight, true);
2159         fill path_out;
2160         unfill path_in;
2161 fet_endchar;
2162
2163
2164 fet_beginchar ("Half up Funk mihead", "u1miFunk");
2165         draw_mi_head (funk_mi_width * funk_notehead_width,
2166                       funk_mi_weight, false);
2167         fill path_out;
2168         unfill path_in;
2169 fet_endchar;
2170
2171
2172 fet_beginchar ("Half down Funk mihead", "d1miFunk");
2173         draw_mi_head (funk_mi_width * funk_notehead_width,
2174                       funk_mi_weight, true);
2175         fill path_out;
2176         unfill path_in;
2177 fet_endchar;
2178
2179
2180 fet_beginchar ("Quarter Funk mihead", "s2miFunk");
2181         draw_mi_head (funk_mi_width * funk_notehead_width,
2182                       funk_mi_weight, false);
2183         fill path_out;
2184 fet_endchar;
2185
2186
2187 %%%%%%  Funk fa
2188 %       Triangle shape
2189 %       Does it rotate for whole notes?
2190 %       Same as other shape note systems
2191 %       Need special notes because of special width
2192 %
2193 save funk_fa_weight;
2194 funk_fa_weight := 1.9;
2195
2196 fet_beginchar ("Whole up Funk fahead", "u0faFunk");
2197         draw_fa_head (funk_notehead_width, funk_fa_weight);
2198         fill p_up_out;
2199         unfill p_up_in;
2200 fet_endchar;
2201
2202
2203 fet_beginchar ("Whole down Funk fahead", "d0faFunk");
2204         draw_fa_head (funk_notehead_width, funk_fa_weight);
2205         fill p_down_out;
2206         unfill p_down_in;
2207 fet_endchar;
2208
2209
2210 fet_beginchar ("Half up Funk fahead", "u1faFunk");
2211         draw_fa_head (funk_notehead_width, funk_fa_weight);
2212         fill p_up_out;
2213         unfill p_up_in;
2214 fet_endchar;
2215
2216
2217 fet_beginchar ("Half down Funk fahead", "d1faFunk");
2218         draw_fa_head (funk_notehead_width, funk_fa_weight);
2219         fill p_down_out;
2220         unfill p_down_in;
2221 fet_endchar;
2222
2223
2224 fet_beginchar ("Quarter up Funk fahead", "u2faFunk");
2225         draw_fa_head (funk_notehead_width, funk_fa_weight);
2226         fill p_up_out;
2227 fet_endchar;
2228
2229
2230 fet_beginchar ("Quarter down Funk fahead", "d2faFunk");
2231         draw_fa_head (funk_notehead_width, funk_fa_weight);
2232         fill p_down_out;
2233 fet_endchar;
2234
2235
2236 %%%%%%  Funk sol head is the same as the others
2237 %       Need special character because of skinnier head
2238 %
2239 def draw_Funk_sol_head (expr filled) =
2240 begingroup
2241         save noteheight;
2242         noteheight# := solfa_noteheight#;
2243         draw_outside_ellipse (1.2, 34, 0.71, 0.);
2244         if not filled:
2245           undraw_inside_ellipse (1.9, 33, 0.74, 5.5 stafflinethickness#);
2246         fi
2247         draw_staff (-2, 2, 0);
2248 endgroup
2249 enddef;
2250
2251
2252 fet_beginchar ("Whole Funk solhead", "s0solFunk");
2253         draw_Funk_sol_head ( false);
2254 fet_endchar;
2255
2256
2257 fet_beginchar ("Half Funk solhead", "s1solFunk");
2258         draw_Funk_sol_head ( false);
2259 fet_endchar;
2260
2261
2262 fet_beginchar ("Quarter Funk solhead", "s2solFunk");
2263         draw_Funk_sol_head ( true);
2264 fet_endchar;
2265
2266
2267 %%%%%%  Funk la head
2268 %       Rectangle head
2269 %       Same as for other shape notes
2270 %       Smaller width requires special characters
2271 %
2272 save funk_la_weight;
2273 funk_la_weight := 1.9;
2274
2275 fet_beginchar ("Whole Funk lahead", "s0laFunk");
2276         draw_la_head (funk_notehead_width, funk_notehead_width);
2277         fill p_out;
2278         unfill p_in;
2279 fet_endchar;
2280
2281
2282 fet_beginchar ("Half Funk lahead", "s1laFunk");
2283         draw_la_head (funk_notehead_width, funk_notehead_width);
2284         fill p_out;
2285         unfill p_in;
2286 fet_endchar;
2287
2288
2289 fet_beginchar ("Quarter Funk lahead", "s2laFunk");
2290         draw_la_head (funk_notehead_width, funk_notehead_width);
2291         fill p_out;
2292 fet_endchar;
2293
2294
2295 %%%%%%  Funk ti head
2296 %       `Sideways snow cone'.
2297 %       Rotates for all notes.
2298 %
2299 def draw_Funk_ti_head (expr width_factor, thickness_factor) =
2300         set_char_box (0, width_factor * solfa_base_notewidth#,
2301                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
2302         save cone_width;
2303         cone_width = 0.8;
2304
2305         save offset;
2306         offset := 2 * thickness_factor - 1;
2307
2308         save pen_radius;
2309         pen_radius := min (solfa_pen_radius,
2310                            .33 * (h + d) / (1 + offset));
2311
2312         pickup pencircle scaled (2 * pen_radius);
2313
2314         lft x1 = 0;
2315         y1 = .5 [y2, y4];
2316
2317         x2 = cone_width [x1, x3];
2318         top y2 = h;
2319
2320         rt x3 = w;
2321         y3 = y1;
2322
2323         x4 = x2;
2324         bot y4 = -d;
2325
2326         save nw_dist, sw_dist, ne, se;
2327         pair nw_dist, sw_dist, ne, se;
2328
2329         ne = unitvector (z2 - z1);
2330         se = unitvector (z4 - z1);
2331
2332         nw_dist = (ne rotated 90) * pen_radius ;
2333         sw_dist = (se rotated -90) * pen_radius;
2334
2335         save path_a, path_b;
2336         path path_a, path_b;
2337         path_a := z1 - nw_dist
2338                   -- z2 - offset * nw_dist;
2339         path_b := z1 - sw_dist
2340                   -- z4 - offset * sw_dist;
2341
2342         save path_right, path_right_in;
2343         path path_right, path_right_in;
2344         path_right := (z2 + ne * pen_radius)
2345                       .. (rt z3){down}
2346                       .. (z4 + se * pen_radius);
2347
2348         path_right_in := (z2 - ne * pen_radius)
2349                          .. lft z3{down}
2350                          .. (z4 - se * pen_radius);
2351
2352         z5 = path_a intersectionpoint path_b;
2353         z6 = path_a intersectionpoint path_right_in;
2354         z7 = path_b intersectionpoint path_right_in;
2355
2356         save p_up_in, p_down_in, p_up_out, p_down_out;
2357         path p_up_in, p_down_in, p_up_out, p_down_out;
2358
2359         p_down_in := z5
2360                      -- z6
2361                      .. lft z3
2362                      .. z7
2363                      -- cycle;
2364
2365         p_down_out := lft z1
2366                       .. (z1 + nw_dist)
2367                       -- (z2 + nw_dist)
2368                       .. top z2
2369                       .. (z2 + ne * pen_radius){direction 0 of path_right}
2370                       & path_right
2371                       & {direction infinity of path_right}(z4 + se * pen_radius)
2372                       .. bot z4
2373                       .. (z4 + sw_dist)
2374                       -- (z1 + sw_dist)
2375                       .. cycle;
2376
2377         p_up_in := p_down_in rotated 180 shifted (w, 0);
2378         p_up_out := p_down_out rotated 180 shifted (w, 0);
2379 enddef;
2380
2381
2382 save funk_ti_weight;
2383 funk_ti_weight := 1.6;
2384
2385 fet_beginchar ("Whole up Funk tihead", "u0tiFunk");
2386         draw_Funk_ti_head (funk_notehead_width, funk_ti_weight);
2387         fill p_up_out;
2388         unfill p_up_in;
2389 fet_endchar;
2390
2391
2392 fet_beginchar ("Whole down Funk tihead", "d0tiFunk");
2393         draw_Funk_ti_head (funk_notehead_width, funk_ti_weight);
2394         fill p_down_out;
2395         unfill p_down_in;
2396 fet_endchar;
2397
2398
2399 fet_beginchar ("Half up Funk tihead", "u1tiFunk");
2400         draw_Funk_ti_head (funk_notehead_width, funk_ti_weight);
2401         fill p_up_out;
2402         unfill p_up_in;
2403 fet_endchar;
2404
2405
2406 fet_beginchar ("Half down Funk tihead", "d1tiFunk");
2407         draw_Funk_ti_head (funk_notehead_width, funk_ti_weight);
2408         fill p_down_out;
2409         unfill p_down_in;
2410 fet_endchar;
2411
2412
2413 fet_beginchar ("Quarter up Funk tihead", "u2tiFunk");
2414         draw_Funk_ti_head (funk_notehead_width, funk_ti_weight);
2415         fill p_up_out;
2416 fet_endchar;
2417
2418
2419 fet_beginchar ("Quarter down Funk tihead", "d2tiFunk");
2420         draw_Funk_ti_head (funk_notehead_width, funk_ti_weight);
2421         fill p_down_out;
2422 fet_endchar;
2423
2424
2425 %%%%%%   Walker shape note heads
2426 %
2427 % Walker heads are narrow like Funk heads, so use funk_notehead_width.
2428 %
2429
2430 %%%%%%   Walker do head
2431 %
2432 % Trapezoid, with largest side on stem side
2433 %
2434 def draw_Walker_do_head (expr width_factor, dir, thickness_factor) =
2435         set_char_box (0, width_factor * solfa_base_notewidth#,
2436                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
2437
2438         pickup pencircle scaled solfa_pen_thick;
2439
2440         save offset;
2441         offset := 2 * thickness_factor - 1;
2442
2443         % adjust width so stem can be centered
2444         if .5w <> good.x .5w: change_width; fi
2445
2446         save scaling;
2447
2448         scaling# = charwd / w;
2449
2450         save inset;
2451         inset := 0.25;
2452
2453         x1 = inset [x4, x3];
2454         top y1 = h;
2455
2456         x2 = inset [x3, x4];
2457         y2 = y1;
2458
2459         bot y3 = -d;
2460         rt x3 = w;
2461
2462         y4 = y3;
2463         lft x4 = 0;
2464
2465         labels (range 1 thru 4);
2466
2467         save left_dir, left_perp, right_dir, right_perp;
2468         pair left_dir, left_perp, right_dir, right_perp;
2469
2470         left_dir = unitvector(z1 - z4);
2471         left_perp = (left_dir rotated 90) * solfa_pen_radius;
2472         right_dir = unitvector(z3 - z2);
2473         right_perp = (right_dir rotated 90) * solfa_pen_radius;
2474
2475         save path_a, path_b, path_c, path_d;
2476         path path_a, path_b, path_c, path_d;
2477
2478         path_a := (z4 - left_perp)
2479                   -- (z1 - left_perp);
2480         path_b := (z1 - (0, offset*solfa_pen_radius))
2481                   -- (z2 - (0, offset*solfa_pen_radius));
2482         path_c := (z2 - right_perp)
2483                   -- (z3 - right_perp);
2484         path_d := (z3 + (0, offset*solfa_pen_radius))
2485                   -- (z4 + (0, offset*solfa_pen_radius));
2486
2487         save p_in, p_out;
2488         path p_in, p_out;
2489
2490         p_in := (path_a intersectionpoint path_b)
2491                 -- (path_b intersectionpoint path_c)
2492                 -- (path_c intersectionpoint path_d)
2493                 -- (path_d intersectionpoint path_a)
2494                 -- cycle;
2495
2496         p_out := top z1{right}
2497                  -- top z2{right}
2498                  .. z2 + right_perp {right_dir}
2499                  -- z3 + right_perp {right_dir}
2500                  .. bot z3{left}
2501                  -- bot z4{left}
2502                  .. z4 + left_perp {left_dir}
2503                  .. z1 + left_perp {left_dir}
2504                  .. cycle;
2505
2506         charwx := scaling# * (w/2 + solfa_pen_radius);
2507         charwy := scaling# * y2 ;
2508
2509         if dir = 1:
2510                 p_in := p_in rotated 180 shifted (w,0);
2511                 p_out := p_out rotated 180 shifted (w,0);
2512         fi;
2513 enddef;
2514
2515
2516 save walker_do_weight;
2517 walker_do_weight := 1.5;
2518
2519 fet_beginchar ("Whole Walker dohead", "s0doWalker");
2520         draw_Walker_do_head (funk_notehead_width, 0, walker_do_weight);
2521         fill p_out;
2522         unfill p_in;
2523 fet_endchar;
2524
2525
2526 fet_beginchar ("Half up Walker dohead", "u1doWalker");
2527         draw_Walker_do_head (funk_notehead_width, 1, walker_do_weight);
2528         fill p_out;
2529         unfill p_in;
2530 fet_endchar;
2531
2532
2533 fet_beginchar ("Half down Walker dohead", "d1doWalker");
2534         draw_Walker_do_head (funk_notehead_width, 0, walker_do_weight);
2535         fill p_out;
2536         unfill p_in;
2537 fet_endchar;
2538
2539
2540 fet_beginchar ("Quarter up Walker dohead", "u2doWalker");
2541         draw_Walker_do_head (funk_notehead_width, 1, walker_do_weight);
2542         fill p_out;
2543 fet_endchar;
2544
2545
2546 fet_beginchar ("Quarter down Walker dohead", "d2doWalker");
2547         draw_Walker_do_head (funk_notehead_width, 0, walker_do_weight);
2548         fill p_out;
2549 fet_endchar;
2550
2551
2552 %%%%%%   Walker re head
2553 %          Parabolic on one side, shallow parabola on other
2554 %          Has up and down shapes for *all* notes
2555 %
2556 def draw_Walker_re_head (expr width_factor, thickness_factor) =
2557         set_char_box (0, width_factor * solfa_base_notewidth#,
2558                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
2559
2560         save offset;
2561         offset := 2 * thickness_factor - 1;
2562
2563         save pen_radius;
2564         pen_radius := min (solfa_pen_radius,
2565                            .3 * (h + d) / (1 + offset));
2566
2567         pickup pencircle scaled (2 * pen_radius);
2568
2569         save dish_factor;
2570         dish_factor := 0.20;
2571
2572         rt x1 = w;
2573         bot y1 = -d;
2574
2575         lft x2 = 0;
2576         y2 = 0.5 [y1, y3];
2577
2578         top y3 = h;
2579         x3 = x1;
2580
2581         x4 = dish_factor [x1, x2];
2582         y4 = y2;
2583
2584         x5 = x1;
2585         y5 = y1 + offset * pen_radius;
2586
2587         y6 = y2;
2588         x6 = x2 + pen_radius;
2589
2590         x7 = x3;
2591         y7 = y3 - offset * pen_radius;
2592
2593         y8 = y4;
2594         x8 = x4 - pen_radius;
2595
2596         save path_a, path_d;
2597         path path_a, path_d;
2598
2599         save p_a_start_dir, p_a_end_dir, p_a_start_perp, p_a_end_perp;
2600         pair p_a_start_dir, p_a_end_dir, p_a_start_perp, p_a_end_perp;
2601
2602         path_a := z3 .. z4{down} .. z1;
2603
2604         p_a_start_dir := unitvector(direction 0 of path_a);
2605         p_a_end_dir := unitvector(direction infinity of path_a);
2606         p_a_start_perp := (p_a_start_dir rotated 90) * pen_radius;
2607         p_a_end_perp := (p_a_end_dir rotated 90) * pen_radius;
2608
2609         path_d := (z3 - p_a_start_perp){p_a_start_dir}
2610                   .. z4 {down}
2611                   ..(z1 - p_a_end_perp){p_a_end_dir};
2612
2613         save path_b, path_c;
2614         path path_b, path_c;
2615
2616         path_b := z5 {left} .. z6{up};
2617         path_c := z7 {left} .. z6{down};
2618
2619         z9 = path_d intersectionpoint path_b;
2620         z10 = path_d intersectionpoint path_c;
2621
2622         labels (range 1 thru 4);
2623
2624         save p_up_in, p_up_out, p_down_in, p_down_out;
2625         path p_up_in, p_up_out, p_down_in, p_down_out;
2626
2627         p_down_in := z6{up}
2628                      ... {right} z10 {p_a_start_dir}
2629                      .. z8{down}
2630                      .. {p_a_end_dir} z9 {left}
2631                      ... cycle;
2632
2633         p_down_out := lft z2{up}
2634                       .. top z3{right}
2635                       .. rt z3
2636                       .. (z3 + p_a_start_perp){p_a_start_dir}
2637                       .. rt z4{down}
2638                       .. (z1 + p_a_end_perp) {p_a_end_dir}
2639                       .. rt z1
2640                       .. bot z1 {left}
2641                       .. cycle;
2642
2643         p_up_in := p_down_in rotated 180 shifted (w,0);
2644         p_up_out := p_down_out rotated 180 shifted (w,0);
2645 enddef;
2646
2647
2648 save walker_re_weight;
2649 walker_re_weight := 1.2;
2650
2651 fet_beginchar ("Whole Walker rehead", "s0reWalker");
2652         draw_Walker_re_head (funk_notehead_width, walker_re_weight);
2653         fill p_down_out;
2654         unfill p_down_in;
2655 fet_endchar;
2656
2657
2658 fet_beginchar ("Half up Walker rehead", "u1reWalker");
2659         draw_Walker_re_head (funk_notehead_width, walker_re_weight);
2660         fill p_up_out;
2661         unfill p_up_in;
2662 fet_endchar;
2663
2664
2665 fet_beginchar ("Half down Walker rehead", "d1reWalker");
2666         draw_Walker_re_head (funk_notehead_width, walker_re_weight);
2667         fill p_down_out;
2668         unfill p_down_in;
2669 fet_endchar;
2670
2671
2672 fet_beginchar ("Quarter up Walker rehead", "u2reWalker");
2673         draw_Walker_re_head (funk_notehead_width, walker_re_weight);
2674         fill p_up_out;
2675 fet_endchar;
2676
2677
2678 fet_beginchar ("Quarter down Walker rehead", "d2reWalker");
2679         draw_Walker_re_head (funk_notehead_width, walker_re_weight);
2680         fill p_down_out;
2681 fet_endchar;
2682
2683
2684 %%%%%%  Walker mi head
2685 %       Diamond shape
2686 %       Symmetric for all hollow notes
2687 %
2688 save walker_mi_width, walker_mi_weight;
2689 walker_mi_width := 1.2;
2690 walker_mi_weight := 1.5;
2691
2692 fet_beginchar ("Whole Walker mihead", "s0miWalker");
2693         draw_mi_head (walker_mi_width * funk_notehead_width,
2694                       walker_mi_weight, true);
2695         fill path_out;
2696         unfill path_in;
2697 fet_endchar;
2698
2699
2700 fet_beginchar ("Half Walker mihead", "s1miWalker");
2701         draw_mi_head (walker_mi_width * funk_notehead_width,
2702                       walker_mi_weight, true);
2703         fill path_out;
2704         unfill path_in;
2705 fet_endchar;
2706
2707
2708 fet_beginchar ("Quarter Walker mihead", "s2miWalker");
2709         draw_mi_head (walker_mi_width * funk_notehead_width,
2710                       walker_mi_weight, true);
2711         fill path_out;
2712 fet_endchar;
2713
2714
2715 %%%%%%  Walker fa
2716 %       Triangle shape
2717 %       Does not rotate for whole notes
2718 %       Whole rotation is different from Funk, so special notes
2719
2720 %%%%%%  Funk sol head is the same as the others
2721 %       Need special character because of skinnier head
2722 %
2723 save walker_fa_weight;
2724 walker_fa_weight := 1.5;
2725
2726 fet_beginchar ("Whole Walker fahead", "s0faWalker");
2727         draw_fa_head (funk_notehead_width, walker_fa_weight);
2728         fill p_down_out;
2729         unfill p_down_in;
2730 fet_endchar;
2731
2732
2733 fet_beginchar ("Half up Walker fahead", "u1faWalker");
2734         draw_fa_head (funk_notehead_width, walker_fa_weight);
2735         fill p_up_out;
2736         unfill p_up_in;
2737 fet_endchar;
2738
2739
2740 fet_beginchar ("Half down Walker fahead", "d1faWalker");
2741         draw_fa_head (funk_notehead_width, walker_fa_weight);
2742         fill p_down_out;
2743         unfill p_down_in;
2744 fet_endchar;
2745
2746
2747 fet_beginchar ("Quarter up Walker fahead", "u2faWalker");
2748         draw_fa_head (funk_notehead_width, walker_fa_weight);
2749         fill p_up_out;
2750 fet_endchar;
2751
2752
2753 fet_beginchar ("Quarter down Walker fahead", "d2faWalker");
2754         draw_fa_head (funk_notehead_width, walker_fa_weight);
2755         fill p_down_out;
2756 fet_endchar;
2757
2758
2759 %%%%%%  Walker sol
2760 %       Same as Funk, no special notes
2761 %
2762
2763 %%%%%%  Walker la head
2764 %       Rectcangle head
2765 %       Lighter weight requires separate notes
2766 %
2767 save walker_la_weight;
2768 walker_la_weight := 1.5;
2769
2770 fet_beginchar ("Whole Walker lahead", "s0laWalker");
2771         draw_la_head (funk_notehead_width, walker_la_weight);
2772         fill p_out;
2773         unfill p_in;
2774 fet_endchar;
2775
2776
2777 fet_beginchar ("Half Funk lahead", "s1laWalker");
2778         draw_la_head (funk_notehead_width, walker_la_weight);
2779         fill p_out;
2780         unfill p_in;
2781 fet_endchar;
2782
2783
2784 fet_beginchar ("Quarter Funk lahead", "s2laWalker");
2785         draw_la_head (funk_notehead_width, walker_la_weight);
2786         fill p_out;
2787 fet_endchar;
2788
2789
2790 %%%%%%  Walker ti head
2791 %       Triangular arrowhead
2792 %       Rotates for all but whole notes
2793 %
2794 def draw_Walker_ti_head (expr width_factor, thickness_factor) =
2795         set_char_box (0, width_factor * solfa_base_notewidth#,
2796                       0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
2797
2798         save offset;
2799         offset := 2 * thickness_factor - 1;
2800
2801         save pen_radius;
2802         pen_radius := min (solfa_pen_radius,
2803                            .3 * (h + d) / (1 + offset));
2804
2805         pickup pencircle scaled (2 * pen_radius);
2806
2807         lft x1 = 0;
2808         y1 = .5 [y2, y3];
2809
2810         rt x2 = w;
2811         top y2 = h;
2812
2813         x3 = x2;
2814         bot y3 = -d;
2815
2816
2817         labels (range 1 thru 4);
2818
2819         save nw_dist, sw_dist, ne, se;
2820         pair nw_dist, sw_dist, ne, se;
2821
2822         ne = unitvector (z2 - z1);
2823         se = unitvector (z3 - z1);
2824
2825         nw_dist = (ne rotated 90) * pen_radius ;
2826         sw_dist = (se rotated -90) * pen_radius;
2827
2828
2829         save path_a, path_b, path_c;
2830         path path_a, path_b, path_c;
2831         path_a := z2 - nw_dist * offset
2832                   -- z1 - nw_dist * offset;
2833         path_b := z3 - sw_dist * offset
2834                   -- z1 - sw_dist * offset;
2835         path_c := z2 + left * pen_radius
2836                   -- z3 + left * pen_radius;
2837
2838         z4 = path_a intersectionpoint path_b;
2839         z5 = path_a intersectionpoint path_c;
2840         z6 = path_b intersectionpoint path_c;
2841
2842         save p_up_in, p_down_in, p_up_out, p_down_out;
2843         path p_up_in, p_down_in, p_up_out, p_down_out;
2844
2845         p_down_in := z4
2846                      -- z5
2847                      -- z6
2848                      -- cycle;
2849
2850         p_down_out := lft z1{up}
2851                       .. (z1 + nw_dist){ne}
2852                       -- (z2 + nw_dist){ne}
2853                       .. top z2{right}
2854                       .. rt z2 {down}
2855                       -- rt z3 {down}
2856                       .. bot z3 {left}
2857                       .. (z3 + sw_dist){- se}
2858                       .. (z1 + sw_dist){- se}
2859                       .. cycle;
2860
2861         p_up_in := p_down_in rotated 180 shifted (w, 0);
2862         p_up_out := p_down_out rotated 180 shifted (w, 0);
2863 enddef;
2864
2865
2866 save walker_ti_weight;
2867 walker_ti_weight := 1.4;
2868
2869 fet_beginchar ("Whole Walker tihead", "s0tiWalker");
2870         draw_Walker_ti_head (funk_notehead_width, walker_ti_weight);
2871         fill p_down_out;
2872         unfill p_down_in;
2873 fet_endchar;
2874
2875
2876 fet_beginchar ("Half up Walker tihead", "u1tiWalker");
2877         draw_Walker_ti_head (funk_notehead_width, walker_ti_weight);
2878         fill p_up_out;
2879         unfill p_up_in;
2880 fet_endchar;
2881
2882
2883 fet_beginchar ("Half down Walker tihead", "d1tiWalker");
2884         draw_Walker_ti_head (funk_notehead_width, walker_ti_weight);
2885         fill p_down_out;
2886         unfill p_down_in;
2887 fet_endchar;
2888
2889
2890 fet_beginchar ("Quarter up Walker tihead", "u2tiWalker");
2891         draw_Walker_ti_head (funk_notehead_width, walker_ti_weight);
2892         fill p_up_out;
2893 fet_endchar;
2894
2895
2896 fet_beginchar ("Quarter down Walker tihead", "d2tiWalker");
2897         draw_Walker_ti_head (funk_notehead_width, walker_ti_weight);
2898         fill p_down_out;
2899 fet_endchar;
2900
2901 fet_endgroup ("noteheads");
2902
2903
2904 %
2905 % we derive black_notehead_width# from the quarter head,
2906 % so we have to define black_notehead_width (pixel qty)
2907 % after the black_notehead_width# itself.
2908 %
2909 % Let's keep it outside the group as well.
2910 %
2911
2912 define_pixels (black_notehead_width);