]> git.donarmstrong.com Git - lilypond.git/blob - mf/parmesan-heads.mf
b69c378ffce6e04be36034b6ab12bc6466b8188d
[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--2007 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 % Some sources (eg. Musix/OpusTeX) think that the appendage should be on
150 % the left, some say right.  Right wins democratically.
151 %
152 def draw_neomensural_longa (expr wid) =
153         draw_neomensural_brevis (wid);
154
155         save theta;
156
157         x7r = head_width;
158         y7 = y5;
159         z6 - z7 = (stem_width / 2, -staff_space);
160         theta = angle (z6 - z7) + 90;
161
162         penpos7 (stem_width, 0);
163         penpos6 (1.2 stem_width, theta);
164         
165         z7' = find_tangent (z6l, pat_out,
166                             (x7l + 0.5 stem_width, y7l),
167                             (x7l - 0.5 stem_width, y7l));
168
169         fill z7r
170              .. z6r{z6 - z7}
171              .. {z7 - z6}z6l
172              -- z7'
173              -- cycle;
174
175         penlabels (6, 7);
176         labels (7');
177 enddef;
178
179
180 %
181 % En wij presenteren U: de opvolgster van Emily
182 %
183 % (ze is wel breed)
184
185 fet_beginchar ("Neo-mensural maxima notehead", "sM3neomensural");
186         draw_neomensural_longa (2.6 staff_space#);
187 fet_endchar;
188
189
190 fet_beginchar ("Neo-mensural longa notehead", "sM2neomensural");
191         draw_neomensural_longa (2 staff_space#);
192 fet_endchar;
193
194
195 fet_beginchar ("Neo-mensural brevis notehead", "sM1neomensural");
196         draw_neomensural_brevis (2 staff_space#);
197 fet_endchar;
198
199
200 def draw_neomensural_black_head (expr wid, height) =
201         save head_width;
202         save ne, nw, ne_dist, nw_dist;
203         pair ne, nw, ne_dist, nw_dist;
204
205         head_width# = wid;
206
207         set_char_box (0, head_width#,
208                       height / 2, height / 2);
209         
210         charwx := head_width# / 2;
211         charwy := height / 2;
212
213         y3 = y1 = 0;
214         x2 = x4 = (x1 + x3) / 2;
215
216         pickup pencircle scaled blot_diameter;
217
218         top y2 = h;
219         bot y4 = -d;
220         lft x1 = 0;
221         rt x3 = w;
222
223         ne := unitvector (z2 - z1);
224         nw_dist := (ne rotated 90) * 0.5 blot_diameter;
225         nw := unitvector (z2 - z3);
226         ne_dist := (nw rotated -90) * 0.5 blot_diameter;
227
228         fill lft z1{up}
229              .. (z1 + nw_dist){ne}
230              -- (z2 + nw_dist){ne}
231              .. top z2{right}
232              .. (z2 + ne_dist){-nw}
233              -- (z3 + ne_dist){-nw}
234              .. rt z3{down}
235              .. (z3 - nw_dist){-ne}
236              -- (z4 - nw_dist){-ne}
237              .. bot z4{left}
238              .. (z4 - ne_dist){nw}
239              -- (z1 - ne_dist){nw}
240              .. cycle;
241
242         labels (1, 2, 3, 4);
243 enddef;
244
245
246 def draw_neomensural_open_head (expr wid, height)=
247         draw_neomensural_black_head (wid, height);
248
249         save diamNW, diamSW;
250
251         diamNW = length (z2 - z1) + blot_diameter;
252         diamSW = length (z4 - z1) + blot_diameter;
253         
254         save hole_widthNW, hole_widthSW;
255
256         hole_widthNW = 0.34 diamNW ;
257         hole_widthSW + 2.6 linethickness = diamSW;
258
259         (z7 + z5) / 2 = (w / 2, 0);
260         (z8 + z6) / 2 = (w / 2, 0);
261         z6 - z5 = hole_widthNW * unitvector (z2 - z1);
262         z7 - z6 = hole_widthSW * unitvector (z4 - z1);
263
264         unfill z5
265                -- z6
266                -- z7
267                -- z8
268                -- cycle;
269
270         labels (5, 6, 7, 8);
271 enddef;
272
273
274 %
275 % WL says the thin lines should be thinner.
276 %
277 fet_beginchar ("Harmonic notehead (Neo-mensural open)", "s0harmonic");
278         draw_neomensural_open_head (1.3 staff_space#, 1.3 noteheight#);
279         charwx := head_width#;
280         charwy := 0;
281 fet_endchar;
282
283
284 fet_beginchar ("Harmonic notehead (Neo-mensural black)", "s2harmonic");
285         draw_neomensural_black_head (1.3 staff_space#, 1.3 noteheight#);
286         charwx := head_width#;
287         charwy := 0;
288 fet_endchar;
289
290
291 fet_beginchar ("Neo-mensural semibrevis head", "s0neomensural");
292         draw_neomensural_open_head (staff_space#, noteheight#);
293 fet_endchar;
294
295
296 fet_beginchar ("Neo-mensural minima head", "s1neomensural");
297         draw_neomensural_open_head (staff_space#, noteheight#);
298 fet_endchar;
299
300
301 fet_beginchar ("Neo-mensural semiminima head", "s2neomensural");
302         draw_neomensural_black_head (staff_space#, noteheight#);
303 fet_endchar;
304
305
306 def draw_mensural_brevis (expr wid) =
307         % TODO.  For the moment, fall back to draw_neomensural_brevis.
308         draw_neomensural_brevis (wid);
309 enddef;
310
311
312 %%% This head does not seem to be used anywhere.  Junk me?  -- jr
313 def draw_mensural_left_stemmed_head (expr wid) =
314         draw_mensural_brevis (wid);
315
316         x6 = x7 = stem_width / 2;
317         y6 = y5;
318         y7 = y5 - 2.25 staff_space;
319
320         z17 = (x7, y7 - stem_width / 2);
321
322         penpos6 (stem_width, 0);
323         penpos7 (stem_width, 0);
324
325         fill z7l
326              -- z6l
327              -- z6r
328              -- z7r
329              .. z17
330              .. cycle;
331
332         penlabels (6, 7);
333         labels (17);
334 enddef;
335
336
337 def draw_mensural_longa (expr wid) =
338         draw_mensural_brevis (wid);
339
340         x6 = x7 = head_width - stem_width / 2;
341         y6 = y5;
342         y7 = y5 - 2.25 staff_space;
343
344         z17 = (x7, y7 - stem_width / 2);
345
346         penpos6 (stem_width, 0);
347         penpos7 (stem_width, 0);
348
349         fill z7l
350              -- z6l
351              -- z6r
352              -- z7r
353              .. z17
354              .. cycle;
355
356         penlabels (6, 7);
357         labels (17);
358 enddef;
359
360
361 %%% This head does not seem to be used anywhere.  Junk me?  -- jr
362 fet_beginchar ("Mensural left stemmed notehead", "slmensural");
363         draw_mensural_left_stemmed_head (staff_space#);
364 fet_endchar;
365
366
367 fet_beginchar ("Mensural maxima notehead", "sM3mensural");
368         draw_mensural_longa (2.0 staff_space#);
369 fet_endchar;
370
371
372 fet_beginchar ("Mensural longa notehead", "sM2mensural");
373         draw_mensural_longa (staff_space#);
374 fet_endchar;
375
376
377 fet_beginchar ("Mensural brevis notehead", "sM1mensural");
378         draw_mensural_brevis (staff_space#);
379 fet_endchar;
380
381
382 def draw_diamond_head (expr head_h, pen_w, pen_h, angle, open) =
383         save head_width, head_height;
384         save ellipse, ellipse_r;
385         path ellipse, ellipse_r, diamond_shape;
386
387         head_height# = head_h;
388         head_width# / head_height# = tand (angle);
389
390         set_char_box (0, head_width#,
391                       head_height# / 2, head_height# / 2);
392
393         charwx := head_width# / 2;
394         charwy := head_height# / 2 - linethickness#;
395
396         define_pixels (head_width, head_height);
397
398         ellipse := reverse fullcircle
399                      xscaled (max (blot_diameter, pen_w * head_width))
400                      yscaled (max (blot_diameter, pen_h * head_width))
401                      rotated -angle;
402
403         z1 = find_tangent_shift (((0, h) -- (0, -h)), ellipse,
404                                  (0, 0), (w / 2, 0));
405         z2 = find_tangent_shift (((0, h) -- (w, h)), ellipse,
406                                  (w / 2, h), (w / 2, 0));
407         z3 = find_tangent_shift (((w, h) -- (w, -h)), ellipse,
408                                  (w, 0), (w / 2, 0));
409         z4 = find_tangent_shift (((0, -h) -- (w, -h)), ellipse,
410                                  (w / 2, -h), (w / 2, 0));
411
412         diamond_shape := get_subpath (ellipse, z1 - z4, z2 - z1, z1)
413                          -- get_subpath (ellipse, z2 - z1, z3 - z2, z2)
414                          -- get_subpath (ellipse, z3 - z2, z4 - z3, z3)
415                          -- get_subpath (ellipse, z4 - z3, z1 - z4, z4)
416                          -- cycle;
417         fill diamond_shape;
418
419         if open:
420                 save l;
421                 path l[];
422
423                 l12 := (directionpoint (z1 - z2) of ellipse) shifted z1
424                         -- (directionpoint (z1 - z2) of ellipse) shifted z2;
425                 l23 := (directionpoint (z2 - z3) of ellipse) shifted z2
426                         -- (directionpoint (z2 - z3) of ellipse) shifted z3;
427                 l34 := (directionpoint (z3 - z4) of ellipse) shifted z3
428                         -- (directionpoint (z3 - z4) of ellipse) shifted z4;
429                 l41 := (directionpoint (z4 - z1) of ellipse) shifted z4
430                         -- (directionpoint (z4 - z1) of ellipse) shifted z1;
431
432                 unfill l12 intersectionpoint l23
433                        -- l23 intersectionpoint l34
434                        -- l34 intersectionpoint l41
435                        -- l41 intersectionpoint l12
436                        -- cycle;
437         fi;
438
439         labels (1, 2, 3, 4);
440 enddef;
441
442
443 fet_beginchar ("Mensural semibrevis head", "s0mensural");
444         draw_diamond_head (staff_space#, 0.15, 0.30, 30, true);
445 fet_endchar;
446
447
448 fet_beginchar ("Mensural minima head", "s1mensural");
449         draw_diamond_head (staff_space#, 0.15, 0.30, 30, true);
450 fet_endchar;
451
452
453 fet_beginchar ("Mensural semiminima head", "s2mensural");
454         draw_diamond_head (staff_space#, 0.15, 0.30, 30, false);
455 fet_endchar;
456
457
458 fet_beginchar ("Petrucci semibrevis head", "s0petrucci");
459 %       draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
460         draw_neomensural_open_head (staff_space#, 1.8 staff_space#);
461 fet_endchar;
462
463
464 fet_beginchar ("Petrucci minima head", "s1petrucci");
465 %       draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true);
466         draw_neomensural_open_head (staff_space#, 1.8 staff_space#);
467 fet_endchar;
468
469
470 fet_beginchar ("Petrucci semiminima head", "s2petrucci");
471 %       draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, false);
472         draw_neomensural_black_head (staff_space#, 1.8 staff_space#);
473 fet_endchar;
474
475
476 %%%%%%%%
477 %
478 %
479 %
480 % EDITIO VATICANA (including solesmes extensions)
481 %
482 %
483 %
484
485 def vat_punctum_char (expr verbose_name, internal_name,
486                            linea, cavum, straight, auctum,
487                            d_up, up_shift, down_shift, mag) =
488         fet_beginchar (verbose_name, "s" & internal_name);
489                 save a_b, b_h, a_w;
490
491                 a_b := 1.54; % b_h * a_b / a_w = wd / ht
492                 b_h := 0.85;
493                 a_w := 1.09;
494
495                 save a, beta, ht, wd;
496
497                 ht# = noteheight# * mag;
498                 2 beta = ht# * b_h;
499                 a = beta * a_b;
500                 wd# = 2 a / a_w;
501                 black_notehead_width# := wd#;
502
503                 % direction
504                 save d_, d_sign;
505                 pair d_;
506
507                 if d_up:
508                         d_ := up;
509                         d_sign := 1;
510                 else:
511                         d_ := down;
512                         d_sign := -1;
513                 fi;
514
515                 % convexity and eccentricity
516                 save u_convexity, u_eccentricity;
517
518                 if straight:
519                         u_convexity# := -0.01 ht#;
520                         u_eccentricity# := 0.0 ht#; % dummy
521                 elseif auctum:
522                         u_convexity# := -0.03 ht#;
523                         u_eccentricity# := +0.25 ht#;
524                 else:
525                         u_convexity# := -0.05 ht#;
526                         u_eccentricity# := 0.0 ht#; % dummy
527                 fi;
528
529                 save convexity, eccentricity;
530
531                 convexity# := d_sign * u_convexity#;
532                 eccentricity# := d_sign * u_eccentricity#;
533
534                 % y shift offset
535                 save yoffs;
536
537                 if up_shift:
538                         yoffs# := 0.08 ht#;
539                 elseif down_shift:
540                         yoffs# := -0.11 ht#;
541                 else:
542                         yoffs# := 0.00 ht#;
543                 fi;
544
545                 define_pixels (convexity, eccentricity, yoffs, ht, wd);
546
547                 pickup pencircle scaled linethickness;
548
549                 save height, yoffs_bt, p, circle, circle_r;
550                 path p, circle, circle_r;
551
552                 height# = 0.47 ht#;
553                 yoffs_bt# = yoffs# - 0.5 height# - 0.25 convexity#;
554
555                 define_pixels (height, yoffs_bt);
556
557                 circle := fullcircle scaled linethickness;
558
559                 x1 = x6;
560                 x2 = x5;
561                 x3 = x4;
562                 y1 + height = y6;
563                 y2 + height = y5;
564                 y3 + height = y4;
565
566                 save box_top, box_bt;
567
568                 if auctum:
569                         z1 = (0.00 wd + linethickness / 2, yoffs_bt);
570                         z2 = (0.21 wd, yoffs_bt + convexity);
571                         z3 = (0.42 wd - linethickness/ 2,
572                               yoffs_bt + eccentricity);
573                         box_top# = height# + yoffs_bt# +
574                                      max (0, convexity#, eccentricity#);
575                         box_bt# = yoffs_bt# +
576                                      min (0, convexity#, eccentricity#);
577                         p = z1
578                             .. {right}z2
579                             .. {d_}z3
580                             -- z4{-d_}
581                             .. z5{left}
582                             .. z6
583                             -- cycle;
584                 else:
585                         z1 = (0.00 wd + linethickness / 2, yoffs_bt);
586                         z2 = (0.21 wd, yoffs_bt + convexity);
587                         z3 = (0.42 wd - linethickness / 2, yoffs_bt);
588                         box_top# = height# + yoffs_bt# + max (0, convexity#);
589                         box_bt# = yoffs_bt# + min (0, convexity#);
590                         p = z1
591                             .. z2
592                             .. z3
593                             -- z4
594                             .. z5
595                             .. z6
596                             -- cycle;
597                 fi;
598
599                 labels (1, 2, 3, 4, 5, 6);
600
601                 save dirs;
602                 pair dirs[];
603
604                 dirs12 := direction (0 + epsilon) of p;
605                 dirs2 := direction 1 of p;
606                 dirs32 := direction (2 - epsilon) of p;
607                 dirs45 := direction (3 + epsilon) of p;
608                 dirs5 := direction 4 of p;
609                 dirs65 := direction (5 - epsilon) of p;
610
611                 fill get_subpath (circle, down, dirs12, z1)
612                      .. (bot z2){dirs2}
613                      .. get_subpath (circle, dirs32, up, z3)
614                      -- get_subpath (circle, up, dirs45, z4)
615                      .. (top z5){dirs5}
616                      .. get_subpath (circle, dirs65, down, z6)
617                      -- cycle;
618
619                 if cavum:
620                         save pat, t;
621                         path pat[];
622                         numeric t[];
623
624                         pat123 := ((directionpoint -dirs12 of circle)
625                                     shifted z1){dirs12}
626                                   .. (top z2){dirs2}
627                                   .. {dirs32}((directionpoint -dirs32 of circle)
628                                        shifted z3);
629                         pat34 := lft z3
630                                  -- lft z4;
631                         pat456 := ((directionpoint -dirs45 of circle)
632                                     shifted z4){dirs45}
633                                   .. (bot z5){dirs5}
634                                   .. {dirs65}((directionpoint -dirs65 of circle)
635                                        shifted z6);
636                         pat61 := rt z6
637                                  -- rt z1;
638
639                         t61 := ypart (pat61 intersectiontimes pat123);
640                         t12 := xpart (pat123 intersectiontimes pat34);
641                         t34 := ypart (pat34 intersectiontimes pat456);
642                         t45 := xpart (pat456 intersectiontimes pat61);
643
644                         unfill subpath (t61, t12) of pat123
645                                -- subpath (t34, t45) of pat456
646                                -- cycle;
647                 fi;
648
649                 set_char_box (0.00 wd#, 0.42 wd#,
650                               max (0, -box_bt#) + linethickness# / 2,
651                               max (0, box_top#) + linethickness# / 2);
652
653                 if linea:
654                         save linea_width, linea_height;
655
656                         linea_width# = 0.6 linethickness#;
657                         linea_height# = 0.7 ht#;
658
659                         define_pixels (linea_width, linea_height);
660
661                         pickup pencircle scaled 0.6 linethickness;
662
663                         draw_rounded_block ((-0.10 wd - linea_width / 2,
664                                              -linea_height / 2),
665                                             (-0.10 wd + linea_width / 2,
666                                              +linea_height / 2),
667                                             0.6 linethickness);
668                         draw_rounded_block ((+0.52 wd - linea_width / 2,
669                                              -linea_height / 2),
670                                             (+0.52 wd + linea_width / 2,
671                                              +linea_height / 2),
672                                             0.6 linethickness);
673
674                         set_char_box (0, 0.62 wd# + linea_width#,
675                                       linea_height# / 2,
676                                       linea_height# / 2);
677
678                         currentpicture := currentpicture
679                                 shifted (0.10 wd + linea_width / 2, 0);
680                 fi;
681         fet_endchar;
682 enddef;
683
684
685 def plica_char (expr verbose_name, internal_name,
686                      d_up, mag) =
687         fet_beginchar (verbose_name, "s" & internal_name);
688                 save a_b, b_h, a_w;
689
690                 a_b := 1.54; % b_h * a_b / a_w = wd / ht
691                 b_h := 0.85;
692                 a_w := 1.09;
693
694                 save a, beta, ht, wd;
695
696                 ht# = noteheight# * mag;
697                 2 beta = ht# * b_h;
698                 a = beta * a_b;
699                 wd# = 2 a / a_w;
700                 black_notehead_width# := wd#;
701
702                 % direction
703                 save d_, d_sign;
704                 pair d_;
705
706                 if d_up:
707                         d_ := up;
708                         d_sign := 1;
709                 else:
710                         d_ := down;
711                         d_sign := -1;
712                 fi;
713
714                 % convexity and eccentricity
715                 save convexity, eccentricity;
716
717                 convexity# := d_sign * -0.10 ht#;
718                 eccentricity# := d_sign * -0.12 ht#;
719
720                 % y shift offset
721                 save yoffs;
722
723                 yoffs# := -0.11 ht#;
724
725                 define_pixels (convexity, eccentricity, yoffs, ht, wd);
726
727                 pickup pencircle scaled linethickness;
728
729                 save height, yoffs_bt, p, circle, circle_r;
730                 path p, circle, circle_r;
731
732                 height# = 0.47 ht#;
733                 yoffs_bt# = yoffs# - 0.5 height# - 0.25 convexity#;
734
735                 define_pixels (height, yoffs_bt);
736
737                 circle := fullcircle scaled linethickness;
738
739                 x1 = x6;
740                 x2 = x5;
741                 x3 = x4;
742                 y1 + height = y6;
743                 y2 + height = y5;
744                 y3 + height = y4;
745
746                 save box_top, box_bt;
747
748                 z1 = (0.00 wd + linethickness / 2, yoffs_bt);
749                 z2 = (0.21 wd, yoffs_bt + convexity);
750                 z3 = (0.42 wd - linethickness/ 2, yoffs_bt + eccentricity);
751                 box_top# = height# + yoffs_bt# +
752                              max (0, convexity#, eccentricity#);
753                 box_bt# = yoffs_bt# +
754                              min (0, convexity#, eccentricity#);
755                 p = z1
756                     .. z2{right}
757                     .. z3
758                     -- z4
759                     .. z5{left}
760                     .. z6
761                     -- cycle;
762
763                 labels (1, 2, 3, 4, 5, 6);
764
765                 save dirs;
766                 pair dirs[];
767
768                 dirs12 := direction (0 + epsilon) of p;
769                 dirs2 := direction 1 of p;
770                 dirs32 := direction (2 - epsilon) of p;
771                 dirs45 := direction (3 + epsilon) of p;
772                 dirs5 := direction 4 of p;
773                 dirs65 := direction (5 - epsilon) of p;
774
775                 fill get_subpath (circle, down, dirs12, z1)
776                      .. (bot z2){dirs2}
777                      .. get_subpath (circle, dirs32, up, z3)
778                      -- get_subpath (circle, up, dirs45, z4)
779                      .. (top z5){dirs5}
780                      .. get_subpath (circle, dirs65, down, z6)
781                      -- cycle;
782
783                 pickup pencircle scaled 0.6 linethickness;
784
785                 save stem_bt;
786
787                 set_char_box (0.00 wd#, 0.42 wd#,
788                               max (0, -box_bt#) + linethickness# / 2,
789                               max (0, box_top#) + linethickness# / 2);
790
791         fet_endchar;
792 enddef;
793
794
795 def epiphonus_char (expr verbose_name, internal_name,
796                          left_stem, d_up, down_shift, mag) =
797         fet_beginchar (verbose_name, "s" & internal_name);
798                 save a_b, b_h, a_w;
799
800                 a_b := 1.54; % b_h * a_b / a_w = wd / ht
801                 b_h := 0.85;
802                 a_w := 1.09;
803
804                 save a, beta, ht, wd;
805
806                 ht# = noteheight# * mag;
807                 2 beta = ht# * b_h;
808                 a = beta * a_b;
809                 wd# = 2 a / a_w;
810                 black_notehead_width# := wd#;
811
812                 % direction
813                 save d_, d_sign;
814                 pair d_;
815
816                 if d_up:
817                         d_ := up;
818                         d_sign := 1;
819                 else:
820                         d_ := down;
821                         d_sign := -1;
822                 fi;
823
824                 % convexity and eccentricity
825                 save convexity;
826
827                 convexity# := d_sign * -0.05ht#;
828
829                 % y shift offset
830                 save yoffs;
831
832                 if down_shift:
833                         yoffs# := -0.11 ht#;
834                 else:
835                         yoffs# := 0.00 ht#;
836                 fi;
837
838                 define_pixels (convexity, yoffs, ht, wd);
839
840                 pickup pencircle scaled linethickness;
841
842                 save height, yoffs_bt, p, circle, circle_r;
843                 path p, circle, circle_r;
844
845                 height# = 0.47 ht#;
846                 yoffs_bt# = yoffs# - 0.5 height# - 0.25 convexity#;
847
848                 define_pixels (height, yoffs_bt);
849
850                 circle := fullcircle scaled linethickness;
851
852                 x1 = x6;
853                 x2 = x5;
854                 x3 = x4;
855                 y1 + height = y6;
856                 y2 + height = y5;
857                 y3 + height = y4;
858
859                 save box_top, box_bt;
860
861                 z1 = (0.00 wd + linethickness / 2, yoffs_bt - 2.5 convexity);
862                 z2 = (0.06 wd, yoffs_bt + 1.4 convexity);
863                 z3 = (0.42 wd - linethickness / 2, yoffs_bt - 1.0 convexity);
864                 box_top# = height# + yoffs_bt# +
865                              max (-1.0 convexity#, 1.4 convexity#, 0);
866                 box_bt# = yoffs_bt# +
867                              min (-1.0 convexity#, 1.4 convexity#, 0);
868                 p = z1{-d_}
869                     .. {curl 1}z2{right}
870                     .. z3
871                     -- z4
872                     .. {left}z5{curl 1}
873                     .. {d_}z6
874                     -- cycle;
875
876                 labels (1, 2, 3, 4, 5, 6);
877
878                 save dirs;
879                 pair dirs[];
880
881                 dirs12 := direction (0 + epsilon) of p;
882                 dirs21 := direction (1 - epsilon) of p;
883                 dirs23 := direction (1 + epsilon) of p;
884                 dirs32 := direction (2 - epsilon) of p;
885                 dirs45 := direction (3 + epsilon) of p;
886                 dirs54 := direction (4 - epsilon) of p;
887                 dirs56 := direction (4 + epsilon) of p;
888                 dirs65 := direction (5 - epsilon) of p;
889
890                 fill get_subpath (circle, down, dirs12, z1)
891                      .. get_subpath (circle, dirs21, dirs23, z2)
892                      .. get_subpath (circle, dirs32, up, z3)
893                      -- get_subpath (circle, up, dirs45, z4)
894                      .. get_subpath (circle, dirs54, dirs56, z5)
895                      .. get_subpath (circle, dirs65, down, z6)
896                      -- cycle;
897
898                 save stem_bt;
899
900                 if left_stem:
901                         pickup pencircle scaled 0.6 linethickness;
902
903                         lft x11 = x1 - linethickness / 2;
904                         bot y11 = yoffs - 1.1 ht - linethickness / 2;
905                         x12 = x11;
906                         y12 = y1;
907
908                         draw_rounded_block (bot lft z11, top rt z12,
909                                             0.6 linethickness);
910                         stem_bt# = yoffs# - 1.1 ht#;
911
912                         labels (11, 12);
913                 else:
914                         stem_bt# = 0;
915                 fi;
916
917                 set_char_box (0.00 wd#, 0.42 wd#,
918                               max (0, -box_bt#, -stem_bt#) + linethickness# / 2,
919                               max (0, box_top#) + linethickness# / 2);
920         fet_endchar;
921 enddef;
922
923
924 def inclinatum_char (expr verbose_name, internal_name,
925                           small, stropha, auctum) =
926         fet_beginchar (verbose_name, "s" & internal_name);
927                 save ht, alpha;
928
929                 alpha := 35;
930
931                 if small:
932                         ht# = 0.50 noteheight#;
933                 else:
934                         ht# = 0.80 noteheight#;
935                 fi;
936
937                 draw_diamond_head (ht#, 0, 0, alpha, false);
938
939                 save off_angle;
940
941                 off_angle := alpha + 15;
942
943                 save stropha_ellipse, auctum_hook, circle;
944                 path stropha_ellipse, auctum_hook, circle;
945
946                 circle := reverse fullcircle scaled linethickness;
947
948                 stropha_ellipse := fullcircle xscaled 0.25 head_height
949                                               yscaled 0.55 head_height
950                                               rotated alpha;
951
952                 z11 = z12
953                       + linethickness / 2 * dir (180 - off_angle)
954                       - directionpoint dir (90 - off_angle)
955                           of stropha_ellipse;
956                 z12 = directionpoint -dir (90 - off_angle) of diamond_shape +
957                         linethickness / 2 * dir (180 - off_angle);
958                 z13 = (0, -0.5 head_height + linethickness);
959
960                 auctum_hook := z12{-dir (90 - off_angle)}
961                                .. {dir (90 + alpha)}z13;
962
963                 labels (12);
964
965                 if (stropha and not auctum):
966                         clearit;
967
968                         save t_in, t_out;
969
970                         t_in := xpart ((stropha_ellipse shifted z11)
971                                        intersectiontimes
972                                        get_subpath (diamond_shape,
973                                                     left, up,
974                                                     (0, 0)));
975                         t_out := xpart ((stropha_ellipse shifted z11)
976                                         intersectiontimes
977                                         get_subpath (diamond_shape,
978                                                      up, right,
979                                                      (0, 0)));
980
981                         % the addition or subtraction of `1' is necessary
982                         % so that we get the right starting point
983                         fill get_subpath_i (diamond_shape,
984                                             dir (angle (z2 - z1) - 1),
985                                             dir (angle (z1 - z4) + 1),
986                                             (0, 0))
987                              -- get_subpath (stropha_ellipse,
988                                              direction t_in of stropha_ellipse,
989                                              direction t_out of stropha_ellipse,
990                                              z11)
991                              -- cycle;
992
993                         labels (11);
994                 fi;
995
996                 if (auctum and not stropha):
997                         clearit;
998
999                         fill get_subpath (diamond_shape,
1000                                           left,
1001                                           -dir (90 - off_angle),
1002                                           (0, 0))
1003                              .. get_subpath (circle,
1004                                              dir (90 + alpha),
1005                                              -dir (90 + alpha),
1006                                              z13)
1007                              .. get_subpath (circle,
1008                                              dir (90 - off_angle),
1009                                              right,
1010                                              z12)
1011                              -- cycle;
1012
1013                         labels (13);
1014                 fi;
1015
1016                 if (auctum and stropha):
1017                         clearit;
1018
1019                         save t;
1020
1021                         t := xpart ((stropha_ellipse shifted z11)
1022                                     intersectiontimes
1023                                     get_subpath (diamond_shape, up, right,
1024                                                  (0, 0)));
1025
1026                         % the addition or subtraction of `1' is necessary
1027                         % so that we get the right starting point
1028                         fill get_subpath_i (diamond_shape,
1029                                             dir (angle (z2 - z1) - 1),
1030                                             -dir (90 - off_angle),
1031                                             (0, 0))
1032                              .. get_subpath (circle,
1033                                              dir (90 + alpha),
1034                                              -dir (90 + alpha),
1035                                              z13)
1036                              .. get_subpath (stropha_ellipse,
1037                                              dir (90 - off_angle),
1038                                              direction t of stropha_ellipse,
1039                                              z11)
1040                              -- cycle;
1041
1042                         labels (11, 13);
1043                 fi;
1044         fet_endchar;
1045 enddef;
1046
1047
1048 % punctum
1049 vat_punctum_char ("Ed. Vat. punctum", "vaticana.punctum",
1050                   false, false, false, false,
1051                   false, false, false, 1.0);
1052
1053
1054 % punctum cavum (for OpusTeX compatibility)
1055 vat_punctum_char ("Ed. Vat. punctum cavum", "vaticana.punctum.cavum",
1056                   false, true, false, false,
1057                   false, false, false, 1.0);
1058
1059
1060 % linea punctum (for OpusTeX compatibility)
1061 vat_punctum_char ("Ed. Vat. linea punctum", "vaticana.linea.punctum",
1062                   true, false, false, false,
1063                   false, false, false, 1.0);
1064
1065
1066 % linea punctum cavum (for OpusTeX compatibility)
1067 vat_punctum_char ("Ed. Vat. linea punctum cavum", "vaticana.linea.punctum.cavum",
1068                   true, true, false, false,
1069                   false, false, false, 1.0);
1070
1071
1072 % punctum inclinatum
1073 inclinatum_char ("Ed. Vat. inclinatum", "vaticana.inclinatum",
1074                  false, false, false);
1075
1076
1077 % pes lower punctum
1078 vat_punctum_char ("Ed. Vat. pes lower punctum", "vaticana.lpes",
1079                   false, false, true, false,
1080                   true, false, false, 1.0);
1081
1082
1083 % pes lower punctum
1084 vat_punctum_char ("Ed. Vat. pes var lower punctum", "vaticana.vlpes",
1085                   false, false, true, false,
1086                   true, false, true, 1.0);
1087
1088
1089 % pes upper punctum
1090 vat_punctum_char ("Ed. Vat. pes upper punctum", "vaticana.upes", 
1091                   false, false, true, false,
1092                   false, false, false, 1.0);
1093
1094
1095 % pes upper punctum (shifted variation)
1096 %
1097 % This note head is used instead of the regular pes upper punctum to
1098 % avoid collision with the lower punctum note of the pes when the upper
1099 % punctum sits directly on top of the lower punctum.
1100 %
1101 vat_punctum_char ("Ed. Vat. var pes upper punctum", "vaticana.vupes",
1102                   false, false, true, false,
1103                   false, true, false, 1.0);
1104
1105
1106 % small punctum as used in epiphonus
1107 vat_punctum_char ("Ed. Vat. plica", "vaticana.plica", 
1108                   false, false, false, false,
1109                   false, false, false, 0.6);
1110
1111
1112 % small punctum as used in epiphonus
1113 plica_char ("Ed. Vat. var plica", "vaticana.vplica", 
1114             false, 0.6);
1115
1116
1117 % eccentric punctum as used in epiphonus
1118 epiphonus_char ("Ed. Vat. epiphonus", "vaticana.epiphonus", 
1119                 false, true, false, 1.0);
1120
1121
1122 % eccentric punctum as used in epiphonus (shifted variation)
1123 %
1124 % This note head is used instead of the regular epiphonus punctum to
1125 % avoid collision with the plica head when the plica sits directly on
1126 % top of the lower head.
1127 %
1128 epiphonus_char ("Ed. Vat. var epiphonus", "vaticana.vepiphonus",
1129                 false, true, true, 1.0);
1130
1131
1132 % small punctum as used in cephalicus
1133 vat_punctum_char ("Ed. Vat. rev. plica", "vaticana.reverse.plica",
1134                   false, false, false, false,
1135                   true, false, false, 0.6);
1136
1137
1138 % small punctum as used in cephalicus
1139 plica_char ("Ed. Vat. rev. var plica", "vaticana.reverse.vplica",
1140             true, 0.6);
1141
1142
1143 % eccentric punctum as used in cephalicus; without left stem
1144 epiphonus_char ("Ed. Vat. inner cephalicus", "vaticana.inner.cephalicus",
1145                 false, false, false, 1.0);
1146
1147
1148 % eccentric punctum as used in cephalicus; with left stem
1149 epiphonus_char ("Ed. Vat. cephalicus", "vaticana.cephalicus",
1150                 true, false, false, 1.0);
1151
1152
1153 % quilisma
1154 fet_beginchar ("Ed. Vat. quilisma", "svaticana.quilisma");
1155         save a_b, b_h, a_w;
1156
1157         a_b := 1.54; % b_h * a_b / a_w = wd / ht
1158         b_h := 0.85;
1159         a_w := 1.09;
1160
1161         save a, beta, ht, wd;
1162
1163         ht# = noteheight#;
1164         2 beta = ht# * b_h;
1165         a = beta * a_b;
1166         wd# = 2 a / a_w;
1167
1168         set_char_box (0, 0.42 wd#, 0.28 ht#, 0.36 ht#);
1169
1170         black_notehead_width# := wd#;
1171
1172         define_pixels (ht, wd);
1173
1174         save ellipse, T;
1175         path ellipse;
1176         transform T;
1177
1178         T := identity xscaled linethickness
1179                       yscaled 0.44 ht;
1180         pickup pencircle transformed T;
1181         ellipse := reverse fullcircle transformed T;
1182
1183         z1 = (rt 0.00 wd, top -0.28 ht);
1184         z2 = (0.11 wd, -0.14 ht);
1185         z3 = (0.12 wd, +0.03 ht);
1186         z4 = (0.25 wd, -0.09 ht);
1187         z5 = (0.25 wd, +0.08 ht);
1188         z6 = (lft 0.42 wd, -0.04 ht);
1189         z7 = (lft 0.40 wd, bot +0.36 ht);
1190
1191         fill get_subpath (ellipse, z1 - z2, z2 - z1, z1)
1192              -- get_subpath (ellipse, z2 - z1, z1 - z2, z2)
1193              -- cycle;
1194         fill get_subpath (ellipse, z3 - z4, z4 - z3, z3)
1195              -- get_subpath (ellipse, z4 - z3, z3 - z4, z4)
1196              -- cycle;
1197         fill get_subpath (ellipse, z5 - z6, z6 - z5, z5)
1198              -- point 0 of get_subpath (ellipse, z6 - z5, z5 - z6, z6)
1199              -- get_subpath (ellipse, z7 - z6, z6 - z7, z7)
1200              -- get_subpath (ellipse, z6 - z7, z5 - z6, z6)
1201              -- cycle;
1202
1203         labels (1, 2, 3, 4, 5, 6, 7);
1204 fet_endchar;
1205
1206
1207 % solesmes punctum inclinatum parvum
1208 inclinatum_char ("Solesmes punctum inclinatum parvum", "solesmes.incl.parvum",
1209                  true, false, false);
1210
1211
1212 % solesmes punctum auctum ascendens
1213 vat_punctum_char ("Solesmes punctum auctum ascendens", "solesmes.auct.asc",
1214                   false, false, false, true,
1215                   true, false, false, 1.0);
1216
1217
1218 % solesmes punctum auctum descendens
1219 vat_punctum_char ("Solesmes punctum auctum descendens", "solesmes.auct.desc",
1220                   false, false, false, true,
1221                   false, false, false, 1.0);
1222
1223
1224 % solesmes punctum inclinatum auctum
1225 inclinatum_char ("Solesmes punctum incl. auctum", "solesmes.incl.auctum",
1226                  false, false, true);
1227
1228
1229 % solesmes stropha
1230 inclinatum_char ("Solesmes stropha", "solesmes.stropha",
1231                  false, true, false);
1232
1233
1234 % solesmes stropha aucta
1235 inclinatum_char ("Solesmes stropha aucta", "solesmes.stropha.aucta",
1236                  false, true, true);
1237
1238
1239 % solesmes oriscus
1240 fet_beginchar ("Solesmes oriscus", "ssolesmes.oriscus");
1241         save a_b, b_h, a_w;
1242
1243         a_b := 1.54; % b_h * a_b / a_w = wd / ht
1244         b_h := 0.85;
1245         a_w := 1.09;
1246
1247         save a, beta, ht, wd;
1248
1249         ht# = noteheight#;
1250         2 beta = ht# * b_h;
1251         a = beta * a_b;
1252         wd# = 2 a / a_w;
1253         black_notehead_width# := wd#;
1254
1255         save convexity;
1256
1257         convexity# = +0.05 ht#;
1258
1259         define_pixels (ht, wd, convexity);
1260
1261         set_char_box (0.00 wd#, 0.50 wd#,
1262                       0.25 ht# + convexity#, 0.25 ht# + convexity#);
1263
1264         z1 = (0.00 wd + blot_diameter / 2, -convexity);
1265         z2 = (1/6 wd, +convexity);
1266         z3 = (2/6 wd, -convexity);
1267         z4 = (0.50 wd - blot_diameter / 2, +convexity);
1268
1269
1270         save height;
1271
1272         height = 2 ypart (directionpoint right of (z1
1273                                                    .. z2
1274                                                    .. z3
1275                                                    .. z4));
1276
1277         save ellipse, T;
1278         path ellipse;
1279         transform T;
1280
1281         T := identity xscaled blot_diameter
1282                       yscaled (h + d - height);
1283         pickup pencircle transformed T;
1284         ellipse := fullcircle transformed T;
1285
1286         % Adjust vertical coordinates to touch bounding box.
1287         y1 := top -d;
1288         y4 := bot h;
1289
1290         save d_;
1291         pair d_;
1292
1293         d_ := direction 0 of (z1
1294                               .. z2
1295                               .. z3
1296                               .. z4);
1297
1298         fill get_subpath (ellipse, -d_, d_, z1)
1299              .. bot z2
1300              .. bot z3
1301              .. get_subpath (ellipse, d_, -d_, z4)
1302              .. top z3
1303              .. top z2
1304              .. cycle;
1305
1306         labels (1, 2, 3, 4);
1307 fet_endchar;
1308
1309
1310 %%%%%%%%
1311 %
1312 %
1313 %
1314 % EDITIO MEDICAEA
1315 %
1316 %
1317 %
1318
1319 % inclinatum
1320 fet_beginchar ("Ed. Med. inclinatum", "smedicaea.inclinatum");
1321         draw_diamond_head (1.2 staff_space#, 0, 0, 35, false);
1322 fet_endchar;
1323
1324
1325 def med_punctum_char (expr verbose_name, internal_name,
1326                            left_up_stem, left_down_stem) =
1327         fet_beginchar (verbose_name, "s" & internal_name);
1328                 save a, ht, wd;
1329
1330                 ht# = 2 staff_space#;
1331                 wd# = ht#;
1332                 black_notehead_width# := wd#;
1333
1334                 define_pixels (ht, wd);
1335
1336                 save ellipse;
1337                 path ellipse;
1338
1339                 ellipse := fullcircle xscaled blot_diameter
1340                                       yscaled 0.50 ht;
1341
1342                 z1 = (0.00 wd + blot_diameter / 2, 0);
1343                 z2 = (0.4 wd - blot_diameter / 2, 0);
1344
1345                 labels (1, 2);
1346
1347                 pickup pencircle scaled linethickness;
1348
1349                 if left_down_stem:
1350                         z4 = (0.00 wd + linethickness / 2, -1.25 ht);
1351
1352                         fill get_subpath (ellipse, left, down, z1)
1353                              -- top lft z4{down}
1354                              .. z4{right}
1355                              .. top rt z4{up}
1356                              -- (rt x4, -.5 ht / 2)
1357                              -- get_subpath (ellipse, right, left, z2)
1358                              -- cycle;
1359
1360                         labels (4);
1361
1362                         set_char_box (0.0, 0.4 wd#, 1.25 ht#, 0.25 ht#);
1363                 elseif left_up_stem:
1364                         z4 = (0.00 wd + linethickness / 2, +1.25 ht);
1365
1366                         fill get_subpath (ellipse, down, right, z1)
1367                              -- get_subpath (ellipse, right, left, z2)
1368                              -- (rt x4, .5 ht / 2)
1369                              -- bot rt z4{up}
1370                              .. z4{left}
1371                              .. bot lft z4{down}
1372                              -- cycle;
1373
1374                         labels (4);
1375
1376                         set_char_box (0.0, 0.4 wd#, 0.25 ht#, 1.25 ht#);
1377                 else:
1378                         fill get_subpath (ellipse, left, right, z1)
1379                              -- get_subpath (ellipse, right, left, z2)
1380                              -- cycle;
1381
1382                         set_char_box (0.0, 0.4 wd#, 0.25 ht#, 0.25 ht#);
1383                 fi;
1384
1385         fet_endchar;
1386 enddef;
1387
1388
1389 % punctum
1390 med_punctum_char ("Ed. Med. punctum", "medicaea.punctum", 
1391                   false, false);
1392
1393
1394 % left up-stemmed punctum
1395 med_punctum_char ("Ed. Med. reverse virga", "medicaea.rvirga",
1396                   true, false);
1397
1398
1399 % virga (i.e. left down-stemmed punctum)
1400 med_punctum_char ("Ed. Med. virga", "medicaea.virga", 
1401                   false, true);
1402
1403
1404 %%%%%%%%
1405 %
1406 %
1407 %
1408 % HUFNAGEL
1409 %
1410 %
1411 %
1412
1413 def huf_punctum_char (expr verbose_name, internal_name,
1414                            down_stem) =
1415         fet_beginchar (verbose_name, "s" & internal_name);
1416                 save alpha;
1417
1418                 alpha = 55;
1419
1420                 draw_diamond_head (staff_space#, 0, 0, alpha, false);
1421
1422                 if down_stem:
1423                         set_char_box (0, head_width#,
1424                                       1.5 staff_space#, head_height# / 2);
1425
1426                         save ellipse;
1427                         path ellipse;
1428
1429                         ellipse := reverse fullcircle xscaled blot_diameter
1430                                                       yscaled 0.7 staff_space
1431                                                       rotated -alpha;
1432
1433                         z11 = (head_width / 2, 0);
1434                         z12 = find_tangent_shift (((0, -d) -- (w, -d)), ellipse,
1435                                                   (w / 2, -d), (w / 2, 0));
1436
1437                         fill get_subpath (ellipse, up, down, z11)
1438                              -- get_subpath (ellipse, down, up, z12)
1439                              -- cycle;
1440
1441                         labels (11, 12);
1442                 fi;
1443         fet_endchar;
1444 enddef;
1445
1446
1447 % punctum
1448 huf_punctum_char ("Hufnagel punctum", "hufnagel.punctum", false)
1449
1450
1451 % virga
1452 huf_punctum_char ("Hufnagel virga", "hufnagel.virga", true)
1453
1454
1455 % pes lower punctum
1456 fet_beginchar ("Hufnagel pes lower punctum", "shufnagel.lpes")
1457         save width, height, alpha;
1458
1459         width# = 2 * staff_space#;
1460         height# = 0.7 * staff_space#;
1461         alpha = 35;
1462
1463         set_char_box (0, width#, height# / 2, height# / 2);
1464
1465         define_pixels (width, height);
1466
1467         save circle;
1468         path circle;
1469
1470         circle := reverse fullcircle scaled linethickness;
1471
1472         pickup pencircle scaled linethickness;
1473
1474         rt x3 = -lft x1 = width / 2;
1475         y2 = y3 = height / 2;
1476         y1 = y4 = -height / 2;
1477
1478         tand (alpha) * (y2 - y1) = x2 - x1 = x3 - x4;
1479
1480         fill get_subpath (circle, left, z2 - z1, z1)
1481              -- get_subpath (circle, z2 - z1, right, z2)
1482              -- get_subpath (circle, right, z4 - z3, z3)
1483              -- get_subpath (circle, z4 - z3, left, z4)
1484              -- cycle;
1485
1486         currentpicture := currentpicture shifted (width/2, 0);
1487
1488 %       labels (1, 2, 3, 4);
1489 fet_endchar;
1490
1491
1492 fet_endgroup ("noteheads");