]> git.donarmstrong.com Git - lilypond.git/blob - mf/parmesan-heads.mf
* input/regression/new-markup-scheme.ly: oops. font-family=music
[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--2004 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
62         define_pixels(head_width);
63         set_char_box(0, head_width#, noteheight#/2, noteheight#/2);
64         
65         2 beamheight + holeheight = noteheight;
66         serif_size = (holeheight - stafflinethickness)/2;
67         serif_protrude = 1.5 serif_size;
68         penpos1(stem_width, 0);
69         penpos2(stem_width, 0);
70         penpos3(beamheight, 90);
71         penpos4(beamheight, 90);
72         penpos5(stem_width, 180);
73
74         z1l = (0, 0);
75         z2l = (0, -stafflinethickness/2);
76         z3r = z2r + serif_size *(1,-1);
77         y4r = y3r;
78         x4r = head_width/2;
79         z5l = z3l + (-serif_size, -serif_protrude);
80
81         penlabels(1,2,3,4, 5);
82         fill z1r -- z1l -- z5r{down} .. z5l{up} .. z3l{right}
83                 -- z4l -- z4r -- z3r{left} .. z2r{up} -- cycle;
84
85         addto currentpicture also currentpicture yscaled -1;
86         addto currentpicture also currentpicture 
87                 shifted (-x4r,0) xscaled -1 shifted (x4l,0);
88
89 enddef;
90
91
92 def draw_neomensural_left_stemmed_head (expr wid) =
93         draw_neomensural_brevis(wid);
94
95         x6 = x7 = stem_width/2;
96         y6 = y5;
97         y7 = y5 - 2.25 staff_space;
98         pickup pencircle scaled stem_width;
99         draw z6 .. z7;
100 enddef;
101
102 fet_beginchar("Left stemmed notehead", "lneomensural");
103         draw_neomensural_left_stemmed_head (2 staff_space#);
104 fet_endchar;
105
106 %
107 % Some sources (eg Musix/OpusTeX think that the appendage should be on
108 % the left, some say right. Right wins democratically.
109 %
110 def draw_neomensural_longa (expr wid) =
111         draw_neomensural_brevis(wid);
112         save theta;
113
114         x7r = head_width;
115         y7 = y5;
116 %       z7 = z5;
117         z6 - z7 = (stem_width/2, -staff_space);
118         theta = angle(z6-z7)+ 90;
119         penpos7(stem_width, theta);
120         penpos6(1.2 stem_width, theta);
121         
122         fill z7r .. z6r{z6-z7} .. {z7-z6} z6l -- z7l -- cycle;
123         penlabels(6,7);
124 enddef;
125
126 %
127 % En wij presenteren U: de opvolgster van Emily
128 %
129 % (ze is wel breed)
130
131 fet_beginchar("Neo-mensural maxima notehead", "s-3neomensural");
132         draw_neomensural_longa (2.6 staff_space#)
133 fet_endchar;
134
135 fet_beginchar("Neo-mensural longa notehead", "s-2neomensural");
136         draw_neomensural_longa (2 staff_space#)
137 fet_endchar;
138
139 fet_beginchar("Neo-mensural brevis notehead", "s-1neomensural")
140         draw_neomensural_brevis(2 staff_space#);
141 fet_endchar;
142
143 def draw_neomensural_black_head (expr wid, height) =
144         save head_width;
145         head_width# = wid;
146         set_char_box (0, head_width#, height/2, height/2);
147         
148         charwx := head_width# / 2;
149         charwy := height / 2;
150
151         y3 = y1 =0;
152         x2 = x4 = (x1 + x3) /2;
153         define_pixels (head_width);
154         pickup pencircle scaled blot_diameter;
155         top y2 = h;
156         bot y4 = -d;
157         lft x1 = 0;
158         rt x3 = w;
159
160         filldraw z1 -- z2 -- z3 -- z4 -- cycle;
161 enddef;
162
163 def draw_neomensural_open_head (expr wid, height)=
164         draw_neomensural_black_head (wid, height);
165         save diamNW, diamSW;
166         diamNW = length (z2 - z1) + blot_diameter;
167         diamSW = length (z4 - z1) + blot_diameter;
168         
169         save hole_widthNW, hole_widthSW;
170         hole_widthNW = 0.34 diamNW ;
171         hole_widthSW + 2.6 linethickness = diamSW;
172
173         (z7 + z5)/2 = (w/2, 0);
174         (z8 + z6)/2 = (w/2, 0);
175         (z6 - z5) = hole_widthNW * unitvector (z2 - z1);
176         (z7 - z6) = hole_widthSW * unitvector (z4 - z1);
177
178         labels (1,2,3,4,5,6,7,8);
179
180         unfill z5 -- z6 -- z7 -- z8 --cycle;
181 enddef;
182
183 fet_beginchar("Neo-mensural open head","s0neomensural")
184       draw_neomensural_open_head (staff_space#, noteheight#);
185 fet_endchar;
186
187 %
188 % WL says the thin lines should be thinner.
189 %
190
191 fet_beginchar("Harmonic notehead (Neo-mensural open)",
192                 "0harmonic")
193
194         draw_neomensural_open_head (1.3 staff_space#, 1.3 noteheight#);
195         charwx := head_width#;
196         charwy := 0;
197 fet_endchar;
198
199
200 fet_beginchar("Neo-mensural open head","s1neomensural")
201       draw_neomensural_open_head (staff_space#, noteheight#);
202 fet_endchar;
203
204 fet_beginchar("Neo-mensural black head","s2neomensural")
205       draw_neomensural_black_head (staff_space#, noteheight#);
206 fet_endchar;
207
208
209
210 def draw_mensural_brevis (expr wid) =
211         % TODO.  For the moment, fall back to draw_neomensural_brevis.
212         draw_neomensural_brevis(wid);
213 enddef;
214
215 def draw_mensural_left_stemmed_head (expr wid) =
216         draw_mensural_brevis(wid);
217         x6 = x7 = stem_width/2;
218         y6 = y5;
219         y7 = y5 - 2.25staff_space;
220         pickup pencircle scaled stem_width;
221         draw z6 .. z7;
222 enddef;
223
224 def draw_mensural_longa (expr wid) =
225         draw_mensural_brevis(wid);
226         x6 = x7 = head_width - stem_width/2;
227         y6 = y5;
228         y7 = y5 - 2.25staff_space;
229         pickup pencircle scaled stem_width;
230         draw z6 .. z7;
231 enddef;
232
233 fet_beginchar("Mensural left stemmed notehead", "slmensural");
234         draw_mensural_left_stemmed_head (staff_space#)
235 fet_endchar;
236
237 fet_beginchar("Mensural maxima notehead", "s-3mensural");
238         draw_mensural_longa (2.0 staff_space#)
239 fet_endchar;
240
241 fet_beginchar("Mensural longa notehead", "s-2mensural");
242         draw_mensural_longa (staff_space#)
243 fet_endchar;
244
245 fet_beginchar("Mensural brevis notehead", "s-1mensural")
246         draw_mensural_brevis(staff_space#);
247 fet_endchar;
248
249 def draw_diamond_head (expr head_h, pen_w, pen_h, angle, open) =
250       save head_width, head_height;
251       head_height# = head_h;
252       head_width# / head_height# = tand(angle);
253
254       set_char_box (0, head_width#,
255         head_height#/2, head_height#/2);
256       
257       charwx := head_width# / 2;
258       charwy := head_height# / 2 - linethickness#;
259
260       define_pixels(head_width, head_height);
261       pickup pencircle
262              xscaled (max(blot_diameter, pen_w * head_width))
263              yscaled (max(blot_diameter, pen_h * head_width))
264              rotated -angle;
265
266       %% FIXME: replace "xpart (top z2)" (and, analogously,
267       %% "ypart (rt z3)") with an expression that really delivers the
268       %% x coordinate of the uppermost pixel that is drawn with respect
269       %% to the pencircle (this requires some elliptical computations).
270       %% MF obviously interprets "xpart (top z2)" as "top (xpart z2)",
271       %% i.e. "top x2", which is not what we want.
272
273       xpart (top z2) = ypart (rt z3) = 0;
274       top y2 = head_height/2;
275       rt x3 = head_width/2;
276       z2 = - z4;
277       z3 = - z1;
278
279       if open:
280               draw z1 -- z2 -- z3 -- z4 -- cycle;
281       else:
282               filldraw z1 -- z2 -- z3 -- z4 -- cycle;
283       fi;
284
285       currentpicture := currentpicture shifted (head_width/2, 0);
286
287 enddef;
288
289
290 fet_beginchar("Mensural open head","s0mensural")
291         draw_diamond_head (staff_space#, 0.15, 0.30, 30, true);
292 fet_endchar;
293
294 fet_beginchar("Mensural open head","s1mensural")
295         draw_diamond_head (staff_space#, 0.15, 0.30, 30, true);
296 fet_endchar;
297
298 fet_beginchar("Mensural black head","s2mensural")
299         draw_diamond_head (staff_space#, 0.15, 0.30, 30, false);
300 fet_endchar;
301
302
303 %%%%%%%%
304 %
305 %
306 %
307 % EDITIO VATICANA (including solesmes extensions)
308 %
309 %
310 %
311
312 % parameterized punctum
313 def punctum_char (expr verbose_name, internal_name,
314                   left_stem, right_stem, linea, cavum,
315                   straight, auctum, direction_up, excentric, up_shift, down_shift, mag) =
316
317         fet_beginchar(verbose_name, "s" & internal_name)
318                 save b_h, a_w;
319                 a_b := 1.54; % b_h*a_b/a_w = wd/ht
320                 b_h := 0.85;
321                 a_w := 1.09;
322
323                 save a, beta, ht, wd;
324                 ht# = noteheight# * mag;
325                 2beta# = ht# * b_h;
326                 a# = beta# * a_b;
327                 wd# = 2a# / a_w;
328                 black_notehead_width# := wd#;
329
330                 % direction
331                 save direction, direction_sign;
332                 pair direction;
333                 if direction_up:
334                         direction = up;
335                         direction_sign# = 1;
336                 else:
337                         direction = down;
338                         direction_sign# = -1;
339                 fi;
340
341                 % convexity and excentricity
342                 save u_convexity, u_excentricity;
343                 if straight:
344                         u_convexity# = -0.01ht#;
345                         u_excentricity# = 0.0ht#; % dummy
346                 elseif auctum:
347                         u_convexity# = -0.03ht#;
348                         u_excentricity# = +0.25ht#;
349                 else:
350                         u_convexity# = -0.05ht#;
351                         u_excentricity# = 0.0ht#; % dummy
352                 fi;
353                 save convexity, excentricity;
354                 convexity# = direction_sign# * u_convexity#;
355                 excentricity# = direction_sign# * u_excentricity#;
356
357                 % y shift offset
358                 save yoffs;
359                 if up_shift:
360                         yoffs# = 0.08ht#;
361                 elseif down_shift:
362                         yoffs# = -0.11ht#;
363                 else:
364                         yoffs# = 0.00ht#;
365                 fi
366
367                 define_pixels(convexity, excentricity, yoffs, ht, wd);
368                 pickup pencircle scaled linethickness;
369
370                 path p;
371                 save height, yoffs_bt;
372                 define_pixels (height, yoffs_bt);
373                 height# = 0.47ht#;
374                 yoffs_bt# = yoffs# - 0.5*height# - 0.25*convexity#;
375                 xpart z1a = xpart z1b;
376                 xpart z2a = xpart z2b;
377                 xpart z3a = xpart z3b;
378                 ypart z1a + height = ypart z1b;
379                 ypart z2a + height = ypart z2b;
380                 ypart z3a + height = ypart z3b;
381
382                 save box_top, box_bt;
383
384                 if auctum:
385                         z1a = (0.00wd + linethickness/2, yoffs_bt);
386                         z2a = (0.21wd, yoffs_bt + 1.0*convexity);
387                         z3a = (0.42wd - linethickness/2,
388                                yoffs_bt + 1.0*excentricity);
389                         box_top# = height# + yoffs_bt# +
390                                 max(0, 1.0*convexity#, 1.0*excentricity#);
391                         box_bt# = yoffs_bt# +
392                                 min(0, 1.0*convexity#, 1.0*excentricity#);
393                         p = z1a .. {right}z2a .. {direction}z3a --
394                             z3b{-direction} .. z2b{left} .. z1b -- cycle;
395                 elseif excentric:
396                         z1a = (0.00wd + linethickness/2,
397                                yoffs_bt - 1.0*convexity);
398                         z2a = (0.08wd, yoffs_bt + 1.4*convexity);
399                         z3a = (0.42wd - linethickness/2,
400                                yoffs_bt - 1.0*convexity);
401                         box_top# = height# + yoffs_bt# +
402                                 max(-1.0*convexity#, 1.4*convexity#, 0);
403                         box_bt# = yoffs_bt# +
404                                 min(-1.0*convexity#, 1.4*convexity#, 0);
405                         p = z1a{direction} .. z2a{right} .. z3a --
406                             z3b .. {left}z2b .. {-direction}z1b -- cycle;
407                 else:
408                         z1a = (0.00wd + linethickness/2, yoffs_bt);
409                         z2a = (0.21wd, yoffs_bt + 1.0*convexity);
410                         z3a = (0.42wd - linethickness/2, yoffs_bt);
411                         box_top# = height# + yoffs_bt# +
412                                 max(0, 1.0*convexity#);
413                         box_bt# = yoffs_bt# +
414                                 min(0, 1.0*convexity#);
415                         p = z1a .. z2a .. z3a --
416                             z3b .. z2b .. z1b -- cycle;
417                 fi;
418
419                 if cavum:
420                         draw p;
421                 else:
422                         filldraw p;
423                 fi;
424
425                 pickup pencircle scaled 0.6linethickness;
426
427                 save stem_bt;
428
429                 if left_stem:
430                         z5=(0.00wd + 0.6linethickness/2, yoffs);
431                         z6=(0.00wd + 0.6linethickness/2, yoffs - 1.1ht);
432                         draw z5 -- z6;
433                         stem_bt# = yoffs# - 1.1ht#;
434                 elseif right_stem:
435                         z5=(0.42wd - 0.6linethickness/2, yoffs);
436                         z6=(0.42wd - 0.6linethickness/2, yoffs - 1.5ht);
437                         draw z5 -- z6;
438                         stem_bt# = yoffs# - 1.5ht#;
439                 else:
440                         stem_bt# = 0;
441                 fi;
442
443                 set_char_box(0.00wd#, 0.42wd#,
444                              max(0, -box_bt#, -stem_bt#) + linethickness#/2,
445                              max(0, box_top#) + linethickness#/2);
446
447                 if linea:
448                         save linea_width, linea_height;
449                         linea_width# = 0.6 linethickness#;
450                         linea_height# = 0.7 ht#;
451                         define_pixels (linea_width, linea_height);
452                         draw_block ((-0.10wd - linea_width/2,
453                                      -linea_height/2),
454                                     (-0.10wd + linea_width/2,
455                                      +linea_height/2));
456                         draw_block ((+0.52wd - linea_width/2,
457                                      -linea_height/2),
458                                     (+0.52wd + linea_width/2,
459                                      +linea_height/2));
460                         set_char_box(0,
461                                      0.62wd# + linea_width#,
462                                      linea_height#/2,
463                                      linea_height#/2);
464                         currentpicture := currentpicture
465                                 shifted (0.10wd + linea_width/2, 0);
466                 fi;
467         fet_endchar;
468 enddef;
469
470 % parameterized punctum inclinatum
471 def inclinatum_char(expr verbose_name, internal_name,
472                     small, stropha, auctum) =
473
474         fet_beginchar(verbose_name, "s"&internal_name)
475                 save ht, alpha;
476                 alpha# = 35;
477                 if small:
478                         ht# = 0.50 noteheight#;
479                 else:
480                         ht# = 0.80 noteheight#;
481                 fi;
482
483                 draw_diamond_head (ht#, 0, 0, alpha#, false);
484
485                 if stropha:
486                         pickup pencircle
487                                 xscaled (0.25*head_height)
488                                 yscaled (0.55*head_height)
489                                 rotated alpha#;
490                         save za, off_angle; pair za;
491                         off_angle := 15;
492                         za = (0, -0.25*head_height)
493                                 rotated -(alpha# + off_angle)
494                                 shifted (0.48 head_width, -0.02 head_width);
495                         undraw za;
496                 fi;
497
498                 if auctum:
499                         pickup pencircle scaled linethickness;
500                         save za, zb, zc;
501                         pair za, zb, zc;
502                         za = (0, -0.5 head_height + linethickness);
503                         zb = 0.6 (za + zc);
504                         zc = za + (0.52 head_width, 0);
505                         draw za{(0,-1) rotated alpha#} .. {right}zb{right} ..
506                              {(0,1) rotated -alpha#}zc;
507                 fi;
508         fet_endchar;
509 enddef;
510
511 % punctum
512 punctum_char("Ed. Vat. punctum", "vaticana.punctum",
513              false, false, false, false, false,
514              false, false, false, false, false, 1.0);
515
516 % punctum cavum (for OpusTeX compatibility)
517 punctum_char("Ed. Vat. punctum cavum", "vaticana.punctum.cavum",
518              false, false, false, true, false,
519              false, false, false, false, false, 1.0);
520
521 % linea punctum (for OpusTeX compatibility)
522 punctum_char("Ed. Vat. linea punctum", "vaticana.linea.punctum",
523              false, false, true, false, false,
524              false, false, false, false, false, 1.0);
525
526 % linea punctum cavum (for OpusTeX compatibility)
527 punctum_char("Ed. Vat. linea punctum cavum", "vaticana.linea.punctum.cavum",
528              false, false, true, true, false,
529              false, false, false, false, false, 1.0);
530
531 % punctum inclinatum
532 inclinatum_char("Ed. Vat. inclinatum", "vaticana.inclinatum",
533                 false, false, false);
534
535 % pes lower punctum
536 punctum_char("Ed. Vat. pes lower punctum", "vaticana.lpes",
537              false, false, false, false, true,
538              false, true, false, false, false, 1.0);
539
540 % pes lower punctum
541 punctum_char("Ed. Vat. pes var lower punctum", "vaticana.vlpes",
542              false, false, false, false, true,
543              false, true, false, false, true, 1.0);
544
545 % pes upper punctum
546 punctum_char("Ed. Vat. pes upper punctum", "vaticana.upes", 
547              false, false, false, false, true,
548              false, false, false, false, false, 1.0);
549
550 % pes upper punctum (shifted variation)
551 %
552 % This note head is used instead of the regular pes upper punctum to
553 % avoid collision with the lower punctum note of the pes when the upper
554 % punctum sits directly on top of the lower punctum.
555 %
556 punctum_char("Ed. Vat. var pes upper punctum", "vaticana.vupes",
557              false, false, false, false, true,
558              false, false, false, true, false, 1.0);
559
560 % small punctum as used in epiphonus
561 punctum_char("Ed. Vat. plica", "vaticana.plica", 
562              false, false, false, false, false,
563              false, false, false, false, false, 0.6);
564
565 % excentric punctum as used in epiphonus
566 punctum_char("Ed. Vat. epiphonus", "vaticana.epiphonus", 
567              false, false, false, false, false,
568              false, true, true, false, false, 1.0);
569
570 % excentric punctum as used in epiphonus (shifted variation)
571 %
572 % This note head is used instead of the regular epiphonus punctum to
573 % avoid collision with the plica head when the plica sits directly on
574 % top of the lower head.
575 %
576 punctum_char("Ed. Vat. var epiphonus", "vaticana.vepiphonus",
577              false, false, false, false, false,
578              false, true, true, false, true, 1.0);
579
580 % small punctum as used in cephalicus
581 punctum_char("Ed. Vat. rev. plica", "vaticana.reverse.plica",
582              false, false, false, false, false,
583              false, true, false, false, false, 0.6);
584
585 % excentric punctum as used in cephalicus; without left stem
586 punctum_char("Ed. Vat. cephalicus", "vaticana.inner.cephalicus",
587              false, false, false, false, false,
588              false, false, true, false, false, 1.0);
589
590 % excentric punctum as used in cephalicus; with left stem
591 punctum_char("Ed. Vat. cephalicus", "vaticana.cephalicus",
592              true, false, false, false, false,
593              false, false, true, false, false, 1.0);
594
595 % quilisma
596 fet_beginchar("Ed. Vat. quilisma", "svaticana.quilisma")
597         save b_h,a_w;
598         a_b:=1.54; % b_h*a_b/a_w = wd/ht
599         b_h:=0.85;
600         a_w:=1.09;
601
602         save a, beta, ht, wd;
603         ht# = noteheight#;
604         2beta# = ht#*b_h;
605         a# = beta#*a_b;
606         wd# = 2a# / a_w;
607         set_char_box(0, 0.42wd#, 0.28 ht#, 0.36 ht#);
608         black_notehead_width# := wd#;
609
610         define_pixels(ht, wd);
611         pickup pencircle xscaled linethickness yscaled 0.44ht;
612         lft x1 = 0.00wd; bot y1 = -0.28ht;
613         x2 = 0.11wd;     y2 = -0.14ht;
614         x3 = 0.12wd;     y3 = +0.03ht;
615         x4 = 0.25wd;     y4 = -0.09ht;
616         x5 = 0.26wd;     y5 = +0.08ht;
617         x6 = 0.40wd;     y6 = -0.04ht;
618         rt x7 = 0.42wd;  top y7 = +0.36ht;
619         draw z1 .. z2 -- z3 .. z4 -- z5 .. z6 -- z7;
620 fet_endchar;
621
622 % solesmes punctum inclinatum parvum
623 inclinatum_char("Solesmes punctum inclinatum parvum", "solesmes.incl.parvum",
624                 true, false, false);
625
626 % solesmes punctum auctum ascendens
627 punctum_char("Solesmes punctum auctum ascendens", "solesmes.auct.asc",
628              false, false, false, false, false,
629              true, true, false, false, false, 1.0);
630
631 % solesmes punctum auctum descendens
632 punctum_char("Solesmes punctum auctum descendens", "solesmes.auct.desc",
633              false, false, false, false, false,
634              true, false, false, false, false, 1.0);
635
636 % solesmes punctum inclinatum auctum
637 inclinatum_char("Solesmes punctum incl. auctum", "solesmes.incl.auctum",
638                 false, false, true);
639
640 % solesmes stropha
641 inclinatum_char("Solesmes stropha", "solesmes.stropha",
642                 false, true, false);
643
644 % solesmes stropha aucta
645 inclinatum_char("Solesmes stropha aucta", "solesmes.stropha.aucta",
646                 false, true, true);
647
648 % solesmes oriscus
649 fet_beginchar("Solesmes oriscus", "ssolesmes.oriscus")
650         save b_h, a_w;
651         a_b := 1.54; % b_h*a_b/a_w = wd/ht
652         b_h := 0.85;
653         a_w := 1.09;
654
655         save a, beta, ht, wd;
656         ht# = noteheight#;
657         2beta# = ht# * b_h;
658         a# = beta# * a_b;
659         wd# = 2a# / a_w;
660         black_notehead_width# := wd#;
661
662         save convexity;
663         convexity# = +0.05ht#;
664
665         define_pixels(ht, wd, convexity);
666         pickup pencircle xscaled blot_diameter yscaled 0.50ht;
667         lft x1 = 0.00wd; y1 = -convexity;
668         x2 = 0.16wd;     y2 = +convexity;
669         x3 = 0.33wd;     y3 = -convexity;
670         rt x4 = 0.50wd;  y4 = +convexity;
671         draw z1 .. z2 .. z3 .. z4;
672         set_char_box(0.00wd#, 0.50wd#,
673                      0.25ht# + convexity#, 0.25ht# + convexity#);
674 fet_endchar;
675
676 %%%%%%%%
677 %
678 %
679 %
680 % EDITIO MEDICAEA
681 %
682 %
683 %
684
685 % inclinatum
686 fet_beginchar("Ed. Med. inclinatum", "smedicaea.inclinatum")
687         draw_diamond_head (1.2staff_space#, 0, 0, 35, false);
688 fet_endchar;
689
690 % parametrized punctum
691 def punctum_char (expr verbose_name, internal_name,
692         left_up_stem, left_down_stem) =
693
694         fet_beginchar(verbose_name, "s"&internal_name)
695
696                 save a, beta, ht, wd;
697                 ht# = 2 staff_space#;
698                 wd# = ht#;
699                 black_notehead_width# := wd#;
700
701                 define_pixels(ht, wd);
702                 pickup pencircle
703                         xscaled blot_diameter
704                         yscaled 0.50ht;
705                 z1 = (0.00wd + blot_diameter/2, 0);
706                 z2 = (0.4wd - blot_diameter/2, 0);
707                 draw z1 .. z2;
708
709                 pickup pencircle
710                         xscaled linethickness
711                         yscaled blot_diameter;
712
713                 if left_down_stem:
714                         z4=(0.00wd + linethickness/2, blot_diameter/2);
715                         z5=(0.00wd + linethickness/2, - 1.25ht);
716                         draw z4 .. z5;
717                         set_char_box(0.0, 0.4wd#, 1.25ht#, 0.25ht#);
718                 elseif left_up_stem:
719                         z4=(0.00wd + linethickness/2, blot_diameter/2);
720                         z5=(0.00wd + linethickness/2, + 1.25ht);
721                         draw z4 .. z5;
722                         set_char_box(0.0, 0.4wd#, 0.25ht#, 1.25ht#);
723                 else:
724                         set_char_box(0.0, 0.4wd#, 0.25ht#, 0.25ht#);
725                 fi;
726
727         fet_endchar;
728 enddef;
729
730 % punctum
731 punctum_char("Ed. Med. punctum", "medicaea.punctum", 
732         false, false);
733
734 % left up-stemmed punctum
735 punctum_char("Ed. Med. reverse virga", "medicaea.rvirga",
736         true, false);
737
738 % virga (i.e. left down-stemmed punctum)
739 punctum_char("Ed. Med. virga", "medicaea.virga", 
740         false, true);
741
742 %%%%%%%%
743 %
744 %
745 %
746 % HUFNAGEL
747 %
748 %
749 %
750
751 % punctum
752 % parametrized punctum
753 def punctum_char (expr verbose_name, internal_name,
754         down_stem) =
755         fet_beginchar(verbose_name, "s" & internal_name)
756                 save alpha;
757                 alpha# = 55;
758                 draw_diamond_head (staff_space#, 0, 0, alpha#, false);
759                 if down_stem:
760                         pickup pencircle
761                                 xscaled blot_diameter
762                                 yscaled (0.7*staff_space)
763                                 rotated -alpha#;
764                         save za, zb; pair za, zb;
765                         za = (head_width/2, 0);
766                         bot zb = (head_width/2, -1.5staff_space);
767                         draw za -- zb;
768                         set_char_box (0, head_width#,
769                                       1.5staff_space#, head_height#/2);
770                 fi;
771         fet_endchar;
772 enddef;
773
774 % punctum
775 punctum_char("Hufnagel punctum", "hufnagel.punctum", false)
776
777 % virga
778 punctum_char("Hufnagel virga", "hufnagel.virga",  true)
779
780 % pes lower punctum
781 fet_beginchar("Hufnagel pes lower punctum", "shufnagel.lpes")
782         save width, height, alpha;
783         width# = 2*staff_space#;
784         height# = 0.7*staff_space#;
785         alpha# = 35;
786
787         set_char_box(0, width#, height#/2, height#/2);
788
789         pickup pencircle scaled linethickness;
790         define_pixels(width, height);
791
792         rt x3 = -lft x1 = width/2;
793         y2 = y3 = height/2;
794         y1 = y4 = -height/2;
795         tand(alpha#) * (y2 - y1) = x2 - x1 = x3 - x4;
796
797         filldraw z1 -- z2 -- z3 -- z4 -- cycle;
798
799         currentpicture := currentpicture shifted (width/2, 0);
800 fet_endchar;
801
802 fet_endgroup ("noteheads")