]> git.donarmstrong.com Git - lilypond.git/blob - mf/parmesan-heads.mf
Merge branch 'master' into topic/master-translation
[lilypond.git] / mf / parmesan-heads.mf
1 % -%-Fundamental-%- -*-Metafont-*-
2 % parmesan-heads.mf -- implement ancient note heads
3
4 % source file of LilyPond's pretty-but-neat music font
5
6 % (c) 2001--2006 Juergen Reuter <reuter@ipd.uka.de>
7
8 % Neo-mensural heads originally by
9 % Christian Mondrup and Mats Bengtsson
10
11
12 save black_notehead_width;
13 numeric black_notehead_width;
14
15 fet_begingroup ("noteheads")
16
17 %
18 % character aligment:
19 %
20 %   The head is assumed to be vertically centered around (0, 0).
21 %   The left-most edge of the head should touch the vertical line
22 %   that goes though the point (0, 0).
23 %
24 % set_char_box() conventions:
25 %
26 % * breapth: Ignored (as far as I know).  Should be set to 0.
27 %
28 % * width: Should match the head's width.
29 %
30 % * depth: Should match the bottom edge of the head.  Affects vertical
31 %   collision handling.
32 %
33 % * height: Should match the top edge of the head.  Affects vertical
34 %   collision handling.
35 %
36 % TODO: should depth/height include appendages/stems?
37
38 overdone_heads = 0;
39 noteheight# := staff_space# + (1 + overdone_heads) * stafflinethickness#;
40 define_pixels (noteheight);
41
42
43 %%%%%%%%
44 %
45 %
46 %
47 % MENSURAL NOTATION
48 %
49 %
50 %
51
52 def draw_neomensural_brevis (expr brevwid) =
53         save beamheight, head_width;
54         save holeheight, stem_width;
55         save serif_size, serif_protrude;
56
57         head_width# = brevwid;
58         holeheight = 3 stafflinethickness;
59         stem_width = 1.4 stafflinethickness;
60
61         define_pixels (head_width);
62
63         set_char_box (0, head_width#,
64                       noteheight# / 2, noteheight# / 2);
65         
66         2 beamheight + holeheight = noteheight;
67         serif_size = (holeheight - stafflinethickness) / 2;
68         serif_protrude = 1.5 serif_size;
69
70         z1l = (0, 0);
71         z2l = (0, -stafflinethickness / 2);
72         z3r = z2r + serif_size * (1, -1);
73         y4r = y3r;
74         x4r = head_width / 2;
75         z5l = z3l + (-serif_size, -serif_protrude);
76
77         penpos1 (stem_width, 0);
78         penpos2 (stem_width, 0);
79         penpos3 (beamheight, 90);
80         penpos4 (beamheight, 90);
81         penpos5 (stem_width, 180);
82
83         save pat_in, pat_out;
84         path pat_in, pat_out;
85
86         pat_out := z4l
87                    -- z3l{left}
88                    .. z5l{down}
89                    .. z5r{up}
90                    -- z1l;
91         pat_out := pat_out
92                    -- reverse pat_out yscaled -1;
93         pat_out := pat_out
94                    -- reverse pat_out shifted (-x4r, 0)
95                                       xscaled -1
96                                       shifted (x4l, 0)
97                    -- cycle;
98         fill pat_out;
99
100         pat_in := z4r
101                   -- z3r{left}
102                   .. z2r{up}
103                   -- z1r;
104         pat_in := pat_in
105                   -- reverse pat_in yscaled -1;
106         pat_in := pat_in
107                   -- reverse pat_in shifted (-x4r, 0)
108                                     xscaled -1
109                                     shifted (x4l, 0)
110                   -- cycle;
111         unfill pat_in;
112
113         penlabels (1, 2, 3, 4, 5);
114 enddef;
115
116
117 %%% This head does not seem to be used anywhere.  Junk me?  -- jr
118 def draw_neomensural_left_stemmed_head (expr wid) =
119         draw_neomensural_brevis (wid);
120
121         x6 = x7 = stem_width / 2;
122         y6 = y5;
123         y7 = y5 - 2.25 staff_space;
124
125         z17 = (x7, y7 - stem_width / 2);
126
127         penpos6 (stem_width, 0);
128         penpos7 (stem_width, 0);
129
130         fill z7l
131              -- z6l
132              -- z6r
133              -- z7r
134              .. z17
135              .. cycle;
136
137         penlabels (6, 7);
138         labels (17);
139 enddef;
140
141
142 %%% This head does not seem to be used anywhere.  Junk me?  -- jr
143 fet_beginchar ("Left stemmed notehead", "slneomensural");
144         draw_neomensural_left_stemmed_head (2 staff_space#);
145 fet_endchar;
146
147
148 %
149 % Find point on `curve' which gives the tangent between point `p'
150 % and `curve'.  To guide the search, two auxiliary points must be
151 % specified, `p_in' and `p_out'.  The line between `p' and `p_in'
152 % must intersect `curve', while the line between `p' and `p_out'
153 % must not.
154 %
155 def find_tangent (expr p, curve, p_in, p_out) =
156         begingroup;
157         save mid, t, t_good, in, out;
158         pair mid, in, out;
159
160         in := p_in;
161         out := p_out;
162
163         forever:
164                 mid := 0.5 [in, out];
165                 exitif abs (out - mid) <= eps;
166                 t := xpart (curve intersectiontimes (p -- mid));
167                 if (t > 0):
168                         in := mid;
169                         t_good := t;
170                 else:
171                         out := mid;
172                 fi;
173         endfor;
174
175         point t_good of curve
176         endgroup
177 enddef;
178
179
180 %
181 % Some sources (eg. Musix/OpusTeX) think that the appendage should be on
182 % the left, some say right.  Right wins democratically.
183 %
184 def draw_neomensural_longa (expr wid) =
185         draw_neomensural_brevis (wid);
186
187         save theta;
188
189         x7r = head_width;
190         y7 = y5;
191         z6 - z7 = (stem_width / 2, -staff_space);
192         theta = angle (z6 - z7) + 90;
193
194         penpos7 (stem_width, 0);
195         penpos6 (1.2 stem_width, theta);
196         
197         z7' = find_tangent (z6l, pat_out,
198                             (x7l + 0.5 stem_width, y7l),
199                             (x7l - 0.5 stem_width, y7l));
200
201         fill z7r
202              .. z6r{z6 - z7}
203              .. {z7 - z6}z6l
204              -- z7'
205              -- cycle;
206
207         penlabels (6, 7);
208         labels (7');
209 enddef;
210
211
212 %
213 % En wij presenteren U: de opvolgster van Emily
214 %
215 % (ze is wel breed)
216
217 fet_beginchar ("Neo-mensural maxima notehead", "s-3neomensural");
218         draw_neomensural_longa (2.6 staff_space#);
219 fet_endchar;
220
221
222 fet_beginchar ("Neo-mensural longa notehead", "s-2neomensural");
223         draw_neomensural_longa (2 staff_space#);
224 fet_endchar;
225
226
227 fet_beginchar ("Neo-mensural brevis notehead", "s-1neomensural");
228         draw_neomensural_brevis (2 staff_space#);
229 fet_endchar;
230
231
232 def draw_neomensural_black_head (expr wid, height) =
233         save head_width;
234         save ne, nw, ne_dist, nw_dist;
235         pair ne, nw, ne_dist, nw_dist;
236
237         head_width# = wid;
238
239         set_char_box (0, head_width#,
240                       height / 2, height / 2);
241         
242         charwx := head_width# / 2;
243         charwy := height / 2;
244
245         y3 = y1 = 0;
246         x2 = x4 = (x1 + x3) / 2;
247
248         pickup pencircle scaled blot_diameter;
249
250         top y2 = h;
251         bot y4 = -d;
252         lft x1 = 0;
253         rt x3 = w;
254
255         ne := unitvector (z2 - z1);
256         nw_dist := (ne rotated 90) * 0.5 blot_diameter;
257         nw := unitvector (z2 - z3);
258         ne_dist := (nw rotated -90) * 0.5 blot_diameter;
259
260         fill lft z1{up}
261              .. (z1 + nw_dist){ne}
262              -- (z2 + nw_dist){ne}
263              .. top z2{right}
264              .. (z2 + ne_dist){-nw}
265              -- (z3 + ne_dist){-nw}
266              .. rt z3{down}
267              .. (z3 - nw_dist){-ne}
268              -- (z4 - nw_dist){-ne}
269              .. bot z4{left}
270              .. (z4 - ne_dist){nw}
271              -- (z1 - ne_dist){nw}
272              .. cycle;
273
274         labels (1, 2, 3, 4);
275 enddef;
276
277
278 def draw_neomensural_open_head (expr wid, height)=
279         draw_neomensural_black_head (wid, height);
280
281         save diamNW, diamSW;
282
283         diamNW = length (z2 - z1) + blot_diameter;
284         diamSW = length (z4 - z1) + blot_diameter;
285         
286         save hole_widthNW, hole_widthSW;
287
288         hole_widthNW = 0.34 diamNW ;
289         hole_widthSW + 2.6 linethickness = diamSW;
290
291         (z7 + z5) / 2 = (w / 2, 0);
292         (z8 + z6) / 2 = (w / 2, 0);
293         z6 - z5 = hole_widthNW * unitvector (z2 - z1);
294         z7 - z6 = hole_widthSW * unitvector (z4 - z1);
295
296         unfill z5
297                -- z6
298                -- z7
299                -- z8
300                -- cycle;
301
302         labels (5, 6, 7, 8);
303 enddef;
304
305
306 %
307 % WL says the thin lines should be thinner.
308 %
309 fet_beginchar ("Harmonic notehead (Neo-mensural open)", "s0harmonic");
310         draw_neomensural_open_head (1.3 staff_space#, 1.3 noteheight#);
311         charwx := head_width#;
312         charwy := 0;
313 fet_endchar;
314
315
316 fet_beginchar ("Harmonic notehead (Neo-mensural black)", "s2harmonic");
317         draw_neomensural_black_head (1.3 staff_space#, 1.3 noteheight#);
318         charwx := head_width#;
319         charwy := 0;
320 fet_endchar;
321
322
323 fet_beginchar ("Neo-mensural semibrevis head", "s0neomensural");
324         draw_neomensural_open_head (staff_space#, noteheight#);
325 fet_endchar;
326
327
328 fet_beginchar ("Neo-mensural minima head", "s1neomensural");
329         draw_neomensural_open_head (staff_space#, noteheight#);
330 fet_endchar;
331
332
333 fet_beginchar ("Neo-mensural semiminima head", "s2neomensural");
334         draw_neomensural_black_head (staff_space#, noteheight#);
335 fet_endchar;
336
337
338 def draw_mensural_brevis (expr wid) =
339         % TODO.  For the moment, fall back to draw_neomensural_brevis.
340         draw_neomensural_brevis (wid);
341 enddef;
342
343
344 %%% This head does not seem to be used anywhere.  Junk me?  -- jr
345 def draw_mensural_left_stemmed_head (expr wid) =
346         draw_mensural_brevis (wid);
347
348         x6 = x7 = stem_width / 2;
349         y6 = y5;
350         y7 = y5 - 2.25 staff_space;
351
352         z17 = (x7, y7 - stem_width / 2);
353
354         penpos6 (stem_width, 0);
355         penpos7 (stem_width, 0);
356
357         fill z7l
358              -- z6l
359              -- z6r
360              -- z7r
361              .. z17
362              .. cycle;
363
364         penlabels (6, 7);
365         labels (17);
366 enddef;
367
368
369 def draw_mensural_longa (expr wid) =
370         draw_mensural_brevis (wid);
371
372         x6 = x7 = head_width - stem_width / 2;
373         y6 = y5;
374         y7 = y5 - 2.25 staff_space;
375
376         z17 = (x7, y7 - stem_width / 2);
377
378         penpos6 (stem_width, 0);
379         penpos7 (stem_width, 0);
380
381         fill z7l
382              -- z6l
383              -- z6r
384              -- z7r
385              .. z17
386              .. cycle;
387
388         penlabels (6, 7);
389         labels (17);
390 enddef;
391
392
393 %%% This head does not seem to be used anywhere.  Junk me?  -- jr
394 fet_beginchar ("Mensural left stemmed notehead", "slmensural");
395         draw_mensural_left_stemmed_head (staff_space#);
396 fet_endchar;
397
398
399 fet_beginchar ("Mensural maxima notehead", "s-3mensural");
400         draw_mensural_longa (2.0 staff_space#);
401 fet_endchar;
402
403
404 fet_beginchar ("Mensural longa notehead", "s-2mensural");
405         draw_mensural_longa (staff_space#);
406 fet_endchar;
407
408
409 fet_beginchar ("Mensural brevis notehead", "s-1mensural");
410         draw_mensural_brevis (staff_space#);
411 fet_endchar;
412
413
414 %
415 % Shift `curve' along the line given by the auxiliary points `p_in'
416 % and `p_out' until `line' is a tangent, and return the shift.
417 % If `curve' is shifted to position `p_in', it must intersect
418 % `line', while shifted to `p_out' it must not.
419 %
420 def find_tangent_shift (expr line, curve, p_in, p_out) =
421         begingroup;
422         save mid, t, t_good, in, out;
423         pair mid, in, out;
424
425         in := p_in;
426         out := p_out;
427
428         forever:
429                 mid := 0.5 [in, out];
430                 exitif abs (out - mid) <= eps;
431                 t := xpart ((curve shifted mid) intersectiontimes line);
432                 if (t > 0):
433                         in := mid;
434                         t_good := t;
435                 else:
436                         out := mid;
437                 fi;
438         endfor;
439
440         mid
441         endgroup
442 enddef;
443
444
445 def draw_diamond_head (expr head_h, pen_w, pen_h, angle, open) =
446         save head_width, head_height;
447         save ellipse, ellipse_r;
448         path ellipse, ellipse_r;
449
450         head_height# = head_h;
451         head_width# / head_height# = tand (angle);
452
453         set_char_box (0, head_width#,
454                       head_height# / 2, head_height# / 2);
455
456         charwx := head_width# / 2;
457         charwy := head_height# / 2 - linethickness#;
458
459         define_pixels (head_width, head_height);
460
461         ellipse := reverse fullcircle
462                      xscaled (max (blot_diameter, pen_w * head_width))
463                      yscaled (max (blot_diameter, pen_h * head_width))
464                      rotated -angle;
465         ellipse_r := ellipse rotated 180;
466
467         z1 = find_tangent_shift (((0, h) -- (0, -h)), ellipse,
468                                  (0, 0), (w / 2, 0));
469         z2 = find_tangent_shift (((0, h) -- (w, h)), ellipse,
470                                  (w / 2, h), (w / 2, 0));
471         z3 = find_tangent_shift (((w, h) -- (w, -h)), ellipse,
472                                  (w, 0), (w / 2, 0));
473         z4 = find_tangent_shift (((0, -h) -- (w, -h)), ellipse,
474                                  (w / 2, -h), (w / 2, 0));
475
476         fill (subpath (directiontime (z1 - z4) of ellipse,
477                        directiontime (z2 - z1) of ellipse)
478                of ellipse) shifted z1
479              -- (subpath (directiontime (z2 - z1) of ellipse,
480                           directiontime (z3 - z2) of ellipse)
481                   of ellipse) shifted z2
482              -- (subpath (directiontime (z3 - z2) of ellipse_r,
483                           directiontime (z4 - z3) of ellipse_r)
484                   of ellipse_r) shifted z3
485              -- (subpath (directiontime (z4 - z3) of ellipse_r,
486                           directiontime (z1 - z4) of ellipse_r)
487                   of ellipse_r) shifted z4
488              -- cycle;
489
490         if open:
491                 save l;
492                 path l[];
493
494                 l12 := (directionpoint (z1 - z2) of ellipse) shifted z1
495                         -- (directionpoint (z1 - z2) of ellipse) shifted z2;
496                 l23 := (directionpoint (z2 - z3) of ellipse) shifted z2
497                         -- (directionpoint (z2 - z3) of ellipse) shifted z3;
498                 l34 := (directionpoint (z3 - z4) of ellipse) shifted z3
499                         -- (directionpoint (z3 - z4) of ellipse) shifted z4;
500                 l41 := (directionpoint (z4 - z1) of ellipse) shifted z4
501                         -- (directionpoint (z4 - z1) of ellipse) shifted z1;
502
503                 unfill l12 intersectionpoint l23
504                        -- l23 intersectionpoint l34
505                        -- l34 intersectionpoint l41
506                        -- l41 intersectionpoint l12
507                        -- cycle;
508         fi;
509
510         labels (1, 2, 3, 4);
511 enddef;
512
513
514 fet_beginchar ("Mensural semibrevis head", "s0mensural");
515         draw_diamond_head (staff_space#, 0.15, 0.30, 30, true);
516 fet_endchar;
517
518
519 fet_beginchar ("Mensural minima head", "s1mensural");
520         draw_diamond_head (staff_space#, 0.15, 0.30, 30, true);
521 fet_endchar;
522
523
524 fet_beginchar ("Mensural semiminima head", "s2mensural");
525         draw_diamond_head (staff_space#, 0.15, 0.30, 30, false);
526 fet_endchar;
527
528
529 fet_beginchar ("Petrucci semibrevis head", "s0petrucci");
530 %       draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
531         draw_neomensural_open_head (staff_space#, 1.8 staff_space#);
532 fet_endchar;
533
534
535 fet_beginchar ("Petrucci minima head", "s1petrucci");
536 %       draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
537         draw_neomensural_open_head (staff_space#, 1.8 staff_space#);
538 fet_endchar;
539
540
541 fet_beginchar ("Petrucci semiminima head", "s2petrucci");
542 %       draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, false);
543         draw_neomensural_black_head (staff_space#, 1.8 staff_space#);
544 fet_endchar;
545
546
547 %%%%%%%%
548 %
549 %
550 %
551 % EDITIO VATICANA (including solesmes extensions)
552 %
553 %
554 %
555
556 % parameterized punctum
557 def punctum_char (expr verbose_name, internal_name,
558                        left_stem, right_stem, linea, cavum,
559                        straight, auctum, rev_auctum, d_up,
560                        eccentric, up_shift, down_shift, mag) =
561         fet_beginchar (verbose_name, "s" & internal_name);
562                 save a_b, b_h, a_w;
563
564                 a_b := 1.54; % b_h * a_b / a_w = wd / ht
565                 b_h := 0.85;
566                 a_w := 1.09;
567
568                 save a, beta, ht, wd;
569
570                 ht# = noteheight# * mag;
571                 2 beta# = ht# * b_h;
572                 a# = beta# * a_b;
573                 wd# = 2 a# / a_w;
574                 black_notehead_width# := wd#;
575
576                 % direction
577                 save d_, d_sign;
578                 pair d_;
579
580                 if d_up:
581                         d_ := up;
582                         d_sign# := 1;
583                 else:
584                         d_ := down;
585                         d_sign# := -1;
586                 fi;
587
588                 % convexity and eccentricity
589                 save u_convexity, u_eccentricity;
590
591                 if straight:
592                         u_convexity# := -0.01 ht#;
593                         u_eccentricity# := 0.0 ht#; % dummy
594                 elseif auctum:
595                         u_convexity# := -0.03 ht#;
596                         u_eccentricity# := +0.25 ht#;
597                 elseif rev_auctum:
598                         u_convexity# := -0.10 ht#;
599                         u_eccentricity# := -0.12 ht#;
600                 else:
601                         u_convexity# := -0.05 ht#;
602                         u_eccentricity# := 0.0 ht#; % dummy
603                 fi;
604
605                 save convexity, eccentricity;
606
607                 convexity# := d_sign# * u_convexity#;
608                 eccentricity# := d_sign# * u_eccentricity#;
609
610                 % y shift offset
611                 save yoffs;
612
613                 if up_shift:
614                         yoffs# := 0.08 ht#;
615                 elseif down_shift:
616                         yoffs# := -0.11 ht#;
617                 else:
618                         yoffs# := 0.00 ht#;
619                 fi;
620
621                 define_pixels (convexity, eccentricity, yoffs, ht, wd);
622
623                 pickup pencircle scaled linethickness;
624
625                 path p;
626                 save height, yoffs_bt;
627
628                 height# = 0.47 ht#;
629                 yoffs_bt# = yoffs# - 0.5 height# - 0.25 convexity#;
630
631                 define_pixels (height, yoffs_bt);
632
633                 x1 = x6;
634                 x2 = x5;
635                 x3 = x4;
636                 y1 + height = y6;
637                 y2 + height = y5;
638                 y3 + height = y4;
639
640                 save box_top, box_bt;
641
642                 if auctum or rev_auctum:
643                         z1 = (0.00 wd + linethickness / 2,
644                                yoffs_bt);
645                         z2 = (0.21 wd,
646                                yoffs_bt + 1.0 convexity);
647                         z3 = (0.42 wd - linethickness/ 2,
648                                yoffs_bt + 1.0 eccentricity);
649                         box_top# = height# + yoffs_bt# +
650                                 max (0, 1.0 convexity#, 1.0 eccentricity#);
651                         box_bt# = yoffs_bt# +
652                                 min (0, 1.0 convexity#, 1.0 eccentricity#);
653                         p = z1
654                             .. {right}z2
655                             .. {d_}z3
656                             -- z4{-d_}
657                             .. z5{left}
658                             .. z6
659                             -- cycle;
660                 elseif eccentric:
661                         z1 = (0.00 wd + linethickness / 2,
662                                yoffs_bt - 1.0 convexity);
663                         z2 = (0.08 wd,
664                                yoffs_bt + 1.4 convexity);
665                         z3 = (0.42 wd - linethickness / 2,
666                                yoffs_bt - 1.0 convexity);
667                         box_top# = height# + yoffs_bt# +
668                                 max (-1.0 convexity#, 1.4 convexity#, 0);
669                         box_bt# = yoffs_bt# +
670                                 min (-1.0 convexity#, 1.4 convexity#, 0);
671                         p = z1{d_}
672                             .. z2{right}
673                             .. z3
674                             -- z4
675                             .. {left}z5
676                             .. {-d_}z6
677                             -- cycle;
678                 else:
679                         z1 = (0.00 wd + linethickness / 2,
680                                yoffs_bt);
681                         z2 = (0.21 wd,
682                                yoffs_bt + 1.0 convexity);
683                         z3 = (0.42 wd - linethickness / 2,
684                                yoffs_bt);
685                         box_top# = height# + yoffs_bt# +
686                                 max (0, 1.0 convexity#);
687                         box_bt# = yoffs_bt# +
688                                 min (0, 1.0 convexity#);
689                         p = z1
690                             .. z2
691                             .. z3
692                             -- z4
693                             .. z5
694                             .. z6
695                             -- cycle;
696                 fi;
697
698                 labels (1, 2, 3, 4, 5, 6);
699
700                 if cavum:
701                         draw p;
702                 else:
703                         filldraw p;
704                 fi;
705
706                 pickup pencircle scaled 0.6 linethickness;
707
708                 save stem_bt;
709
710                 if left_stem:
711                         z11 = (0.00 wd + 0.6 linethickness / 2, yoffs);
712                         z12 = (0.00 wd + 0.6 linethickness / 2, yoffs - 1.1 ht);
713                         draw z11
714                              -- z12;
715                         stem_bt# = yoffs# - 1.1 ht#;
716                 elseif right_stem:
717                         z11 = (0.42 wd - 0.6 linethickness / 2, yoffs);
718                         z12 = (0.42 wd - 0.6 linethickness / 2, yoffs - 1.5 ht);
719                         draw z11
720                              -- z12;
721                         stem_bt# = yoffs# - 1.5 ht#;
722                 else:
723                         stem_bt# = 0;
724                 fi;
725
726                 set_char_box (0.00 wd#, 0.42 wd#,
727                               max (0, -box_bt#, -stem_bt#) + linethickness# / 2,
728                               max (0, box_top#) + linethickness# / 2);
729
730                 if linea:
731                         save linea_width, linea_height;
732
733                         linea_width# = 0.6 linethickness#;
734                         linea_height# = 0.7 ht#;
735
736                         define_pixels (linea_width, linea_height);
737
738                         draw_block ((-0.10 wd - linea_width / 2,
739                                      -linea_height / 2),
740                                     (-0.10 wd + linea_width / 2,
741                                      +linea_height / 2));
742                         draw_block ((+0.52 wd - linea_width / 2,
743                                      -linea_height / 2),
744                                     (+0.52 wd + linea_width / 2,
745                                      +linea_height / 2));
746
747                         set_char_box (0,
748                                       0.62 wd# + linea_width#,
749                                       linea_height# / 2,
750                                       linea_height# / 2);
751
752                         currentpicture := currentpicture
753                                 shifted (0.10 wd + linea_width / 2, 0);
754                 fi;
755         fet_endchar;
756 enddef;
757
758
759 % parameterized punctum inclinatum
760 def inclinatum_char (expr verbose_name, internal_name,
761                      small, stropha, auctum) =
762
763         fet_beginchar (verbose_name, "s" & internal_name)
764                 save ht, alpha;
765                 alpha# = 35;
766                 if small:
767                         ht# = 0.50 noteheight#;
768                 else:
769                         ht# = 0.80 noteheight#;
770                 fi;
771
772                 draw_diamond_head (ht#, 0, 0, alpha#, false);
773
774                 if stropha:
775                         pickup pencircle
776                                 xscaled (0.25*head_height)
777                                 yscaled (0.55*head_height)
778                                 rotated alpha#;
779                         save za, off_angle; pair za;
780                         off_angle := 15;
781                         za = (0, -0.25*head_height)
782                                 rotated -(alpha# + off_angle)
783                                 shifted (0.48 head_width, -0.02 head_width);
784                         undrawdot za;
785                 fi;
786
787                 if auctum:
788                         pickup pencircle scaled linethickness;
789                         save za, zb, zc;
790                         pair za, zb, zc;
791                         za = (0, -0.5 head_height + linethickness);
792                         zb = 0.6 (za + zc);
793                         zc = za + (0.52 head_width, 0);
794                         draw za{(0,-1) rotated alpha#} .. {right}zb{right} ..
795                              {(0,1) rotated -alpha#}zc;
796                 fi;
797         fet_endchar;
798 enddef;
799
800 % punctum
801 punctum_char ("Ed. Vat. punctum", "vaticana.punctum",
802               false, false, false, false, false,
803               false, false, false, false, false, false, 1.0);
804
805 % punctum cavum (for OpusTeX compatibility)
806 punctum_char ("Ed. Vat. punctum cavum", "vaticana.punctum.cavum",
807               false, false, false, true, false,
808               false, false, false, false, false, false, 1.0);
809
810 % linea punctum (for OpusTeX compatibility)
811 punctum_char ("Ed. Vat. linea punctum", "vaticana.linea.punctum",
812               false, false, true, false, false,
813               false, false, false, false, false, false, 1.0);
814
815 % linea punctum cavum (for OpusTeX compatibility)
816 punctum_char ("Ed. Vat. linea punctum cavum", "vaticana.linea.punctum.cavum",
817               false, false, true, true, false,
818               false, false, false, false, false, false, 1.0);
819
820 % punctum inclinatum
821 inclinatum_char ("Ed. Vat. inclinatum", "vaticana.inclinatum",
822                  false, false, false);
823
824 % pes lower punctum
825 punctum_char ("Ed. Vat. pes lower punctum", "vaticana.lpes",
826               false, false, false, false, true,
827               false, false, true, false, false, false, 1.0);
828
829 % pes lower punctum
830 punctum_char ("Ed. Vat. pes var lower punctum", "vaticana.vlpes",
831               false, false, false, false, true,
832               false, false, true, false, false, true, 1.0);
833
834 % pes upper punctum
835 punctum_char ("Ed. Vat. pes upper punctum", "vaticana.upes", 
836               false, false, false, false, true,
837               false, false, false, false, false, false, 1.0);
838
839 % pes upper punctum (shifted variation)
840 %
841 % This note head is used instead of the regular pes upper punctum to
842 % avoid collision with the lower punctum note of the pes when the upper
843 % punctum sits directly on top of the lower punctum.
844 %
845 punctum_char ("Ed. Vat. var pes upper punctum", "vaticana.vupes",
846               false, false, false, false, true,
847               false, false, false, false, true, false, 1.0);
848
849 % small punctum as used in epiphonus
850 punctum_char ("Ed. Vat. plica", "vaticana.plica", 
851               false, false, false, false, false,
852               false, false, false, false, false, false, 0.6);
853
854 % small punctum as used in epiphonus
855 punctum_char ("Ed. Vat. var plica", "vaticana.vplica", 
856               false, false, false, false, false,
857               false, true, false, false, false, true, 0.6);
858
859 % eccentric punctum as used in epiphonus
860 punctum_char ("Ed. Vat. epiphonus", "vaticana.epiphonus", 
861               false, false, false, false, false,
862               false, false, true, true, false, false, 1.0);
863
864 % eccentric punctum as used in epiphonus (shifted variation)
865 %
866 % This note head is used instead of the regular epiphonus punctum to
867 % avoid collision with the plica head when the plica sits directly on
868 % top of the lower head.
869 %
870 punctum_char ("Ed. Vat. var epiphonus", "vaticana.vepiphonus",
871               false, false, false, false, false,
872               false, false, true, true, false, true, 1.0);
873
874 % small punctum as used in cephalicus
875 punctum_char ("Ed. Vat. rev. plica", "vaticana.reverse.plica",
876               false, false, false, false, false,
877               false, false, true, false, false, false, 0.6);
878
879 % small punctum as used in cephalicus
880 punctum_char ("Ed. Vat. rev. var plica", "vaticana.reverse.vplica",
881               false, false, false, false, false,
882               false, true, true, false, false, true, 0.6);
883
884 % eccentric punctum as used in cephalicus; without left stem
885 punctum_char ("Ed. Vat. cephalicus", "vaticana.inner.cephalicus",
886               false, false, false, false, false,
887               false, false, false, true, false, false, 1.0);
888
889 % eccentric punctum as used in cephalicus; with left stem
890 punctum_char ("Ed. Vat. cephalicus", "vaticana.cephalicus",
891               true, false, false, false, false,
892               false, false, false, true, false, false, 1.0);
893
894 % quilisma
895 fet_beginchar ("Ed. Vat. quilisma", "svaticana.quilisma")
896         save a_b, b_h, a_w;
897
898         a_b:=1.54; % b_h*a_b/a_w = wd/ht
899         b_h:=0.85;
900         a_w:=1.09;
901
902         save a, beta, ht, wd;
903         ht# = noteheight#;
904         2 beta# = ht# * b_h;
905         a# = beta#*a_b;
906         wd# = 2 a# / a_w;
907         set_char_box (0, 0.42 wd#, 0.28 ht#, 0.36 ht#);
908         black_notehead_width# := wd#;
909
910         define_pixels (ht, wd);
911         pickup pencircle xscaled linethickness yscaled 0.44 ht;
912         lft x1 = 0.00 wd; bot y1 = -0.28 ht;
913         x2 = 0.11 wd;     y2 = -0.14 ht;
914         x3 = 0.12 wd;     y3 = +0.03 ht;
915         x4 = 0.25 wd;     y4 = -0.09 ht;
916         x5 = 0.26 wd;     y5 = +0.08 ht;
917         x6 = 0.40 wd;     y6 = -0.04 ht;
918         rt x7 = 0.42 wd;  top y7 = +0.36 ht;
919         draw z1 .. z2 -- z3 .. z4 -- z5 .. z6 -- z7;
920 fet_endchar;
921
922 % solesmes punctum inclinatum parvum
923 inclinatum_char ("Solesmes punctum inclinatum parvum", "solesmes.incl.parvum",
924                  true, false, false);
925
926 % solesmes punctum auctum ascendens
927 punctum_char ("Solesmes punctum auctum ascendens", "solesmes.auct.asc",
928               false, false, false, false, false,
929               true, false, true, false, false, false, 1.0);
930
931 % solesmes punctum auctum descendens
932 punctum_char ("Solesmes punctum auctum descendens", "solesmes.auct.desc",
933               false, false, false, false, false,
934               true, false, false, false, false, false, 1.0);
935
936 % solesmes punctum inclinatum auctum
937 inclinatum_char ("Solesmes punctum incl. auctum", "solesmes.incl.auctum",
938                  false, false, true);
939
940 % solesmes stropha
941 inclinatum_char ("Solesmes stropha", "solesmes.stropha",
942                  false, true, false);
943
944 % solesmes stropha aucta
945 inclinatum_char ("Solesmes stropha aucta", "solesmes.stropha.aucta",
946                  false, true, true);
947
948 % solesmes oriscus
949 fet_beginchar ("Solesmes oriscus", "ssolesmes.oriscus")
950         save a_b, b_h, a_w;
951
952         a_b := 1.54; % b_h*a_b/a_w = wd/ht
953         b_h := 0.85;
954         a_w := 1.09;
955
956         save a, beta, ht, wd;
957         ht# = noteheight#;
958         2 beta# = ht# * b_h;
959         a# = beta# * a_b;
960         wd# = 2 a# / a_w;
961         black_notehead_width# := wd#;
962
963         save convexity;
964         convexity# = +0.05 ht#;
965
966         define_pixels (ht, wd, convexity);
967         pickup pencircle xscaled blot_diameter yscaled 0.50 ht;
968         lft x1 = 0.00 wd; y1 = -convexity;
969         x2 = 0.16 wd;     y2 = +convexity;
970         x3 = 0.33 wd;     y3 = -convexity;
971         rt x4 = 0.50 wd;  y4 = +convexity;
972         draw z1 .. z2 .. z3 .. z4;
973         set_char_box (0.00 wd#, 0.50 wd#,
974                       0.25 ht# + convexity#, 0.25 ht# + convexity#);
975 fet_endchar;
976
977 %%%%%%%%
978 %
979 %
980 %
981 % EDITIO MEDICAEA
982 %
983 %
984 %
985
986 % inclinatum
987 fet_beginchar ("Ed. Med. inclinatum", "smedicaea.inclinatum")
988         draw_diamond_head (1.2 staff_space#, 0, 0, 35, false);
989 fet_endchar;
990
991
992 % parametrized punctum
993 def punctum_char (expr verbose_name, internal_name,
994                        left_up_stem, left_down_stem) =
995         fet_beginchar (verbose_name, "s" & internal_name);
996                 save a, beta, ht, wd;
997
998                 ht# = 2 staff_space#;
999                 wd# = ht#;
1000                 black_notehead_width# := wd#;
1001
1002                 define_pixels (ht, wd);
1003
1004                 pickup pencircle xscaled blot_diameter
1005                                  yscaled 0.50 ht;
1006
1007                 z1 = (0.00 wd + blot_diameter / 2, 0);
1008                 z2 = (0.4 wd - blot_diameter / 2, 0);
1009
1010                 draw z1
1011                      .. z2;
1012
1013                 pickup pencircle xscaled linethickness
1014                                  yscaled blot_diameter;
1015
1016                 if left_down_stem:
1017                         z4 = (0.00 wd + linethickness / 2, blot_diameter / 2);
1018                         z5 = (0.00 wd + linethickness / 2, -1.25 ht);
1019
1020                         draw z4
1021                              .. z5;
1022                         set_char_box (0.0, 0.4 wd#, 1.25 ht#, 0.25 ht#);
1023                 elseif left_up_stem:
1024                         z4 = (0.00 wd + linethickness / 2, blot_diameter / 2);
1025                         z5 = (0.00 wd + linethickness / 2, +1.25 ht);
1026
1027                         draw z4
1028                              .. z5;
1029                         set_char_box (0.0, 0.4 wd#, 0.25 ht#, 1.25 ht#);
1030                 else:
1031                         set_char_box (0.0, 0.4 wd#, 0.25 ht#, 0.25 ht#);
1032                 fi;
1033
1034         fet_endchar;
1035 enddef;
1036
1037
1038 % punctum
1039 punctum_char ("Ed. Med. punctum", "medicaea.punctum", 
1040               false, false);
1041
1042
1043 % left up-stemmed punctum
1044 punctum_char ("Ed. Med. reverse virga", "medicaea.rvirga",
1045               true, false);
1046
1047
1048 % virga (i.e. left down-stemmed punctum)
1049 punctum_char ("Ed. Med. virga", "medicaea.virga", 
1050               false, true);
1051
1052 %%%%%%%%
1053 %
1054 %
1055 %
1056 % HUFNAGEL
1057 %
1058 %
1059 %
1060
1061 % punctum
1062 % parametrized punctum
1063 def punctum_char (expr verbose_name, internal_name,
1064                        down_stem) =
1065         fet_beginchar (verbose_name, "s" & internal_name);
1066                 save alpha;
1067
1068                 alpha# = 55;
1069                 draw_diamond_head (staff_space#, 0, 0, alpha#, false);
1070                 if down_stem:
1071                         pickup pencircle xscaled blot_diameter
1072                                          yscaled 0.7 staff_space
1073                                          rotated -alpha#;
1074
1075                         save za, zb;
1076                         pair za, zb;
1077
1078                         za = (head_width / 2, 0);
1079                         bot zb = (head_width / 2, -1.5 staff_space);
1080
1081                         draw za
1082                              -- zb;
1083                         set_char_box (0, head_width#,
1084                                       1.5 staff_space#, head_height# / 2);
1085                 fi;
1086         fet_endchar;
1087 enddef;
1088
1089 % punctum
1090 punctum_char ("Hufnagel punctum", "hufnagel.punctum", false)
1091
1092 % virga
1093 punctum_char ("Hufnagel virga", "hufnagel.virga",  true)
1094
1095 % pes lower punctum
1096 fet_beginchar ("Hufnagel pes lower punctum", "shufnagel.lpes")
1097         save width, height, alpha;
1098         width# = 2*staff_space#;
1099         height# = 0.7*staff_space#;
1100         alpha# = 35;
1101
1102         set_char_box (0, width#, height#/2, height#/2);
1103
1104         pickup pencircle scaled linethickness;
1105         define_pixels (width, height);
1106
1107         rt x3 = -lft x1 = width/2;
1108         y2 = y3 = height/2;
1109         y1 = y4 = -height/2;
1110         tand (alpha#) * (y2 - y1) = x2 - x1 = x3 - x4;
1111
1112         filldraw z1 -- z2 -- z3 -- z4 -- cycle;
1113
1114         currentpicture := currentpicture shifted (width/2, 0);
1115 fet_endchar;
1116
1117 fet_endgroup ("noteheads")