]> git.donarmstrong.com Git - lilypond.git/commitdiff
This patch addresses the following problems in the feta sources
authorWerner Lemberg <wl@gnu.org>
Thu, 13 Jan 2005 22:55:38 +0000 (22:55 +0000)
committerWerner Lemberg <wl@gnu.org>
Thu, 13 Jan 2005 22:55:38 +0000 (22:55 +0000)
files which contribute to the fetaXX fonts.

. Many fixes for rasterization at low resolutions (consistent use of
  `vround' and `hround', integer shift values for paths, applying
  `eps' for mirrored paths, use of `define_whole_pixels' and
  friends, etc.) -- while this probably looks like a waste of time
  it has revealed deficiencies in some glyph shapes.  See comment at
  the end of feta-params.mf how vertical symmetry is achieved.

. The `---' operator has been replaced everywhere with `--'; this
  both improves and considerably reduces the font size after
  conversion with mf2pt1.

These change aren't explicitly mentioned below since virtually all
glyphs are affected.

Other notable differences:

. Glyphs from feta-accordion.mf now have charboxes around the
  outline.

. Fixed incorrect charbox for `accDot'.

. The `rcomma' and `lcomma' glyphs were distorted due to a typo.

. Fixed position of the bow in the `upprall' glyph and its siblings.

. The bulb size in the `2/2 meter' and `4/4 meter' glyphs is now
  dependent on the staff line thickness to avoid touching the middle
  staff line at smaller sizes.

. Largely extended output for feta-testXX: Where useful, glyphs
are shown both between and on staff lines.

* mf/feta-params.mf (staff_space_rounded,
stafflinethickness_rounded, linethickness_rounded,
ledgerlinethickness_rounded, stemthickness_rounded): New variables.
Update all code which uses them where appropriate.
(feta_eps, feta_shift, feta_space_shift, feta_offset, feta_fillpen):
New variables used to control rasterization at low resolutions.  Set
to zert if feta code is processed with metapost.

* mf/feta-macros.mf (draw_staff, draw_staff_outline): Updated.
(draw_rounded_block, draw_square_block): Updated to use `--' only.
(flare_path): Updated.
Make it work with `filldraw' (but only circular pens).
(hfloor, vfloor, hceiling, vceiling): New macros.

* mf/feta-params.mf (to_bp): New macro for mf2pt1.
(set_char_box): Updated.
Add code which emits specials for mf2pt1 if run with metapost.

* mf/feta-accordion.mf ("accDiscant", "accFreebase", "accStdbase"):
Use `draw' again in mf mode to have good pixel dropout control.
Fix intersection points of horizontal lines with circle.
("accDot"): Fix parameters for set_char_box.
("accOldEE"): Use `draw' again in mf mode to have good pixel dropout
control.

* mf/feta-banier.mf: Updated.

* mf/feta-bolletjes.mf (remember_pic): New variable, used for
testing.
(undraw_inside_ellipse): Remove `center' argument.  Update all
callers.
(draw_brevis): New macro, called by "Brevis notehead".
(draw_whole_triangle_head): New macro, called by "Whole
trianglehead".
(draw_small_triangle_head): Use `filldraw'.

* mf/feta-eindelijk.mf: Remove useless global group.
Updated.

* mf/feta-klef.mf (draw_c_clef): Correct point positions for using
`filldraw'.

* mf/feta-pendaal.mf: Updated.

* mf/feta-puntje.mf: Updated.

* mf/feta-schrift.mf (draw_very_long_fermata): Simplified to use
less points.
("Flageolet"): Use `draw' again in mf mode to have good pixel
dropout control.
("Varied Coda"): Use `draw_block'.
(draw_comma): Fix typo.
(draw_arpeggio_arrow): Use `draw' also in mf mode to have good
pixel dropout control.

* mf/feta-slag.mf ("upprall", "downprall", "lineprall"): Fix start
position of bow.

* mf/feta-timesig.mf (draw_C): Reduce bulb size for smaller design
sizes.

* mf/feta-toevallig.mf (remember_pic): New variable, used for
testing.
(draw_meta_sharp): Much simplified.
("Sharp", "1/2 Sharp", "3/4 Sharp"): Don't rotate but shift.

* mf/feta-test-generic.mf: Include all files as in feta-generic.mf.

16 files changed:
ChangeLog
mf/feta-accordion.mf
mf/feta-banier.mf
mf/feta-bolletjes.mf
mf/feta-din-code.mf
mf/feta-eindelijk.mf
mf/feta-klef.mf
mf/feta-macros.mf
mf/feta-params.mf
mf/feta-pendaal.mf
mf/feta-puntje.mf
mf/feta-schrift.mf
mf/feta-slag.mf
mf/feta-test-generic.mf
mf/feta-timesig.mf
mf/feta-toevallig.mf

index 4da13a718134b5284c91740263d669b73404729a..6b8c56bc76861b331849a33f3ae8d003c2c427a5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,109 @@
+2005-01-12  Werner Lemberg  <wl@gnu.org>
+
+       This patch addresses the following problems in the feta sources
+       files which contribute to the fetaXX fonts.
+
+       . Many fixes for rasterization at low resolutions (consistent use of
+         `vround' and `hround', integer shift values for paths, applying
+         `eps' for mirrored paths, use of `define_whole_pixels' and
+         friends, etc.) -- while this probably looks like a waste of time
+         it has revealed deficiencies in some glyph shapes.  See comment at
+         the end of feta-params.mf how vertical symmetry is achieved.
+
+       . The `---' operator has been replaced everywhere with `--'; this
+         both improves and considerably reduces the font size after
+         conversion with mf2pt1.
+
+       These change aren't explicitly mentioned below since virtually all
+       glyphs are affected.
+
+       Other notable differences:
+
+       . Glyphs from feta-accordion.mf now have charboxes around the
+         outline.
+
+       . Fixed incorrect charbox for `accDot'.
+
+       . The `rcomma' and `lcomma' glyphs were distorted due to a typo.
+
+       . Fixed position of the bow in the `upprall' glyph and its siblings.
+
+       . The bulb size in the `2/2 meter' and `4/4 meter' glyphs is now
+         dependent on the staff line thickness to avoid touching the middle
+         staff line at smaller sizes.
+
+       . Largely extended output for feta-testXX: Where useful, glyphs
+       are shown both between and on staff lines.
+
+
+       * mf/feta-params.mf (staff_space_rounded,
+       stafflinethickness_rounded, linethickness_rounded,
+       ledgerlinethickness_rounded, stemthickness_rounded): New variables.
+       Update all code which uses them where appropriate.
+       (feta_eps, feta_shift, feta_space_shift, feta_offset, feta_fillpen):
+       New variables used to control rasterization at low resolutions.  Set
+       to zert if feta code is processed with metapost.
+
+       * mf/feta-macros.mf (draw_staff, draw_staff_outline): Updated.
+       (draw_rounded_block, draw_square_block): Updated to use `--' only.
+       (flare_path): Updated.
+       Make it work with `filldraw' (but only circular pens).
+       (hfloor, vfloor, hceiling, vceiling): New macros.
+
+       * mf/feta-params.mf (to_bp): New macro for mf2pt1.
+       (set_char_box): Updated.
+       Add code which emits specials for mf2pt1 if run with metapost.
+
+       * mf/feta-accordion.mf ("accDiscant", "accFreebase", "accStdbase"):
+       Use `draw' again in mf mode to have good pixel dropout control.
+       Fix intersection points of horizontal lines with circle.
+       ("accDot"): Fix parameters for set_char_box.
+       ("accOldEE"): Use `draw' again in mf mode to have good pixel dropout
+       control.
+
+       * mf/feta-banier.mf: Updated.
+
+       * mf/feta-bolletjes.mf (remember_pic): New variable, used for
+       testing.
+       (undraw_inside_ellipse): Remove `center' argument.  Update all
+       callers.
+       (draw_brevis): New macro, called by "Brevis notehead".
+       (draw_whole_triangle_head): New macro, called by "Whole
+       trianglehead".
+       (draw_small_triangle_head): Use `filldraw'.
+
+       * mf/feta-eindelijk.mf: Remove useless global group.
+       Updated.
+
+       * mf/feta-klef.mf (draw_c_clef): Correct point positions for using
+       `filldraw'.
+
+       * mf/feta-pendaal.mf: Updated.
+
+       * mf/feta-puntje.mf: Updated.
+
+       * mf/feta-schrift.mf (draw_very_long_fermata): Simplified to use
+       less points.
+       ("Flageolet"): Use `draw' again in mf mode to have good pixel
+       dropout control.
+       ("Varied Coda"): Use `draw_block'.
+       (draw_comma): Fix typo.
+       (draw_arpeggio_arrow): Use `draw' also in mf mode to have good
+       pixel dropout control.
+
+       * mf/feta-slag.mf ("upprall", "downprall", "lineprall"): Fix start
+       position of bow.
+
+       * mf/feta-timesig.mf (draw_C): Reduce bulb size for smaller design
+       sizes.
+
+       * mf/feta-toevallig.mf (remember_pic): New variable, used for
+       testing.
+       (draw_meta_sharp): Much simplified.
+       ("Sharp", "1/2 Sharp", "3/4 Sharp"): Don't rotate but shift.
+
+       * mf/feta-test-generic.mf: Include all files as in feta-generic.mf.
+
 2005-01-13  Mats Bengtsson  <mabe@drongo.s3.kth.se>
 
        * Documentation/user/notation.itely (Ancient rests): Fix typo
index 5da0be8a57ea4888a892ae3f681ff17997626fb3..e362826faa62eafc64b9aa7bc8b1e6ca6141f5e2 100644 (file)
@@ -1,61 +1,79 @@
 % -*- Fundamental -*-
 
-fet_begingroup ("accordion")
+fet_begingroup ("accordion");
 
-accreg_dot_size# := .5 staff_space#;
-accreg_linethickness# := 1.3 stafflinethickness#;
 
 %
-% This dimension is the same for all register symbols.
-% The different symbols should calculate their other
-% dimensions from this and accreg_dot_size.
+% These dimensions are the same for all register symbols.
+% The different symbols should calculate their other dimensions from them.
 %
 
+accreg_dot_size# := .5 staff_space#;
+accreg_linethickness# := 1.3 stafflinethickness#;
 accreg_lh# := 1.0 staff_space#;
 
 define_pixels (accreg_dot_size, accreg_linethickness, accreg_lh);
 
 
 fet_beginchar ("accDiscant", "accDiscant")
-       save r, p;
+       save r, p, lh, lt;
        path p;
 
        r# = 3/2 accreg_lh#;
        define_pixels (r);
 
-       set_char_box (r#, r#, 0, 2 r#);
+       set_char_box (r# + accreg_linethickness# / 2,
+                     r# + accreg_linethickness# / 2,
+                     0, 2 r# + 0.7 accreg_linethickness#);
 
-       penpos1 (accreg_linethickness, 0);
-       penpos2 (0.7 accreg_linethickness, 90);
-       penpos3 (accreg_linethickness, 180);
-       penpos4 (0.7 accreg_linethickness, 270);
+       lh = vround (2/3 r);
+       lt = vround (0.7 accreg_linethickness);
 
-       z1 = (r, r);
-       z2 = (0, 2 r);
-       z3 = (-r, r);
-       z4 = (0, 0);
+       h := 3 lh + lt;
+       b := w := (3 lh + hround accreg_linethickness) / 2;
+
+       penpos1 (hround accreg_linethickness, 0);
+       penpos2 (lt, 90);
+       penpos3 (hround accreg_linethickness, 180);
+       penpos4 (lt, 270);
+
+       z1r = (w, h / 2);
+       z2r = (0, h);
+       z3r = (-b, h / 2);
+       z4r = (0, 0);
 
        penlabels (1, 2, 3, 4);
 
-       penstroke z1e
-                 .. z2e
-                 .. z3e
-                 .. z4e
-                 .. cycle;
+       % mf doesn't handle pixel dropouts in outline objects, so we use
+       % `draw' if not called by mpost
+       if known miterlimit:
+               penstroke z1e
+                         .. z2e
+                         .. z3e
+                         .. z4e
+                         .. cycle;
+       else:
+               pickup pencircle xscaled accreg_linethickness yscaled lt;
+               draw z1
+                    .. z2
+                    .. z3
+                    .. z4
+                    .. cycle;
+       fi;
 
        p := z4{right}
             .. z1{up}
             .. {left}z2;
 
-       z5 = p intersectionpoint ((0, 4/3 r) -- (r, 4/3 r));
+       pickup penrazor scaled lt rotated 90;
+
+       top z5 = p intersectionpoint ((0, lh + lt) -- (w, lh + lt));
        z6 = z5 xscaled -1;
-       z7 = p intersectionpoint ((0, 2/3 r) -- (r, 2/3 r));
+       bot z7 = p intersectionpoint ((0, 2 lh) -- (w, 2 lh));
        z8 = z7 xscaled -1;
 
        labels (5, 6, 7, 8);
 
-       pickup penrazor scaled 0.7 accreg_linethickness rotated 90;
-
        draw z5
             -- z6;
        draw z7
@@ -64,42 +82,65 @@ fet_endchar;
 
 
 fet_beginchar ("accDot", "accDot")
-       set_char_box (accreg_dot_size#, accreg_dot_size#, 0, 0);
+       set_char_box (accreg_dot_size# / 2, accreg_dot_size# / 2,
+                     accreg_dot_size# / 2, accreg_dot_size# / 2);
 
        pickup pencircle scaled accreg_dot_size;
 
-       drawdot (0, 0);
+       rt x0 = hround (accreg_dot_size / 2);
+       top y0 = vround (accreg_dot_size / 2);
+
+       drawdot z0;
 fet_endchar;
 
 
 fet_beginchar ("accFreebase", "accFreebase")
-       save r, p;
+       save r, p, lh, lt;
        path p;
 
        r# = accreg_lh#;
        define_pixels (r);
 
-       set_char_box (r#, r#, 0, 2 r#);
+       set_char_box (r# + accreg_linethickness# / 2,
+                     r# + accreg_linethickness# / 2,
+                     0, 2 r# + 0.7 accreg_linethickness#);
+
+       lh = vround r;
+       lt = vround (0.7 accreg_linethickness);
+
+       h := 2 lh + lt;
+       b := w := (2 lh + hround accreg_linethickness) / 2;
 
-       penpos1 (accreg_linethickness, 0);
-       penpos2 (0.7 accreg_linethickness, 90);
+       penpos1 (hround accreg_linethickness, 0);
+       penpos2 (lt, 90);
        penpos3 (accreg_linethickness, 180);
-       penpos4 (0.7 accreg_linethickness, 270);
+       penpos4 (lt, 270);
 
-       z1 = (r, r);
-       z2 = (0, 2 r);
-       z3 = (-r, r);
-       z4 = (0, 0);
+       z1r = (w, h / 2);
+       z2r = (0, h);
+       z3r = (-b, h / 2);
+       z4r = (0, 0);
 
        penlabels (1, 2, 3, 4);
 
-       penstroke z1e
-                 .. z2e
-                 .. z3e
-                 .. z4e
-                 .. cycle;
-
-       pickup penrazor scaled 0.7 accreg_linethickness rotated 90;
+       % mf doesn't handle pixel dropouts in outline objects, so we use
+       % `draw' if not called by mpost
+       if known miterlimit:
+               penstroke z1e
+                         .. z2e
+                         .. z3e
+                         .. z4e
+                         .. cycle;
+       else:
+               pickup pencircle xscaled accreg_linethickness yscaled lt;
+               draw z1
+                    .. z2
+                    .. z3
+                    .. z4
+                    .. cycle;
+       fi;
+
+       pickup penrazor scaled lt rotated 90;
 
        draw z1
             -- z3;
@@ -107,45 +148,64 @@ fet_endchar;
 
 
 fet_beginchar ("accStdbase", "accStdbase")
-       save r, p;
+       save r, p, lh, lt;
        path p;
 
        r# = 2 accreg_lh#;
        define_pixels (r);
 
-       set_char_box (r#, r#, 0, 2 r#);
+       set_char_box (r# + accreg_linethickness# / 2,
+                     r# + accreg_linethickness# / 2,
+                     0, 2 r# + 0.7 accreg_linethickness#);
 
-       penpos1 (accreg_linethickness, 0);
-       penpos2 (0.7 accreg_linethickness, 90);
-       penpos3 (accreg_linethickness, 180);
-       penpos4 (0.7 accreg_linethickness, 270);
+       lh = vround (1/2 r);
+       lt = vround (0.7 accreg_linethickness);
 
-       z1 = (r, r);
-       z2 = (0, 2 r);
-       z3 = (-r, r);
-       z4 = (0, 0);
+       h := 4 lh + lt;
+       b := w := (4 lh + hround accreg_linethickness) / 2;
+
+       penpos1 (hround accreg_linethickness, 0);
+       penpos2 (lt, 90);
+       penpos3 (hround accreg_linethickness, 180);
+       penpos4 (lt, 270);
+
+       z1r = (w, h / 2);
+       z2r = (0, h);
+       z3r = (-b, h / 2);
+       z4r = (0, 0);
 
        penlabels (1, 2, 3, 4);
 
-       penstroke z1e
-                 .. z2e
-                 .. z3e
-                 .. z4e
-                 .. cycle;
+       % mf doesn't handle pixel dropouts in outline objects, so we use
+       % `draw' if not called by mpost
+       if known miterlimit:
+               penstroke z1e
+                         .. z2e
+                         .. z3e
+                         .. z4e
+                         .. cycle;
+       else:
+               pickup pencircle xscaled accreg_linethickness yscaled lt;
+               draw z1
+                    .. z2
+                    .. z3
+                    .. z4
+                    .. cycle;
+       fi;
 
        p := z4{right}
             .. z1{up}
             .. {left}z2;
 
-       z5 = p intersectionpoint ((0, 3/2 r) -- (r, 3/2 r));
+       pickup penrazor scaled lt rotated 90;
+
+       top z5 = p intersectionpoint ((0, lh + lt) -- (w, lh + lt));
        z6 = z5 xscaled -1;
-       z7 = p intersectionpoint ((0, 1/2 r) -- (r, 1/2 r));
+       bot z7 = p intersectionpoint ((0, 3 lh) -- (w, 3 lh));
        z8 = z7 xscaled -1;
 
        labels (5, 6, 7, 8);
 
-       pickup penrazor scaled 0.7 accreg_linethickness rotated 90;
-
        draw z1
             -- z3;
        draw z5
@@ -156,18 +216,40 @@ fet_endchar;
 
 
 fet_beginchar ("accBayanbase", "accBayanbase")
-       save lh;
-       lh = accreg_lh;
+       save lh, lt;
 
-       set_char_box (accreg_lh#, accreg_lh#, 0, 3 accreg_lh#);
+       lh = vround accreg_lh;
+       lt = vround accreg_linethickness;
 
-       draw_gridline ((-w, 0), (w, 0), accreg_linethickness);
-       draw_gridline ((-w, lh),(w, lh), accreg_linethickness);
-       draw_gridline ((-w, 2 lh), (w, 2 lh), accreg_linethickness);
-       draw_gridline ((-w, 3 lh), (w, 3 lh), accreg_linethickness);
+       set_char_box (accreg_lh# + accreg_linethickness# / 2,
+                     accreg_lh# + accreg_linethickness# / 2,
+                     0, 3 accreg_lh# + accreg_linethickness#);
 
-       draw_gridline ((-w, 0), (-w, 3 lh), accreg_linethickness);
-       draw_gridline ((w, 0), (w, 3 lh), accreg_linethickness);
+       h := 3 lh + lt;
+
+       draw_rounded_block ((-w, 0), (-w + lt, h), lt);
+       draw_rounded_block ((w - lt, 0), (w, h), lt);
+
+       pickup penrazor scaled lt rotated 90;
+
+       bot z1 = (-w + lt / 2, 0);
+       bot z2 = (-w + lt / 2, lh);
+       bot z3 = (-w + lt / 2, 2 lh);
+       bot z4 = (-w + lt / 2, 3 lh);
+
+       bot z5 = (w - lt / 2, 0);
+       bot z6 = (w - lt / 2, lh);
+       bot z7 = (w - lt / 2, 2 lh);
+       bot z8 = (w - lt / 2, 3 lh);
+
+       draw z1
+            -- z5;
+       draw z2
+            -- z6;
+       draw z3
+            -- z7;
+       draw z4
+            -- z8;
 fet_endchar;
 
 
@@ -262,19 +344,24 @@ enddef;
 
 
 fet_beginchar ("accOldEE", "accOldEE")
-       save pp;
+       save r, pp, ir, lh, lt, stroke_width;
 
-       set_char_box (staff_space#, staff_space#, 0, 2 staff_space#);
+       r# = staff_space#;
+       define_pixels (r);
 
-       r = staff_space;
        lr = .4 staff_space - linethickness;
        ir = .6 staff_space;
+       stroke_width = .05 staff_space + .5 linethickness;
+
+       set_char_box (r# + accreg_linethickness# / 2,
+                     r# + accreg_linethickness# / 2,
+                     0, 2 r# + 0.7 accreg_linethickness#);
 
        z1 = (0, 0);
        z2 = (0, ir);
 
        penpos1 (blot_diameter, 0);
-       penpos2 (.05 staff_space + .5 linethickness + blot_diameter, 0);
+       penpos2 (stroke_width + blot_diameter, 0);
 
        pickup pencircle scaled (lr + blot_diameter);
 
@@ -285,30 +372,48 @@ fet_beginchar ("accOldEE", "accOldEE")
                           -- z2e) rotated pp;
        endfor;
 
-       penpos3 (accreg_linethickness, 0);
-       penpos4 (0.7 accreg_linethickness, 90);
-       penpos5 (accreg_linethickness, 180);
-       penpos6 (0.7 accreg_linethickness, 270);
+       pickup pencircle scaled lr;
 
-       z3 = (r, 0);
-       z4 = (0, r);
-       z5 = (-r, 0);
-       z6 = (0, -r);
+       drawdot (0, 0);
 
-       % penlabels (1, 2, 3, 4, 5, 6);
+       currentpicture := currentpicture shifted (0, h / 2);
 
-       penstroke z3e
-                 .. z4e
-                 .. z5e
-                 .. z6e
-                 .. cycle;
+       lh = vround (2 r);
+       lt = vround (0.7 accreg_linethickness);
 
-       pickup pencircle scaled lr;
+       h := lh + lt;
+       b := w := (lh + hround accreg_linethickness) / 2;
 
-       drawdot (0, 0);
+       penpos3 (hround accreg_linethickness, 0);
+       penpos4 (lt, 90);
+       penpos5 (hround accreg_linethickness, 180);
+       penpos6 (lt, 270);
+
+       z3r = (w, h / 2);
+       z4r = (0, h);
+       z5r = (-b, h / 2);
+       z6r = (0, 0);
+
+       % penlabels (1, 2, 3, 4, 5, 6);
+
+       % mf doesn't handle pixel dropouts in outline objects, so we use
+       % `draw' if not called by mpost
+       if known miterlimit:
+               penstroke z3e
+                         .. z4e
+                         .. z5e
+                         .. z6e
+                         .. cycle;
+       else:
+               pickup pencircle xscaled accreg_linethickness yscaled lt;
+               draw z3
+                    .. z4
+                    .. z5
+                    .. z6
+                    .. cycle;
+       fi;
 
-       currentpicture := currentpicture shifted (0, r);
 fet_endchar;
 
 
-fet_endgroup ("accordion")
+fet_endgroup ("accordion");
index 7b21fd859fbbb476102f0814f150f806f22a960a..59f29545f162d247556254d38c5cdb1e66eb7108 100644 (file)
@@ -2,7 +2,7 @@
 %
 
 
-fet_begingroup ("flags")
+fet_begingroup ("flags");
 
 save outer_path;
 path outer_path;
@@ -25,7 +25,7 @@ right_downflag_space# = .0 downflag_width#;
 % Because of optical illusion, the utmost flag (bottom for
 % down-pointing, top for up-pointing) should be smaller than the other
 % flags.  Adobe Sonata doesn't do this correctly.  (Instead they have
-% an extension flag, which looks less elegant)
+% an extension flag, which looks less elegant.)
 %
 
 save hip_thickness, foot_thickness;
@@ -33,6 +33,8 @@ save hip_thickness, foot_thickness;
 hip_thickness# = 1.0 linethickness# + 0.069 staff_space#;
 foot_thickness# = 1.2055 linethickness# + 0.06 staff_space#;
 
+define_pixels (hip_thickness, foot_thickness);
+
 %
 % Inspired by Adobe Sonata and [Wanske].
 % For example, see POSTSCRIPT Language -- program design,
@@ -50,7 +52,7 @@ def draw_flag (expr center, flare, dims, hip_depth, foot_wid,
        penpos1 (flare, 90);
        penpos2 (whatever, 0);
 
-       x2r - x2l = hip_thickness;
+       x2r - x2l = hround (hip_thickness);
 
        penpos3 (foot_thickness, -20.0);
 
@@ -58,7 +60,12 @@ def draw_flag (expr center, flare, dims, hip_depth, foot_wid,
        z2r = center + (xpart (dims), -ypart (dims) * hip_depth);
        z3r = center + (xpart (dims) * foot_wid, -ypart (dims));
 
-       outer_path := z3r{curl c} .. z2r{up} .. {up}z1r;
+       x2r := hround x2r;
+       y2r := vround y2r;
+
+       outer_path := z3r{curl c}
+                     .. z2r{up}
+                     .. {up}z1r;
 
        if show_labels = 1:
                penlabels (1, 2, 3);
@@ -112,41 +119,43 @@ endgroup
 enddef;
 
 
-fet_beginchar ("8th Flag (up)", "u3")
+fet_beginchar ("8th Flag (up)", "u3");
        save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio;
 
-       flare# = 1.0 staff_space#;
+       flare = staff_space;
        hip_depth_ratio = .72;
        foot_width_ratio = .8;
        hip_width# = upflag_width# - hip_thickness# / 2;
        foot_depth# = 3 staff_space# - blot_diameter# / 2;
-       define_pixels (flare, hip_width, hip_thickness,
-                      foot_depth, foot_thickness);
+       define_pixels (hip_width, foot_depth);
 
-       set_char_box (0, hip_width# + stemthickness# / 2 + right_upflag_space#,
+       set_char_box (0,
+                     hip_width# + stemthickness# / 2 + right_upflag_space#,
                      foot_depth# + foot_thickness# / 2, stemthickness# / 2);
 
        draw_flag ((0,0), flare, (hip_width, foot_depth),
                   hip_depth_ratio, foot_width_ratio,
                   hip_thickness, foot_thickness, 1);
 
-       draw_square_block ((-.5 stemthickness, -staff_space), (0, 0));
+       draw_square_block ((-stemthickness_rounded, -staff_space_rounded),
+                          (0, 0));
 fet_endchar;
 
 
-fet_beginchar ("16th Flag (up)", "u4")
+fet_beginchar ("16th Flag (up)", "u4");
        save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio;
        save flagspace, total_depth, flag_count;
+
        total_depth# = 3.5 staff_space# - blot_diameter# / 2;
        flag_count = 2;
-       flare# = .85 staff_space#;
+       flare = .85 staff_space;
        flagspace# = .85 staff_space#;
        hip_depth_ratio = .72;
        hip_width# = upflag_width# - hip_thickness# / 2;
        flagspace# + foot_depth# = total_depth#;
        foot_width_ratio = .8;
-       define_pixels (flare, hip_width, hip_thickness, flagspace,
-                      foot_depth,  foot_thickness);
+       define_pixels (hip_width, foot_depth);
+       define_whole_vertical_pixels (flagspace);
 
        set_char_box (0,
                      hip_width# + stemthickness# / 2 + right_upflag_space#,
@@ -159,17 +168,18 @@ fet_beginchar ("16th Flag (up)", "u4")
        add_flag (flagspace, flare, .97, 1.00, 1.25,
                  hip_thickness, foot_thickness);
 
-       draw_square_block ((-.5 stemthickness, 0), (0, -2 staff_space));
+       draw_square_block ((-stemthickness_rounded, 0),
+                          (0, -2 staff_space_rounded));
 fet_endchar;
 
 
-fet_beginchar ("32nd Flag (up)", "u5")
+fet_beginchar ("32nd Flag (up)", "u5");
        save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio;
        save flagspace, total_depth, flag_count;
 
        flag_count = 3;
        total_depth# = 4.25 staff_space#;
-       flare# = .85 staff_space#;
+       flare = .85 staff_space;
        flagspace# = .87 staff_space#;
        hip_depth_ratio = .72;
        hip_width# = upflag_width# - hip_thickness# / 2;
@@ -177,8 +187,8 @@ fet_beginchar ("32nd Flag (up)", "u5")
 
        (flag_count - 1) * flagspace# + foot_depth# = total_depth#;
 
-       define_pixels (flare, hip_width, hip_thickness, flagspace,
-                      foot_depth, foot_thickness);
+       define_pixels (hip_width, foot_depth);
+       define_whole_vertical_pixels (flagspace);
 
        set_char_box (0, hip_width# + right_upflag_space#,
                      total_depth# + foot_thickness# / 2, stemthickness# / 2);
@@ -192,16 +202,17 @@ fet_beginchar ("32nd Flag (up)", "u5")
        add_flag (flagspace, flare, .95, 1.05, 1.25,
                  hip_thickness, foot_thickness);
 
-       draw_square_block ((-.5 stemthickness, 0), (0, -3 staff_space));
+       draw_square_block ((-stemthickness_rounded, 0),
+                          (0, -3 staff_space_rounded));
 fet_endchar;
 
 
-fet_beginchar ("64th Flag (up)", "u6")
+fet_beginchar ("64th Flag (up)", "u6");
        save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio;
        save flagspace, total_depth, flag_count;
 
        flag_count = 4;
-       flare# = .85 staff_space#;
+       flare = .85 staff_space;
        flagspace# = .9 staff_space#;
        hip_depth_ratio = .72;
        hip_width# = upflag_width# - hip_thickness# / 2;
@@ -210,8 +221,8 @@ fet_beginchar ("64th Flag (up)", "u6")
 
        (flag_count - 1) * flagspace# + foot_depth# = total_depth#;
 
-       define_pixels (flare, hip_width, hip_thickness, flagspace,
-                      foot_depth,  foot_thickness);
+       define_pixels (hip_width, foot_depth);
+       define_whole_vertical_pixels (flagspace);
 
        set_char_box (0, hip_width# + right_upflag_space#,
                      total_depth# + foot_thickness# / 2, stemthickness# / 2);
@@ -228,16 +239,17 @@ fet_beginchar ("64th Flag (up)", "u6")
        add_flag (flagspace, flare, .95, 1.05, 1.25,
                  hip_thickness, foot_thickness);
 
-       draw_square_block ((-.5 stemthickness, 0), (0, -4 staff_space));
+       draw_square_block ((-stemthickness_rounded, 0),
+                          (0, -4 staff_space_rounded));
 fet_endchar;
 
 
-fet_beginchar ("8th (down)", "d3")
+fet_beginchar ("8th (down)", "d3");
        save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio;
        save flagspace, total_depth, flag_count;
 
        flag_count = 1;
-       flare# = .99 staff_space#;
+       flare = .99 staff_space;
        flagspace# = .9 staff_space#;
        hip_depth_ratio = .72 ;
        hip_width# = downflag_width# - hip_thickness# / 2;
@@ -246,8 +258,7 @@ fet_beginchar ("8th (down)", "d3")
 
        (flag_count - 1) * flagspace# + foot_depth# = total_depth#;
 
-       define_pixels (flare, hip_width, hip_thickness, flagspace,
-                      foot_depth, foot_thickness);
+       define_pixels (hip_width, flagspace, foot_depth);
 
        set_char_box (0, hip_width# + right_downflag_space#,
                      total_depth# + foot_thickness# / 2, stemthickness# / 2)
@@ -257,7 +268,8 @@ fet_beginchar ("8th (down)", "d3")
                   hip_depth_ratio, foot_width_ratio,
                   hip_thickness, foot_thickness, 0);
 
-       draw_square_block ((-.5 stemthickness, 0), (0, -staff_space));
+       draw_square_block ((-stemthickness_rounded, 0),
+                          (0, -staff_space_rounded));
 
        y_mirror_char;
 fet_endchar;
@@ -268,16 +280,15 @@ fet_endchar;
 % Single Stroke for Short Appogiatura
 %
 
-fet_beginchar ("grace dash (up)", "ugrace")
+fet_beginchar ("grace dash (up)", "ugrace");
        save flare, hip_depth_ratio, hip_width, foot_depth;
 
-       flare# = staff_space#;
        hip_depth_ratio = .72;
+       flare# = staff_space#;
        hip_width# = upflag_width# - hip_thickness# / 2;
        foot_depth# = 3 staff_space#;
 
-       define_pixels (flare, hip_width, hip_thickness,
-                      foot_depth, foot_thickness);
+       define_pixels (hip_width, foot_depth);
 
        set_char_box (hip_width# * hip_depth_ratio,
                      hip_width# + right_upflag_space#,
@@ -292,11 +303,11 @@ fet_beginchar ("grace dash (up)", "ugrace")
        penpos2 (1.5 stemthickness, angle (z2 - z1) - 90);
 
        fill z1l
-            --- z2l
+            -- z2l
             .. top z2
             .. rt z2
             .. z2r
-            --- z1r
+            -- z1r
             .. bot z1
             .. lft z1
             .. cycle;
@@ -305,20 +316,18 @@ fet_beginchar ("grace dash (up)", "ugrace")
 fet_endchar;
 
 
-fet_beginchar ("grace dash (down)", "dgrace")
+fet_beginchar ("grace dash (down)", "dgrace");
        save flare, hip_depth_ratio, hip_width, foot_depth;
-       save flagspace, total_depth;
+       save total_depth;
 
-       flare# = .99 staff_space#;
-       flagspace# = .9 staff_space#;
        hip_depth_ratio = .72 ;
+       flare# = .99 staff_space#;
        hip_width# = downflag_width# - hip_thickness# / 2;
        total_depth# = 2.85 staff_space#;
        foot_depth# = total_depth#;
        foot_width_ratio = .8;
 
-       define_pixels (flare, hip_width, hip_thickness,
-                      flagspace, foot_depth);
+       define_pixels (hip_width, foot_depth);
 
        set_char_box (hip_width# * hip_depth_ratio,
                      hip_width# + right_downflag_space#,
@@ -333,11 +342,11 @@ fet_beginchar ("grace dash (down)", "dgrace")
        penpos2 (1.5 stemthickness, angle (z2 - z1) - 90);
 
        fill z1l
-            --- z2l
+            -- z2l
             .. top z2
             .. rt z2
             .. z2r
-            --- z1r
+            -- z1r
             .. bot z1
             .. lft z1
             .. cycle;
@@ -346,12 +355,12 @@ fet_beginchar ("grace dash (down)", "dgrace")
 fet_endchar;
 
 
-fet_beginchar ("16th (down)", "d4")
+fet_beginchar ("16th (down)", "d4");
        save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio;
        save flagspace, total_depth, flag_count;
 
        flag_count = 2;
-       flare# = .8 staff_space#;
+       flare = .8 staff_space;
        flagspace# = .9 staff_space#;
        hip_depth_ratio = .85;
        hip_width# = downflag_width# - hip_thickness# / 2;
@@ -363,8 +372,8 @@ fet_beginchar ("16th (down)", "d4")
        set_char_box (0, hip_width# + right_downflag_space#,
                      total_depth# + foot_thickness# / 2, stemthickness# / 2);
 
-       define_pixels (flare, hip_width, hip_thickness, flagspace,
-                      foot_depth, foot_thickness);
+       define_pixels (hip_width, foot_depth);
+       define_whole_vertical_pixels (flagspace);
 
        draw_flag ((0, -(flag_count - 1) * flagspace), flare,
                   (hip_width, foot_depth),
@@ -374,18 +383,19 @@ fet_beginchar ("16th (down)", "d4")
        add_flag (flagspace, flare, .95, 1.00, 1.25,
                  hip_thickness, foot_thickness);
 
-       draw_square_block ((-.5 stemthickness, 0), (0, -2 staff_space));
+       draw_square_block ((-stemthickness_rounded, 0),
+                          (0, -2 staff_space_rounded));
 
        y_mirror_char;
 fet_endchar;
 
 
-fet_beginchar ("32nd (down)", "d5")
+fet_beginchar ("32nd (down)", "d5");
        save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio;
        save flagspace, total_depth, flag_count;
 
        flag_count = 3;
-       flare# = .84 staff_space#;
+       flare = .84 staff_space;
        flagspace# = .9 staff_space#;
        hip_depth_ratio = .85;
        hip_width# = downflag_width# - hip_thickness# / 2;
@@ -394,8 +404,8 @@ fet_beginchar ("32nd (down)", "d5")
 
        (flag_count - 1) * flagspace# + foot_depth# = total_depth#;
 
-       define_pixels (flare, hip_width, hip_thickness, flagspace,
-                      foot_depth,  foot_thickness);
+       define_pixels (hip_width, foot_depth);
+       define_whole_vertical_pixels (flagspace);
 
        set_char_box (0, hip_width# + right_downflag_space#,
                      total_depth# + foot_thickness# / 2, stemthickness# / 2);
@@ -410,18 +420,19 @@ fet_beginchar ("32nd (down)", "d5")
        add_flag (flagspace, flare, .95, 1.05, 1.25,
                  hip_thickness, foot_thickness);
 
-       draw_square_block ((-.5 stemthickness, 0), (0, -3 staff_space));
+       draw_square_block ((-stemthickness_rounded, 0),
+                          (0, -3 staff_space_rounded));
 
        y_mirror_char;
 fet_endchar;
 
 
-fet_beginchar ("64th (down)", "d6")
+fet_beginchar ("64th (down)", "d6");
        save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio;
        save flagspace, total_depth, flag_count;
 
        flag_count = 4;
-       flare# = .8 staff_space#;
+       flare = .8 staff_space;
        flagspace# = .9 staff_space#;
        hip_depth_ratio = .85;
        hip_width# = downflag_width# - hip_thickness# / 2;
@@ -430,8 +441,8 @@ fet_beginchar ("64th (down)", "d6")
 
        (flag_count - 1) * flagspace# + foot_depth# = total_depth#;
 
-       define_pixels (flare, hip_width, hip_thickness, flagspace,
-                      foot_depth, foot_thickness);
+       define_pixels (hip_width, foot_depth);
+       define_whole_vertical_pixels (flagspace);
 
        set_char_box (0, hip_width# + right_downflag_space#,
                      total_depth# + foot_thickness# / 2, stemthickness# / 2);
@@ -448,7 +459,8 @@ fet_beginchar ("64th (down)", "d6")
        add_flag (.98 flagspace, flare, .91, 1.05, 1.2,
                  hip_thickness, foot_thickness);
 
-       draw_square_block ((-.5 stemthickness, 0), (0, -4 staff_space));
+       draw_square_block ((-stemthickness_rounded, 0),
+                          (0, -4 staff_space_rounded));
 
        y_mirror_char;
 fet_endchar;
index 1331fecffd6c84074b0a867363b012156d3ae7b9..d082c8cc2ed7ea7db34defe2fd6e10e4e2870d64 100644 (file)
 test_outlines := 0;
 
 
+save remember_pic;
+picture remember_pic;
+
+
 % Most beautiful noteheads are pronounced, not circular,
 % and not even symmetric.
 % These examples are inspired by [Wanske]; see literature list.
@@ -39,12 +43,13 @@ slash_thick# := 2/3 * 0.48 staff_space#;
 %
 % Hand-engraved music often has balls extending above and below
 % the lines.  If you like that, modify overdone heads (unit:
-% stafflinethickness)
+% stafflinethickness).
 %
 overdone_heads = 0.0;
 noteheight# := staff_space# + (1 + overdone_heads) * stafflinethickness#;
 
-define_pixels (slash_thick, noteheight);
+define_pixels (slash_thick);
+define_whole_vertical_pixels (noteheight);
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -60,7 +65,7 @@ def draw_outside_ellipse (expr ellipticity, tilt, superness, slant) =
        path p;
 
        p := superellipse ((ellipticity, 0), (-slant * ellipticity, 1.0),
-                          (- ellipticity, 0), (slant * ellipticity, -1.0),
+                          (-ellipticity, 0), (slant * ellipticity, -1.0),
                           superness);
        p := p rotated tilt;
 
@@ -70,22 +75,25 @@ def draw_outside_ellipse (expr ellipticity, tilt, superness, slant) =
        top_point := directionpoint left of p;
        right_point := directionpoint up of p;
 
-       save scaling, width, height;
+       save scaling, width;
 
        scaling# = noteheight# / (2 ypart (top_point));
        width# := 2 xpart (right_point) * scaling#;
-
-       define_pixels (width, scaling);
+       define_pixels (scaling, width);
 
        set_char_box (0, width#, noteheight# / 2, noteheight# / 2);
 
+       d := d - feta_space_shift;
+
        % attachment Y
        charwy := ypart (right_point) * scaling#;
        charwx := width#;
 
-       p := p scaled scaling shifted (width / 2, 0);
+       p := p scaled scaling shifted (w / 2, .5 (h - d));
+
+       width := hround width;
+
        if test_outlines = 1:
-               pickup pencircle scaled 1;
                draw p;
        else:
                fill p;
@@ -93,8 +101,7 @@ def draw_outside_ellipse (expr ellipticity, tilt, superness, slant) =
 enddef;
 
 
-def undraw_inside_ellipse (expr ellipticity, tilt, superness, clearance,
-                          center) =
+def undraw_inside_ellipse (expr ellipticity, tilt, superness, clearance) =
 begingroup
        save p;
        path p;
@@ -114,12 +121,10 @@ begingroup
 
        height# = staff_space# + stafflinethickness# - clearance;
        scaling# = height# / (2 ypart (top_point));
-
        define_pixels (scaling);
-       p := (p scaled scaling) shifted center;
+       p := (p scaled scaling) shifted (w / 2, .5 (h - d));
 
        if test_outlines = 1:
-               pickup pencircle scaled 1;
                draw p;
        else:
                unfill p;
@@ -131,15 +136,16 @@ enddef;
 %
 % dimensions aren't entirely right.
 %
-fet_beginchar ("Brevis notehead", "s-1");
+def draw_brevis =
        save stemthick, fudge;
-       define_pixels (stemthick);
-       fudge = blot_diameter / 2;
+
        stemthick# = 2 stafflinethickness#;
+       define_whole_blacker_pixels (stemthick);
+
+       fudge = hround (blot_diameter / 2);
 
        draw_outside_ellipse (1.80, 0, 0.707, 0);
-       undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#,
-                              (w / 2, 0));
+       undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#);
 
        pickup pencircle scaled stemthick;
 
@@ -155,55 +161,145 @@ fet_beginchar ("Brevis notehead", "s-1");
 
        draw_gridline (z1, z2, stemthick);
        draw_gridline (z3, z4, stemthick);
+enddef;
+
+
+fet_beginchar ("Brevis notehead", "s-1");
+       draw_brevis;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Whole notehead", "s0")
+if test > 0:
+       fet_beginchar ("Brevis notehead", "s-1");
+               draw_brevis;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Whole notehead", "s0");
        draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0, 0.707, 0);
        undraw_inside_ellipse (1.30, 125 - puff_up_factor * 10,
-                              0.68, 2 stafflinethickness#, (w / 2, 0));
+                              0.68, 2 stafflinethickness#);
 
-%      draw_staff_outline (-2, 2, 0.5);
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Half notehead", "s1")
+if test > 0:
+       fet_beginchar ("Whole notehead", "s0");
+               draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0,
+                                     0.707, 0);
+               undraw_inside_ellipse (1.30, 125 - puff_up_factor * 10,
+                                      0.68, 2 stafflinethickness#);
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Half notehead", "s1");
        draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17);
-       undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#,
-                              (w / 2, 0));
+       undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
-fet_beginchar ("Quart notehead", "s2")
+
+if test > 0:
+       fet_beginchar ("Half notehead", "s1");
+               draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34,
+                                     0.66, 0.17);
+               undraw_inside_ellipse (3.25, 33, 0.81,
+                                      2.5 stafflinethickness#);
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Quart notehead", "s2");
        % used to have 32. With 31, they are slightly bolder.
        draw_outside_ellipse (1.49 - puff_up_factor / 3.0, 31, 0.707, 0);
        black_notehead_width# := charwd;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
+if test > 0:
+       fet_beginchar ("Quart notehead", "s2");
+               draw_outside_ellipse (1.49 - puff_up_factor / 3.0, 31,
+                                     0.707, 0);
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
-fet_beginchar ("Whole diamondhead", "s0diamond")
+fet_beginchar ("Whole diamondhead", "s0diamond");
        draw_outside_ellipse (1.80, 0, 0.495, 0);
        undraw_inside_ellipse (1.30, 125, 0.6,
-                              .4 staff_space# +  stafflinethickness#,
-                              (w / 2, 0));
+                              .4 staff_space# + stafflinethickness#);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Half diamondhead", "s1diamond")
+if test > 0:
+       fet_beginchar ("Whole diamondhead", "s0diamond");
+               draw_outside_ellipse (1.80, 0, 0.495, 0);
+               undraw_inside_ellipse (1.30, 125, 0.6,
+                                      .4 staff_space# + stafflinethickness#);
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Half diamondhead", "s1diamond");
        draw_outside_ellipse (1.50, 34, 0.49, 0.17);
        undraw_inside_ellipse (3.5, 33, 0.80,
-                              .3 staff_space# + 1.5 stafflinethickness#,
-                              (w / 2, 0));
+                              .3 staff_space# + 1.5 stafflinethickness#);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Quart diamondhead", "s2diamond")
+if test > 0:
+       fet_beginchar ("Half diamondhead", "s1diamond");
+               draw_outside_ellipse (1.50, 34, 0.49, 0.17);
+               undraw_inside_ellipse (3.5, 33, 0.80,
+                                      .3 staff_space#
+                                      + 1.5 stafflinethickness#);
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Quart diamondhead", "s2diamond");
        draw_outside_ellipse (1.80, 35, 0.495, -0.25);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
+if test > 0:
+       fet_beginchar ("Quart diamondhead", "s2diamond");
+               draw_outside_ellipse (1.80, 35, 0.495, -0.25);
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
@@ -239,7 +335,8 @@ def define_triangle_shape (expr stemdir) =
 
        save pen_thick;
        pen_thick# = stafflinethickness# + .1 staff_space#;
-       define_pixels (pen_thick, llap);
+       define_pixels (llap);
+       define_blacker_pixels (pen_thick);
 
        left_up_dir = llap# * dir (90 + tilt);
 
@@ -339,7 +436,7 @@ def define_triangle_shape (expr stemdir) =
 enddef;
 
 
-fet_beginchar ("Whole trianglehead", "s0triangle")
+def draw_whole_triangle_head =
        save hei, xs;
        save llap;
        save tilt;
@@ -352,9 +449,25 @@ fet_beginchar ("Whole trianglehead", "s0triangle")
        define_triangle_shape (1);
        fill triangle_out;
        unfill triangle_in;
+enddef;
+
+
+fet_beginchar ("Whole trianglehead", "s0triangle");
+       draw_whole_triangle_head;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
+if test > 0:
+       fet_beginchar ("Whole trianglehead", "s0triangle");
+               draw_whole_triangle_head;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
 def draw_small_triangle_head (expr dir) =
        save hei, xs;
        save llap;
@@ -365,18 +478,25 @@ def draw_small_triangle_head (expr dir) =
        xs = 1.2;
        caveness := 0.1;
        define_triangle_shape (dir);
-       fill triangle_out;
-       unfill triangle_in;
+
+       pickup feta_fillpen;
+
+       filldraw triangle_out;
+       unfilldraw triangle_in;
 enddef;
 
 
-fet_beginchar ("Half trianglehead", "d1triangle")
+fet_beginchar ("Half trianglehead", "d1triangle");
        draw_small_triangle_head (-1);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Half trianglehead", "u1triangle")
+fet_beginchar ("Half trianglehead", "u1triangle");
        draw_small_triangle_head (1);
+
+       draw_staff (-2, 2, 0.5);
 fet_endchar;
 
 
@@ -394,13 +514,17 @@ def draw_closed_triangle_head (expr dir) =
 enddef;
 
 
-fet_beginchar ("Quart trianglehead", "u2triangle")
+fet_beginchar ("Quart trianglehead", "u2triangle");
        draw_closed_triangle_head (1);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Quart trianglehead", "d2triangle")
+fet_beginchar ("Quart trianglehead", "d2triangle");
        draw_closed_triangle_head (-1);
+
+       draw_staff (-2, 2, 0.5);
 fet_endchar;
 
 
@@ -422,6 +546,9 @@ def draw_slash (expr hwid_hash) =
        charwy := charht;
 
        clearxy;
+
+       d := d - feta_shift;
+
        pickup pencircle scaled blot_diameter;
 
        bot y1 = -d;
@@ -434,16 +561,17 @@ def draw_slash (expr hwid_hash) =
        y4 = y1;
        x3 - x2 = x4 - x1;
 
-       ne_dir := unitvector (z3  - z4);
-       fill bot z1
-            .. lft z1
-            --- lft z2
-            .. top z2
-            --- top z3
-            .. rt z3
-            --- rt z4
-            .. bot z4
-            --- cycle;
+       ne_dir := unitvector (z3 - z4);
+
+       fill bot z1{left}
+            .. lft z1{ne_dir}
+            -- lft z2{ne_dir}
+            .. top z2{right}
+            -- top z3{right}
+            .. rt z3{-ne_dir}
+            -- rt z4{-ne_dir}
+            .. bot z4{left}
+            -- cycle;
 
        if hwid_hash > 2 slash_thick#:
                save th;
@@ -469,18 +597,24 @@ def draw_slash (expr hwid_hash) =
 enddef;
 
 
-fet_beginchar ("Whole slashhead", "s0slash")
+fet_beginchar ("Whole slashhead", "s0slash");
        draw_slash (4 slash_thick# + 0.5 staff_space#);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Half slashhead", "s1slash")
+fet_beginchar ("Half slashhead", "s1slash");
        draw_slash (3.0 slash_thick# + 0.15 staff_space#);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Quart slashhead", "s2slash")
+fet_beginchar ("Quart slashhead", "s2slash");
        draw_slash (1.5 slash_thick#);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
@@ -493,13 +627,19 @@ def draw_cross (expr thick) =
        save ne_dir, nw_dir;
        save horz_dist, vert_dist;
        save crz_in, crz_out;
+       save thickness;
        pair ne_dir, nw_dir;
        path crz_in, crz_out;
 
        pen_thick# := 1.2 stafflinethickness#;
-       define_pixels (pen_thick);
+       thickness# := thick * stafflinethickness#;
+       define_pixels (thickness);
+       define_blacker_pixels (pen_thick);
+
        pickup pencircle scaled pen_thick;
 
+       h := h - feta_shift;
+
        top y3 = h;
        ne_dir := unitvector ((1, (2 h - pen_thick) / (w - pen_thick)));
        rt x4 = w / 2;
@@ -509,8 +649,8 @@ def draw_cross (expr thick) =
        z6 - z3 = whatever * ne_dir;
        z3 - z4 = whatever * (ne_dir yscaled -1);
 
-       z4 - z3 = whatever * (ne_dir)
-                 + (ne_dir rotated -90) * thick * stafflinethickness;
+       z4 - z3 = whatever * (ne_dir) + (ne_dir rotated -90) * thickness;
+
 
        x1 = charwd / 2 - .5 pen_thick#;
        z1 = whatever * ne_dir
@@ -521,113 +661,216 @@ def draw_cross (expr thick) =
        nw_dir = unitvector (z3 - z4);
 
        vert_dist = 0.5 pen_thick / cosd (angle (ne_dir));
-       horz_dist = 0.5 pen_thick / sind (angle (nw_dir));
+       horz_dist = 0.5 pen_thick / sind (angle (ne_dir));
+
+       x4' := x4;
+       x5' := x5;
+       y6' := y6;
+
+       x4 := hround (x4' + .5 pen_thick) - .5 pen_thick;
+       x5 := hfloor (x5' + horz_dist) - horz_dist;
+       y6 := vfloor (y6' + vert_dist) - vert_dist;
 
        crz_out = (z6 + up * vert_dist)
-                 --- (z3 + nw_dir * 0.5 pen_thick)
+                 -- (z3 + nw_dir * 0.5 pen_thick){ne_dir}
                  .. (top z3)
-                 .. (z3 + ne_dir * 0.5 pen_thick)
-                 --- (z4 + ne_dir * 0.5 pen_thick)
+                 .. (z3 + ne_dir * 0.5 pen_thick){-nw_dir}
+                 -- (z4 + ne_dir * 0.5 pen_thick){-nw_dir}
                  .. (rt z4)
-                 .. (z4 - nw_dir * 0.5 pen_thick)
-                 --- (z5 + right * horz_dist);
-       crz_out := crz_out
-                  & reverse crz_out yscaled -1;
-       crz_out := crz_out
-                  & reverse crz_out xscaled -1
-                  & cycle;
-       fill crz_out;
+                 .. (z4 - nw_dir * 0.5 pen_thick){-ne_dir}
+                 -- (z5 + right * horz_dist);
+       crz_out := crz_out shifted (0, feta_shift)
+                  -- reverse crz_out yscaled -1 shifted (0, -feta_eps);
+       fill crz_out
+            -- reverse crz_out xscaled -1 shifted (-feta_eps, 0)
+            -- cycle;
 
        if (thick > 1):
+               x4 := hround (x4' - horz_dist) + horz_dist;
+               x5 := hceiling (x5' - .5 pen_thick) + .5 pen_thick;
+               y6 := vfloor (y6' - .5 pen_thick) + .5 pen_thick;
+
                crz_in = (bot z6){right}
-                        .. (z6 - nw_dir * 0.5 pen_thick)
-                        --- (z3 + down * vert_dist)
-                        --- (z4 + left * horz_dist)
-                        --- (z5 + nw_dir * 0.5 pen_thick)
+                        .. (z6 - nw_dir * 0.5 pen_thick){ne_dir}
+                        -- (z3 + down * vert_dist)
+                        -- (z4 + left * horz_dist)
+                        -- (z5 + nw_dir * 0.5 pen_thick){-ne_dir}
                         .. {down}(lft z5);
-               crz_in := crz_in
-                         .. reverse crz_in yscaled -1;
-               crz_in := crz_in
-                         .. reverse crz_in xscaled -1
-                         .. cycle;
-               unfill crz_in;
+               crz_in := crz_in shifted (0, feta_shift)
+                         -- reverse crz_in yscaled -1 shifted (0, -feta_eps);
+               unfill crz_in
+                      -- reverse crz_in xscaled -1 shifted (-feta_eps, 0)
+                      -- cycle;
        fi
 
        % ugh
-       currentpicture := currentpicture shifted (w / 2, 0);
+       currentpicture := currentpicture shifted (hround (w / 2), 0);
 
        charwx := charwd;
-       charwy := y1;
+       charwy := y1 + feta_shift;
+
        z12 = (charwx * hppp, y1 * vppp);
+
        labels (12);
 enddef;
 
 
-fet_beginchar ("Whole Crossed notehead", "s0cross")
+fet_beginchar ("Whole Crossed notehead", "s0cross");
+       save wid, hei;
+
        wid# := black_notehead_width# + 4 stafflinethickness#;
        hei# := noteheight# + stafflinethickness#;
 
        set_char_box (0, wid#, hei# / 2, hei# / 2);
 
        draw_cross (3.75);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Half Crossed notehead", "s1cross")
+if test > 0:
+       fet_beginchar ("Whole Crossed notehead", "s0cross");
+               save wid, hei;
+
+               wid# := black_notehead_width# + 4 stafflinethickness#;
+               hei# := noteheight# + stafflinethickness#;
+
+               set_char_box (0, wid#, hei# / 2, hei# / 2);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Half Crossed notehead", "s1cross");
+       save wid, hei;
+
        wid# := black_notehead_width# + 2 stafflinethickness#;
        hei# := noteheight# + stafflinethickness# / 2;
 
        set_char_box (0, wid#, hei# / 2, hei# / 2);
 
        draw_cross (3.0);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Crossed notehead", "s2cross")
+if test > 0:
+       fet_beginchar ("Half Crossed notehead", "s1cross");
+               save wid, hei;
+
+               wid# := black_notehead_width# + 2 stafflinethickness#;
+               hei# := noteheight# + stafflinethickness# / 2;
+
+               set_char_box (0, wid#, hei# / 2, hei# / 2);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Crossed notehead", "s2cross");
        wid# := black_notehead_width#;
        hei# := noteheight#;
        set_char_box (0, wid#, hei# / 2, hei# / 2);
 
        draw_cross (1.0);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("X-Circled notehead", "s2xcircle")
+if test > 0:
+       fet_beginchar ("Crossed notehead", "s2cross");
+               wid# := black_notehead_width#;
+               hei# := noteheight#;
+               set_char_box (0, wid#, hei# / 2, hei# / 2);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("X-Circled notehead", "s2xcircle");
+       save wid, hei;
+       save cthick, cxd, cyd, dy;
+
        wid# := black_notehead_width# * sqrt (sqrt2);
        hei# := noteheight# * sqrt (sqrt2);
 
        set_char_box (0, wid#, hei# / 2, hei# / 2);
 
-       cthick := (1.2 + 1/4) * stafflinethickness;
-       cxr := w / 2 - cthick / 2;
-       cyr := h - cthick / 2;
+       d := d - feta_space_shift;
+
+       cthick# := (1.2 + 1/4) * stafflinethickness#;
+       define_blacker_pixels (cthick);
+
+       cxd := w - cthick;
+       cyd := h + d - cthick / 2;
+
+       dy = .5 (h - d);
 
        pickup pencircle scaled cthick;
 
-       fill fullcircle xscaled (2 cxr + cthick)
-                       yscaled (2 cyr + cthick)
-                       shifted (w / 2, 0);
-       unfill fullcircle xscaled (2 cxr - cthick)
-                         yscaled (2 cyr - cthick)
-                         shifted (w / 2, 0);
+       fill fullcircle xscaled (cxd + cthick)
+                       yscaled (cyd + cthick)
+                       shifted (w / 2, dy);
+       unfill fullcircle xscaled (cxd - cthick)
+                         yscaled (cyd - cthick)
+                         shifted (w / 2, dy);
 
-       xpos := cxr / sqrt2;
-       ypos := cyr / sqrt2;
+       xpos := .5 cxd / sqrt2;
+       ypos := .5 cyd / sqrt2;
 
        pickup penrazor scaled cthick rotated (angle (xpos, ypos) + 90);
-       draw (-xpos + w / 2, -ypos) -- (xpos + w / 2, ypos);
+       draw (-xpos + w / 2, -ypos + dy) -- (xpos + w / 2, ypos + dy);
 
        pickup penrazor scaled cthick rotated (angle (xpos, -ypos) + 90);
-       draw (-xpos + w / 2, ypos) -- (xpos + w / 2, -ypos);
+       draw (-xpos + w / 2, ypos + dy) -- (xpos + w / 2, -ypos + dy);
 
        charwx := charwd;
        charwy := 0;
 
        z12 = (charwx * hppp, charwy * vppp);
        labels (12);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
+if test > 0:
+       fet_beginchar ("X-Circled notehead", "s2xcircle");
+               save wid, hei;
+               save cthick, cxr, cyr;
+
+               wid# := black_notehead_width# * sqrt (sqrt2);
+               hei# := noteheight# * sqrt (sqrt2);
+
+               set_char_box (0, wid#, hei# / 2, hei# / 2);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
 %%%%%%%%
 %
 % SOLFA SHAPED NOTES
@@ -635,7 +878,7 @@ fet_endchar;
 
 save solfa_pen_thick;
 solfa_pen_thick# = 2 stafflinethickness#;
-define_pixels (solfa_pen_thick);
+define_blacker_pixels (solfa_pen_thick);
 
 
 def draw_do_head (expr width_factor, dir) =
@@ -668,15 +911,15 @@ def draw_do_head (expr width_factor, dir) =
                -- cycle;
 
        p_out := bot z1
-                --- bot z2
-                .. rt z2
-                .. (z2 + right_dist)
-                --- (z3 + right_dist)
-                .. top z3
-                .. (z3 + left_dist)
-                --- (z1 + left_dist)
-                .. lft z1
-                .. cycle;
+                -- bot z2{right}
+                .. rt z2{up}
+                .. (z2 + right_dist){z3 - z2}
+                -- (z3 + right_dist){z3 - z2}
+                .. top z3{left}
+                .. (z3 + left_dist){z1 - z3}
+                -- (z1 + left_dist){z1 - z3}
+                .. lft z1{down}
+                .. {right}cycle;
                 
 
        labels (1, 2, 3);
@@ -689,34 +932,34 @@ def draw_do_head (expr width_factor, dir) =
 enddef;
 
 
-fet_beginchar ("Whole dohead", "s0do")
+fet_beginchar ("Whole dohead", "s0do");
        draw_do_head (1.8, 1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Half dohead", "d1do")
+fet_beginchar ("Half dohead", "d1do");
        draw_do_head (1.5, -1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Half dohead", "s1do")
+fet_beginchar ("Half dohead", "s1do");
        draw_do_head (1.5, 1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Quart dohead", "d2do")
+fet_beginchar ("Quart dohead", "d2do");
        draw_do_head (1.55, -1);
        fill p_out;
 fet_endchar;
 
 
-fet_beginchar ("Quart dohead", "s2do")
+fet_beginchar ("Quart dohead", "s2do");
        draw_do_head (1.55, 1);
        fill p_out;
 fet_endchar;
@@ -745,7 +988,7 @@ def draw_re_head (expr width_factor, dir) =
        y1 = y5;
        x1 = x2;
        y2 = curve_start [y3, y1];
-       bot y3 = - d;
+       bot y3 = -d;
        x3 = .5 [x2, x4];
        rt x4 = w;
        y4 = y2;
@@ -755,58 +998,58 @@ def draw_re_head (expr width_factor, dir) =
        labels (range 1 thru 5);
 
        p_in := (z1 + 0.5 solfa_pen_thick * (1, -1))
-               --- rt z2
-               .. top z3{right}
-               .. lft z4
-               --- (z5 + 0.5 solfa_pen_thick * (-1, -1))
-               --- cycle;
+               -- rt z2{down}
+               .. top z3
+               .. lft z4{up}
+               -- (z5 + 0.5 solfa_pen_thick * (-1, -1))
+               -- cycle;
 
        p_out := lft z1
-                --- lft z2
-                .. bot z3{right}
-                .. rt z4
-                --- rt z5
-                .. top z5
-                --- top z1
-                .. cycle;
+                -- lft z2{down}
+                .. bot z3
+                .. rt z4{up}
+                -- rt z5{up}
+                .. top z5{left}
+                -- top z1{left}
+                .. {down}cycle;
 
        charwx := charwd;
        charwy := curve_start [-chardp, charht];
 
        if dir = -1:
-               charwy := - charwy;
+               charwy := -charwy;
        fi;
 enddef;
 
 
-fet_beginchar ("Whole rehead", "s0re")
+fet_beginchar ("Whole rehead", "s0re");
        draw_re_head (1.8, 1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Half up rehead", "u1re")
+fet_beginchar ("Half up rehead", "u1re");
        draw_re_head (1.5, 1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Half down rehead", "d1re")
+fet_beginchar ("Half down rehead", "d1re");
        draw_re_head (1.5, -1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Quart rehead", "u2re")
+fet_beginchar ("Quart rehead", "u2re");
        draw_re_head (1.55, 1);
        fill p_out;
 fet_endchar;
 
 
-fet_beginchar ("Quart rehead", "d2re")
+fet_beginchar ("Quart rehead", "d2re");
        draw_re_head (1.55, -1);
        fill p_out;
 fet_endchar;
@@ -814,9 +1057,9 @@ fet_endchar;
 
 def draw_mi_head (expr width_factor) =
        save path_out, path_in;
-       save ne_dist, nw_dist;
+       save ne_dist, se_dist, ne, se;
        path path_out, path_in;
-       pair ne_dist, nw_dist;
+       pair ne_dist, se_dist, ne, se;
 
        set_char_box (0, width_factor * noteheight#,
                      0.5 noteheight#, 0.5 noteheight#);
@@ -837,11 +1080,14 @@ def draw_mi_head (expr width_factor) =
        z8 - z5 = whatever * (z4 - z1);
        z6 - z7 = whatever * (z4 - z1);
 
-       ne_dist = (unitvector (z4 - z1) rotated 90) * 0.5 solfa_pen_thick;
-       nw_dist = (unitvector (z1 - z2) rotated 90) * 0.5 solfa_pen_thick;
+       ne = unitvector (z4 - z1);
+       se = unitvector (z1 - z2);
+
+       ne_dist = (ne rotated 90) * 0.5 solfa_pen_thick;
+       se_dist = (se rotated 90) * 0.5 solfa_pen_thick;
 
        z5 = whatever [z1, z4] - ne_dist;
-       z5 = whatever [z1, z2] - 1.5 nw_dist;
+       z5 = whatever [z1, z2] - 1.5 se_dist;
 
        z5 - z1 = -(z7 - z3);
 
@@ -854,36 +1100,36 @@ def draw_mi_head (expr width_factor) =
                   -- cycle;
 
        path_out := lft z1
-                   .. (z1 + nw_dist)
-                   --- (z2 + nw_dist)
+                   .. (z1 + se_dist){-se}
+                   -- (z2 + se_dist){-se}
                    .. bot z2
-                   .. (z2 - ne_dist)
-                   --- (z3 - ne_dist)
+                   .. (z2 - ne_dist){ne}
+                   -- (z3 - ne_dist){ne}
                    .. rt z3
-                   .. (z3 - nw_dist)
-                   --- (z4 - nw_dist)
+                   .. (z3 - se_dist){se}
+                   -- (z4 - se_dist){se}
                    .. top z4
-                   .. (z4 + ne_dist)
-                   --- (z1 + ne_dist)
+                   .. (z4 + ne_dist){-ne}
+                   -- (z1 + ne_dist){-ne}
                    .. cycle;
 enddef;
 
 
-fet_beginchar ("Whole mihead", "s0mi")
+fet_beginchar ("Whole mihead", "s0mi");
        draw_mi_head (1.8);
        fill path_out;
        unfill path_in;
 fet_endchar;
 
 
-fet_beginchar ("Half mihead", "s1mi")
+fet_beginchar ("Half mihead", "s1mi");
        draw_mi_head (1.6);
        fill path_out;
        unfill path_in;
 fet_endchar;
 
 
-fet_beginchar ("Quart mihead", "s2mi")
+fet_beginchar ("Quart mihead", "s2mi");
        draw_mi_head (1.65);
        fill path_out;
 fet_endchar;
@@ -893,9 +1139,9 @@ def draw_fa_head (expr width_factor) =
        set_char_box (0, width_factor * noteheight#,
                      0.5 noteheight#, 0.5 noteheight#);
 
-       save p_down_in, p_down_out, p_up_in, p_up_out, nw_dist;
+       save p_down_in, p_down_out, p_up_in, p_up_out, nw_dist, nw;
        path p_down_in, p_down_out, p_up_in, p_up_out;
-       pair nw_dist;
+       pair nw_dist, nw;
 
        pickup pencircle scaled solfa_pen_thick;
 
@@ -910,26 +1156,27 @@ def draw_fa_head (expr width_factor) =
        y4 = y3;
        x4 = x1;
 
-       labels (range 1 thru 4);
+       labels (1, 2, 3, 4);
 
-       nw_dist = (unitvector (z1 - z3) rotated 90) * 0.5 solfa_pen_thick;
+       nw = unitvector (z1 - z3);
+       nw_dist = (nw rotated 90) * 0.5 solfa_pen_thick;
 
        p_up_in := (((z1 - nw_dist) -- (z3 - nw_dist)) intersectionpoint
                     (bot z1 -- bot z2))
                   -- (((z1 - nw_dist) -- (z3 - nw_dist)) intersectionpoint
                        (lft z3 -- lft z2))
                   -- (z2 + 0.5 solfa_pen_thick * (-1, -1))
-                  --- cycle;
+                  -- cycle;
 
-       p_up_out := lft z1
-                   .. (z1 + nw_dist)
-                   --- (z3 + nw_dist)
-                   .. bot z3
-                   .. rt z3
-                   --- rt z2
-                   .. top z2
-                   --- top z1
-                   .. cycle;
+       p_up_out := lft z1{down}
+                   .. (z1 + nw_dist){-nw}
+                   -- (z3 + nw_dist){-nw}
+                   .. bot z3{right}
+                   .. rt z3{up}
+                   -- rt z2{up}
+                   .. top z2{left}
+                   -- top z1{left}
+                   .. {down}cycle;
 
        p_down_in := p_up_in rotated 180 shifted (w, 0);
        p_down_out := p_up_out rotated 180 shifted (w, 0);
@@ -939,41 +1186,41 @@ def draw_fa_head (expr width_factor) =
 enddef;
 
 
-fet_beginchar ("Whole fa up head", "d0fa")
+fet_beginchar ("Whole fa up head", "d0fa");
        draw_fa_head (1.8);
        fill p_up_out;
        unfill p_up_in;
 fet_endchar;
 
 
-fet_beginchar ("Whole fa down head", "u0fa")
+fet_beginchar ("Whole fa down head", "u0fa");
        draw_fa_head (1.8);
        fill p_down_out;
        unfill p_down_in;
 fet_endchar;
 
 
-fet_beginchar ("half fa up head", "d1fa")
+fet_beginchar ("half fa up head", "d1fa");
        draw_fa_head (1.5);
        fill p_up_out;
        unfill p_up_in;
 fet_endchar;
 
 
-fet_beginchar ("Half fa down head", "u1fa")
+fet_beginchar ("Half fa down head", "u1fa");
        draw_fa_head (1.5);
        fill p_down_out;
        unfill p_down_in;
 fet_endchar;
 
 
-fet_beginchar ("Quarter fa up head", "u2fa")
+fet_beginchar ("Quarter fa up head", "u2fa");
        draw_fa_head (1.55);
        fill p_up_out;
 fet_endchar;
 
 
-fet_beginchar ("Quarter fa down head", "d2fa")
+fet_beginchar ("Quarter fa down head", "d2fa");
        draw_fa_head (1.55);
        fill p_down_out;
 fet_endchar;
@@ -1007,32 +1254,32 @@ def draw_la_head (expr width_factor) =
                -- cycle;
 
        p_out := top z1
-                --- top z2
-                .. rt z2
-                --- rt z3
-                .. bot z3
-                --- bot z4
-                .. lft z4
-                --- lft z1
+                -- top z2{right}
+                .. rt z2{down}
+                -- rt z3{down}
+                .. bot z3{left}
+                -- bot z4{left}
+                .. lft z4{up}
+                -- lft z1{up}
                 .. cycle;
 enddef;
 
 
-fet_beginchar ("Whole lahead", "s0la")
+fet_beginchar ("Whole lahead", "s0la");
        draw_la_head (1.8);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Half lahead", "s1la")
+fet_beginchar ("Half lahead", "s1la");
        draw_la_head (1.5);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Quart lahead", "s2la")
+fet_beginchar ("Quart lahead", "s2la");
        draw_la_head (1.55);
        fill p_out;
 fet_endchar;
@@ -1042,9 +1289,9 @@ def draw_ti_head (expr width_factor, dir) =
        set_char_box (0, width_factor * noteheight#,
                      0.5 noteheight#, 0.5 noteheight#);
        save p_in, p_out, p_top;
-       save left_dist, right_dist;
+       save nw_dist, sw_dist, nw, sw;
        path p_in, p_out, p_top;
-       pair left_dist, right_dist;
+       pair nw_dist, sw_dist, nw, sw;
        save cone_height;
        cone_height = 0.64;
 
@@ -1061,68 +1308,73 @@ def draw_ti_head (expr width_factor, dir) =
 
        labels (range 1 thru 4);
 
-       left_dist = (unitvector (z2 - z1) rotated 90) * 0.5 solfa_pen_thick;
-       right_dist = (unitvector (z1 - z4) rotated 90) * 0.5 solfa_pen_thick;
+       nw = unitvector (z2 - z1);
+       sw = unitvector (z1 - z4);
+
+       nw_dist = (nw rotated 90) * 0.5 solfa_pen_thick;
+       sw_dist = (sw rotated 90) * 0.5 solfa_pen_thick;
 
-       p_top := (z2 - right_dist) .. (top z3){right} .. (z4 - left_dist);
+       p_top := (z2 - sw_dist)
+                .. (top z3){right}
+                .. (z4 - nw_dist);
 
-       p_in := (((z1 - left_dist) -- (z2 - left_dist)) intersectionpoint
-                 ((z1 - right_dist) -- (z4 - right_dist)))
-               -- (((z1 - left_dist) -- (z2 - left_dist)) intersectionpoint
-                    ((z2 + right_dist) .. {right}(bot z3)))
+       p_in := (((z1 - nw_dist) -- (z2 - nw_dist)) intersectionpoint
+                 ((z1 - sw_dist) -- (z4 - sw_dist)))
+               -- (((z1 - nw_dist) -- (z2 - nw_dist)) intersectionpoint
+                    ((z2 + sw_dist) .. {right}(bot z3)))
                .. bot z3
-               .. (((bot z3){right} .. (z4 + left_dist)) intersectionpoint
-                    ((z1 - right_dist) -- (z4 - right_dist)))
+               .. (((bot z3){right} .. (z4 + nw_dist)) intersectionpoint
+                    ((z1 - sw_dist) -- (z4 - sw_dist)))
                -- cycle;
 
        p_out := bot z1
-                .. (z1 + left_dist)
-                --- (z2 + left_dist)
+                .. (z1 + nw_dist)
+                -- (z2 + nw_dist)
                 .. lft z2
-                .. (z2 - right_dist){direction 0 of p_top}
+                .. (z2 - sw_dist){direction 0 of p_top}
                 & p_top
-                & {direction infinity of p_top}(z4 - left_dist)
+                & {direction infinity of p_top}(z4 - nw_dist)
                 .. rt z4
-                .. (z4 + right_dist)
-                --- (z1 + right_dist)
+                .. (z4 + sw_dist)
+                -- (z1 + sw_dist)
                 .. cycle;
 
        charwx := charwd;
        charwy := cone_height [-chardp, charht];
        if dir = -1:
-               charwy := - charwy;
+               charwy := -charwy;
        fi;
 enddef;
 
 
-fet_beginchar ("Whole up tihead", "s0ti")
+fet_beginchar ("Whole up tihead", "s0ti");
        draw_ti_head (1.8, 1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Half up tihead", "u1ti")
+fet_beginchar ("Half up tihead", "u1ti");
        draw_ti_head (1.5, 1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Half down tihead", "d1ti")
+fet_beginchar ("Half down tihead", "d1ti");
        draw_ti_head (1.5, -1);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
-fet_beginchar ("Quart up tihead", "u2ti")
+fet_beginchar ("Quart up tihead", "u2ti");
        draw_ti_head (1.55, 1);
        fill p_out;
 fet_endchar;
 
 
-fet_beginchar ("Quart down tihead", "d2ti")
+fet_beginchar ("Quart down tihead", "d2ti");
        draw_ti_head (1.55, -1);
        fill p_out;
 fet_endchar;
index baf5d9f8fcc8738b8958c9e8a99830df35faf148..a7a2f00485adf660bab27d1ed92e8486a11dd30b 100644 (file)
@@ -14,7 +14,7 @@ horizontal_space# :=  .66 ex#;
 font_x_height ex#;
 font_normal_space horizontal_space#;
 
-define_pixels (staffspace, linethickness, stafflinethickness, ex, descender, ascender);
+define_pixels (staffspace, linethickness, ex, descender, ascender);
 
 
 
index 4c4eac3c94e0d383caaecda7beef7e8f5c4f77bc..149980a87558d7b46ec5eca8529eeb94a76ab100 100644 (file)
@@ -8,8 +8,6 @@
 
 fet_begingroup ("rests");
 
-begingroup
-
 save block_rest_y, block_rest_x;
 save breve_rest_y, breve_rest_x;
 
@@ -18,7 +16,8 @@ breve_rest_x# = 3/5 staff_space#;
 block_rest_y# = 5/8 staff_space#;
 block_rest_x# = 3/2 staff_space#;
 
-define_pixels (block_rest_y, block_rest_x);
+define_whole_pixels (block_rest_y, block_rest_x);
+define_whole_pixels (breve_rest_y, breve_rest_x);
 
 
 def block_rest =
@@ -29,21 +28,28 @@ enddef;
 fet_beginchar ("whole rest", "0");
        set_char_box (0, block_rest_x#,
                      block_rest_y#, 0);
+
        block_rest;
-       currentpicture := currentpicture shifted (0, -block_rest_y);
+       currentpicture := currentpicture
+                           shifted (0, -block_rest_y + feta_space_shift);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
 fet_beginchar ("half rest", "1");
        set_char_box (0, block_rest_x#, 0, block_rest_y#);
+
        block_rest;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
 %
 % should use ledgerline thickness?
 %
-fet_beginchar ("whole rest (outside staff)", "0o")
+fet_beginchar ("whole rest (outside staff)", "0o");
        set_char_box (0, block_rest_x#,
                      block_rest_y#, ledgerlinethickness# / 2);
 
@@ -55,7 +61,9 @@ fet_beginchar ("whole rest (outside staff)", "0o")
        y5 = y6 = 0;
        lft x5 = -b - block_rest_y;
        rt x6 = w + block_rest_y;
-       draw_gridline (z5, z6, ledgerlinethickness);
+       draw_gridline (z5, z6, ledgerlinethickness_rounded);
+
+       draw_staff (-2, 2, -3);
 fet_endchar;
 
 
@@ -70,56 +78,59 @@ fet_beginchar ("half rest (outside staff)", "1o");
        y5 = y6 = 0;
        lft x5 = -b - block_rest_y;
        rt x6 = w + block_rest_y;
-       draw_gridline (z5, z6, ledgerlinethickness);
-fet_endchar;
 
+       draw_gridline (z5, z6, ledgerlinethickness_rounded);
+
+       draw_staff (-2, 2, 3);
+fet_endchar;
 
-define_pixels (breve_rest_y, breve_rest_x);
 
 fet_beginchar ("maxima rest", "-3");
        set_char_box (0, 3 breve_rest_x#, breve_rest_y#, breve_rest_y#);
-       draw_block ((0, -floor (breve_rest_y)),
-                   (breve_rest_x, floor (breve_rest_y)));
+
+       draw_block ((0, -breve_rest_y + feta_shift),
+                   (breve_rest_x, breve_rest_y));
+
        addto currentpicture also currentpicture shifted (2 breve_rest_x, 0);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
 fet_beginchar ("longa rest", "-2");
        set_char_box (0, breve_rest_x#, breve_rest_y#, breve_rest_y#);
-       draw_block ((0, -floor (breve_rest_y)),
-                   (breve_rest_x, floor (breve_rest_y)));
+
+       draw_block ((0, -breve_rest_y + feta_shift),
+                   (breve_rest_x, breve_rest_y));
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
 fet_beginchar ("breve rest", "-1");
        set_char_box (0, breve_rest_x#, 0, breve_rest_y#);
-       draw_block ((0, 0), (breve_rest_x, floor (breve_rest_y)));
-fet_endchar;
 
+       draw_block ((0, 0), (breve_rest_x, breve_rest_y));
+
+       draw_staff (-2, 2, 0);
+fet_endchar;
 
-tracingvariables := 1;
 
 fet_beginchar ("Quarter rest", "2");
-%      draw_staff (-2, 2, 0.0);
        save alpha, yshift, height;
-       alpha:=-50;
+       save xcenter;
 
-       thick# := 1/4 staff_space#;
-       define_blacker_pixels (thick);
+       yshift# := -1.25 staff_space#;
+       height# := 2.8125 staff_space#;
+       define_pixels (yshift, height);
 
+       alpha := -50;
+       thick := 1/4 staff_space;
        rthin := 1.25 linethickness;
+       xcenter := -0.1 staff_space;
        rthick := 2 thick + rthin;
 
-       yshift# = -1.25 staff_space#;
-       height# = 2.8125 staff_space#;
-
-       define_pixels (yshift, height);
-       save xcenter;
-       xcenter = -0.1 staff_space;
-
-       set_char_box (0, 0.95 staff_space#,
-                     -yshift#,
-                     yshift# + height#);
+       set_char_box (0, 0.95 staff_space#, -yshift#, yshift# + height#);
 
        save ne, nw, se, sw;
        pair ne, nw, se, sw;
@@ -151,10 +162,13 @@ fet_beginchar ("Quarter rest", "2");
        z3 = 1/2 [z2, z4];
        x4 = xcenter + 3/8 staff_space;
        y4 = 0;
-       z5 = z4l + 1.3 staff_space * se;
+       y4l := vround y4l;
+       z5 = round (z4l + 1.3 staff_space * se) + feta_offset;
        x6l = x4l;
-       y6l = y4r;
-       x7 = xcenter + 2/5 staff_space;
+       y6l = vround y4r;
+       x6r := hround x6r + xpart feta_offset;
+       y6r := vround y6r + ypart feta_offset;
+       x7 = hround (xcenter + 2/5 staff_space) + xpart feta_offset;
        y7 = -d;
 
        save before, after;
@@ -183,6 +197,8 @@ fet_beginchar ("Quarter rest", "2");
 
        penlabels (1, 2, 3, 4, 5, 6, 7);
        penlabels (10, 11, 12, 13);
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
@@ -221,12 +237,13 @@ save bulb_diam, thin, thick;
 
 bulb_diam# := 0.64 staff_space#;
 thin# := 1.4 linethickness# - 0.02 staff_space#;
-thick# :=  2.2 linethickness#;
-crook_thin := 0.5 linethickness + 0.08 staff_space;
+thick# := 2.2 linethickness#;
 
+crook_thin := 0.5 linethickness + 0.08 staff_space;
 lower_brush := 1.5 linethickness;
 
-define_pixels (bulb_diam, thin, thick);
+define_pixels (bulb_diam);
+define_whole_blacker_pixels (thin, thick);
 
 
 %
@@ -246,11 +263,16 @@ begingroup;
        y10 = ycenter;
        z10 = whatever [z2, z1] + left * bulb_diam * stretch;
 
+       % this enforces similar bulb shapes for lower resolutions
+       x10 := hround x10;
+
        z3 = z10 + bulb_diam / 2.15 * dir (-72);
+       y3 := hround y3;
        z5 = z10 + up * bulb_diam / 2 + right * linethickness / 3;
+       y5 := hround y5;
 
        z7 = 0.5 [z4, z5] + crook_thin * (0.45, 0.4) / 1.3;
-       x8 = x10 - 0.4 bulb_diam;
+       x8 = hround (x10 - 0.4 bulb_diam);
        y8 = y10 + 0.25 linethickness;
 
        z6 = whatever [z1l, z2l];
@@ -259,7 +281,7 @@ begingroup;
        z4 = z3 + whatever * (z6 - z3)
             + 1.1 crook_thin * (unitvector (z6 - z3) rotated 90);
        x4 = x10 + bulb_diam * .62;
-       y4 := ceiling (y4);
+       y4 := vround y4;
 
        (pt, whatever) = pat intersectiontimes ((0, ycut) -- (w, ycut));
 
@@ -282,26 +304,27 @@ enddef;
 
 
 def draw_eighth_rest (expr show_labels) =
-       save width;
        save ycenter;
        save pat, bulb;
        path pat, bulb;
 
-       width# := 1.0 staff_space#;
-
-       define_pixels (width);
-       set_char_box (0, width#,
+       set_char_box (0, 1.0 staff_space#,
                      1.0 staff_space# + 0.5 linethickness#,
                      0.5 staff_space# + bulb_diam# / 2);
 
        penpos1 (thick, 0);
        penpos2 (thin, 10);
 
-       y1 = - staff_space;
-       y2 = h -  lower_brush;
-       x2r = width;
+       y1 = -staff_space_rounded;
+       y2 = h - vround lower_brush;
+       x2r = w;
        z2 = z1 + whatever * dir (72);
        z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1) - 10);
+       y9 := vround y9;
+
+       x1l := hround x1l;
+       x1r := hround x1r;
+       x1 := .5 [x1l, x1r];
 
        if show_labels = 1:
                penlabels (1, 2);
@@ -309,21 +332,21 @@ def draw_eighth_rest (expr show_labels) =
        fi;
 
        pat = z1l
-             --- z2l
+             -- z2l
              .. z9
              .. z2r
-             --- z1r
+             -- z1r
              .. cycle;
        bulb = draw_rest_bulb (0.5 staff_space, y2r, pat, 1.0, show_labels);
 
        fill simple_serif (z1l, z1r, 40)
-            --- z2r
+            -- z2r
             .. z9
             .. bulb
-            --- z1l
+            -- z1l
             .. cycle;
 
-       % draw_staff (-2, 2, 0.0);
+       draw_staff (-2, 2, 0);
 enddef;
 
 
@@ -344,207 +367,227 @@ fet_endchar;
 %
 
 fet_beginchar ("16th rest", "4");
-       save width;
        save ycenter;
        save pat, bulb_a, bulb_b;
        path pat, bulb_a, bulb_b;
 
-       width# := 1.2 staff_space#;
-
-       define_pixels (width);
-       set_char_box (0, width#,
+       set_char_box (0, 1.2 staff_space#,
                      2.0 staff_space# + 0.5 linethickness#,
                      0.5 staff_space# + bulb_diam# / 2);
 
        penpos1 (thick, 0);
        penpos2 (thin, 10);
 
-       y1 = -2 staff_space ;
-       y2 = h -  lower_brush;
-       x2r = width;
-       z2 = z1 + whatever*dir (74);
-               z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1)- 10);
+       y1 = -2 staff_space_rounded;
+       y2 = h - vround lower_brush;
+       x2r = w;
+       z2 = z1 + whatever * dir (74);
+               z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1) - 10);
+       y9 := vround y9;
+
+       x1l := hround x1l;
+       x1r := hround x1r;
+       x1 := .5 [x1l, x1r];
+
        pat = z1l
-             --- z2l
+             -- z2l
              .. z9
              .. z2r
-             --- z1r
+             -- z1r
              .. cycle;
-       bulb_a = draw_rest_bulb (0.5 staff_space, y2r, pat, 0.98, 1);
-       bulb_b = draw_rest_bulb (-0.5 staff_space,
-                               (-0.5 + 0.2) * staff_space, pat, 1.02, 1);
+       bulb_a = draw_rest_bulb (.5 staff_space,
+                                y2r, pat, 0.98, 1);
+       bulb_b = draw_rest_bulb (.5 staff_space - staff_space_rounded,
+                                hround ((-0.5 + 0.2) * staff_space),
+                                pat, 1.02, 1);
 
        fill simple_serif (z1l, z1r, 40)
-            --- z2r
+            -- z2r
             .. z9
             .. bulb_a
-            --- bulb_b
-            --- z1l
+            -- bulb_b
+            -- z1l
             .. cycle;
 
        penlabels (1, 2);
        labels (9);
 
-       % draw_staff (-2, 2, 0.0);
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
 fet_beginchar ("32th rest", "5");
-       save width;
        save ycenter;
        save pat, bulb_a, bulb_b, bulb_c;
        path pat, bulb_a, bulb_b, bulb_c;
 
-       width# := 1.3 staff_space#;
-
-       define_pixels (width);
-       set_char_box (0, width#,
+       set_char_box (0, 1.3 staff_space#,
                      2.0 staff_space# + 0.5 linethickness#,
                      1.5 staff_space# + bulb_diam# / 2);
 
        penpos1 (thick, 0);
        penpos2 (thin, 10);
 
-       y1 = -2 staff_space ;
-       y2 = h - lower_brush;
-       x2r = width;
+       y1 = -2 staff_space_rounded;
+       y2 = h - vround lower_brush;
+       x2r = w;
        z2 = z1 + whatever * dir (76);
                z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1) - 10);
+       y9 := vround y9;
+
+       x1l := hround x1l;
+       x1r := hround x1r;
+       x1 := .5 [x1l, x1r];
+
        pat = z1l
-             --- z2l
+             -- z2l
              .. z9
              .. z2r
-             --- z1r
+             -- z1r
              .. cycle;
-       bulb_a = draw_rest_bulb ( 1.5 staff_space, y2r, pat, 0.96, 1);
-       bulb_b = draw_rest_bulb (0.5 staff_space,
-                                (0.5 + 0.2) * staff_space, pat, 1.00, 1);
-       bulb_c = draw_rest_bulb (-0.5 staff_space,
-                                (-0.5 + 0.21) * staff_space, pat, 1.04, 1);
+       bulb_a = draw_rest_bulb (.5 staff_space + staff_space_rounded,
+                                y2r, pat, 0.96, 1);
+       bulb_b = draw_rest_bulb (.5 staff_space,
+                                hround ((0.5 + 0.2) * staff_space),
+                                pat, 1.00, 1);
+       bulb_c = draw_rest_bulb (.5 staff_space - staff_space_rounded,
+                                hround ((-0.5 + 0.21) * staff_space),
+                                pat, 1.04, 1);
 
        fill simple_serif (z1l, z1r, 40)
-            --- z2r
+            -- z2r
             .. z9
             .. bulb_a
-            --- bulb_b
-            --- bulb_c
-            --- z1l
+            -- bulb_b
+            -- bulb_c
+            -- z1l
             .. cycle;
 
        penlabels (1, 2);
        labels (9);
 
-       % draw_staff (-2, 2, 0.0);
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
 fet_beginchar ("64th rest", "6");
-       save width;
        save ycenter;
        save pat, bulb_a, bulb_b, bulb_c, bulb_d;
        path pat, bulb_a, bulb_b, bulb_c, bulb_d;
 
-       width# := 1.4 staff_space#;
-
-       define_pixels (width);
-       set_char_box (0, width#,
+       set_char_box (0, 1.4 staff_space#,
                      3.0 staff_space# + 0.5 linethickness#,
                      1.5 staff_space# + bulb_diam# / 2);
 
        penpos1 (thick, 0);
        penpos2 (thin, 10);
 
-       y1 = -3 staff_space;
-       y2 = h - lower_brush;
-       x2r = width;
+       y1 = -3 staff_space_rounded;
+       y2 = h - vround lower_brush;
+       x2r = w;
        z2 = z1 + whatever * dir (78);
                z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1) - 10);
+       y9 := vround y9;
+
+       x1l := hround x1l;
+       x1r := hround x1r;
+       x1 := .5 [x1l, x1r];
+
        pat = z1l
-             --- z2l
+             -- z2l
              .. z9
              .. z2r
-             --- z1r
+             -- z1r
              .. cycle;
-       bulb_a = draw_rest_bulb (1.5 staff_space, y2r, pat, 0.94, 1);
-       bulb_b = draw_rest_bulb (0.5 staff_space,
-                                (0.5 + 0.20) * staff_space, pat, 0.98, 1);
-       bulb_c = draw_rest_bulb (-0.5 staff_space,
-                                (-0.5 + 0.21) * staff_space, pat, 1.02, 1);
-       bulb_d = draw_rest_bulb (-1.5 staff_space,
-                                (-1.5 + 0.22) * staff_space, pat, 1.06, 1);
+       bulb_a = draw_rest_bulb (.5 staff_space + staff_space_rounded,
+                                y2r, pat, 0.94, 1);
+       bulb_b = draw_rest_bulb (.5 staff_space,
+                                hround ((0.5 + 0.20) * staff_space),
+                                pat, 0.98, 1);
+       bulb_c = draw_rest_bulb (.5 staff_space - staff_space_rounded,
+                                hround ((-0.5 + 0.21) * staff_space),
+                                pat, 1.02, 1);
+       bulb_d = draw_rest_bulb (.5 staff_space - 2 staff_space_rounded,
+                                hround ((-1.5 + 0.22) * staff_space),
+                                pat, 1.06, 1);
 
        fill simple_serif (z1l, z1r, 40)
-            --- z2r
+            -- z2r
             .. z9
             .. bulb_a
-            --- bulb_b
-            --- bulb_c
-            --- bulb_d
-            --- z1l
+            -- bulb_b
+            -- bulb_c
+            -- bulb_d
+            -- z1l
             .. cycle;
 
        penlabels (1, 2);
        labels (9);
 
-       % draw_staff (-2, 2, 0.0);
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
 fet_beginchar ("128th rest", "7");
-       save width;
        save ycenter;
        save pat, bulb_a, bulb_b, bulb_c, bulb_d, bulb_e;
        path pat, bulb_a, bulb_b, bulb_c, bulb_d, bulb_e;
 
-       width# = 1.5 staff_space#;
-
-       define_pixels (width);
-       set_char_box (0, width#,
+       set_char_box (0, 1.5 staff_space#,
                      3.0 staff_space# + 0.5 linethickness#,
                      2.5 staff_space# + bulb_diam# / 2);
 
        penpos1 (thick, 0);
        penpos2 (thin, 10);
 
-       y1 = -3 staff_space;
-       y2 = h - lower_brush;
-       x2r = width;
+       y1 = -3 staff_space_rounded;
+       y2 = h - vround lower_brush;
+       x2r = w;
        z2 = z1 + whatever * dir (80);
                z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1)- 10);
+       y9 := vround y9;
+
+       x1l := hround x1l;
+       x1r := hround x1r;
+       x1 := .5 [x1l, x1r];
+
        pat = z1l
-             --- z2l
+             -- z2l
              .. z9
              .. z2r
-             --- z1r
+             -- z1r
              .. cycle;
-       bulb_a = draw_rest_bulb (2.5 staff_space, y2r, pat, 0.92, 1);
-       bulb_b = draw_rest_bulb (1.5 staff_space,
-                                (1.5 + 0.20) * staff_space, pat, 0.96, 1);
-       bulb_c = draw_rest_bulb (0.5 staff_space,
-                                (0.5 + 0.21) * staff_space, pat, 1.0, 1);
-       bulb_d = draw_rest_bulb (-0.5 staff_space,
-                                (-0.5 + 0.22) * staff_space, pat, 1.04, 1);
-       bulb_e = draw_rest_bulb (-1.5 staff_space,
-                                (-1.5 + 0.23) * staff_space, pat, 1.08, 1);
+       bulb_a = draw_rest_bulb (.5 staff_space + 2 staff_space_rounded,
+                                y2r, pat, 0.92, 1);
+       bulb_b = draw_rest_bulb (.5 staff_space + staff_space_rounded,
+                                hround ((1.5 + 0.20) * staff_space),
+                                pat, 0.96, 1);
+       bulb_c = draw_rest_bulb (.5 staff_space,
+                                hround ((0.5 + 0.21) * staff_space),
+                                pat, 1.0, 1);
+       bulb_d = draw_rest_bulb (.5 staff_space - staff_space_rounded,
+                                hround ((-0.5 + 0.22) * staff_space),
+                                pat, 1.04, 1);
+       bulb_e = draw_rest_bulb (.5 staff_space - 2 staff_space_rounded,
+                                hround ((-1.5 + 0.23) * staff_space),
+                                pat, 1.08, 1);
 
        fill simple_serif (z1l, z1r, 40)
-            --- z2r
+            -- z2r
             .. z9
             .. bulb_a
-            --- bulb_b
-            --- bulb_c
-            --- bulb_d
-            --- bulb_e
-            --- z1l
+            -- bulb_b
+            -- bulb_c
+            -- bulb_d
+            -- bulb_e
+            -- z1l
             .. cycle;
 
        penlabels (1, 2);
        labels (9);
 
-       % draw_staff (-2, 2, 0.0);
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-endgroup;
-
-fet_endgroup ("rests")
+fet_endgroup ("rests");
index aa4d2cd10c5363aac4d077235a4411fa6755f164..f2580490d607e542a63a42555bf40c2de6837e91 100644 (file)
 
 fet_begingroup ("clefs");
 
-test_staff := 0;
-
-
+%
 % [Wanske] says the bulbs should be positioned about 1/4 right of the
-% "arrow".
-
+% `arrow'.
 %
-% TODO: the hair-curve at z6r looks a little awkward.
+% TODO: The hair-curve at z6r looks a little awkward.
 %
 
 def draw_c_clef (expr reduction) =
@@ -29,33 +26,48 @@ def draw_c_clef (expr reduction) =
        norm# := 2/3 reduced_ss#;
        hair# := 0.06 reduced_ss# + 0.5 linethickness#;
        right_edge# = 15/4 norm# + 2 hair#;
-       define_pixels (hair, norm, reduced_ss, right_edge);
+       define_pixels (norm, reduced_ss, right_edge);
+       define_whole_vertical_blacker_pixels (hair);
+
+       set_char_box (0, right_edge#, 2 reduced_ss#, 2 reduced_ss#);
 
-       set_char_box (0, right_edge# + 0,
-                     2 reduced_ss#, 2 reduced_ss#);
+       % make unreduced glyph fit exactly into five staff lines
+       if reduction = 1:
+               h := d := 2 staff_space_rounded;
+       fi;
 
-       draw_block ((0, -d), (3/4 norm + 1/2 hair, h));
-       draw_block ((3/4 norm + 2 hair, -d), (3/4 norm + 7/2 hair, h));
+       % assure that the gap between the left and right stem
+       % has the same number of pixels as the thickness of the right
+       % stem
+       draw_block ((0, -d + feta_shift),
+                   (3/4 norm + 1/2 hair, h));
+       draw_block ((3/4 norm + 1/2 hair + hround (3/2 hair), -d + feta_shift),
+                   (3/4 norm + 1/2 hair + 2 hround (3/2 hair), h));
 
-       xoff = 3/4 norm + 7/2 hair;
+       % assure symmetry
+       h := h - feta_shift;
+
+       pickup feta_fillpen;
+
+       xoff = 3/4 norm + 1/2 hair + 2 hround (3/2 hair);
        z5l = (xoff - 3/4 hair, 0);
        z5r = (x4, 0);
 
-       penpos1 (hair, -90);
-       z1l = (xoff + norm + hair, h);
+       penpos1 (hair - pen_top - pen_bot, -90);
+       top z1l = (xoff + norm + hair, h);
 
-       penpos2 (norm - 3/2 hair, 180);
-       z2l = (right_edge, h / 2);
+       penpos2 (hround (norm - 3/2 hair) - pen_lft - pen_rt, 180);
+       rt z2l = (w, h / 2);
 
-       penpos3 (hair, 90);
-       z3 = ((right_edge - xoff) / 2 + xoff, 2 hair);
+       penpos3 (hair - pen_top - pen_bot, 90);
+       bot z3l = ((right_edge - xoff) / 2 + xoff,
+                  vround (.5 norm - 1.5 hair));
 
-       penpos4 (hair, 0);
-       z4 = (xoff + 1/2 norm + 1/2 hair,
-             reduced_ss - linethickness - .2 hair);
+       penpos4 (hair - pen_lft - pen_rt, 0);
+       top z4 = (xoff + 1/2 norm + 1/2 hair,
+                 vfloor (reduced_ss - linethickness - .2 hair));
 
-       penpos6 (norm - hair, 90);
-       z6 = (xoff + 3/4 norm, 0);
+       bot z6 = (xoff + 3/4 norm, vround (.5 norm - .5 hair));
 
        save t;
        t = 0.833;
@@ -63,46 +75,36 @@ def draw_c_clef (expr reduction) =
        save p;
        path p;
 
-       pickup pencircle scaled 1pt#;
-
        p = z5l{curl 1}
            .. z4l{up}
            .. z4r{down}
            .. z3r{right}
            ..tension t.. z2r{up}
-           ..tension t.. flare_path (z1l, 180, 90, hair, norm - 1/2 hair, -1)
+           ..tension t.. flare_path (top z1l, 180, 90,
+                                     hair, hfloor (norm - 1/2 hair), -1)
            ..tension t.. z2l{down}
            .. z3l{left}
-           .. z6r
+           .. z6
            .. z5r{down};
 
-       % mf2pt1 replaces `filldraw' with `fill' -- since we use fontforge
-       % for postprocessing and hinting, we don't have to care for a
-       % minimum width of the contour.
-       filldraw p
-                & reverse p yscaled -1
-                & cycle;
+       filldraw p shifted (0, feta_shift)
+                -- reverse p yscaled -1 shifted (0, -feta_eps)
+                -- cycle;
 
        penlabels (1, 2, 3, 4, 5, 6);
 
        % ugh, should be bulb, not flare?
-enddef;
 
+       draw_staff (-2, 2, 0);
+enddef;
 
-fet_beginchar ("C clef", "C")
-       if test_staff = 1:
-               draw_staff (-2,2, 0.0);
-       fi;
 
+fet_beginchar ("C clef", "C");
        draw_c_clef (1.0);
 fet_endchar;
 
 
-fet_beginchar ("C clef", "C_change")
-       if test_staff = 1:
-               draw_staff (-2,2, 0.0);
-       fi;
-
+fet_beginchar ("C clef", "C_change");
        draw_c_clef (.8);
 fet_endchar;
 
@@ -133,8 +135,7 @@ begingroup;
 
        center = outer_tangent_point
                 + big_radius * dir (0)
-                + big_radius * dir (-turning_dir * 90)
-                - bulb_radius * dir (-turning_dir * 90);
+                + (big_radius - bulb_radius) * dir (-turning_dir * 90);
 
        z1' = center + bulb_radius * dir (turning_dir * 180);
        z2' = outer_tangent_point + flare * dir (0);
@@ -164,7 +165,6 @@ endgroup
 enddef;
 
 
-%
 %
 % There is some variation in the shape of bass clefs.
 %
@@ -193,22 +193,23 @@ enddef;
 
 def draw_bass_clef (expr exact_center, reduction) =
        save reduced_ss, swoosh_width;
-       save right_thickness, tip_protude;
-       save dot_diam, bulb_y_offset, overshoot_top;
+       save right_thickness, right_offset, tip_protude;
+       save dot_diam, bulb_y_offset, bulb_flare;
        pair tip_protude;
 
        reduced_ss# = staff_space# * reduction;
-
-       2.2 dot_diam = round reduction * (staff_space - stafflinethickness);
-       right_thickness = 0.37 staff_space + 1.2 linethickness;
+       2.2 dot_diam# = reduction * (staff_space# - stafflinethickness#);
+       right_thickness# = 0.37 staff_space# + 1.2 linethickness#;
        swoosh_width# = 2.1 reduced_ss#;
-%      tip_protude := (-linethickness, -.2 staff_space);
-       tip_protude := (0, 0);
-       bulb_y_offset := 0.15 staff_space;
-       overshoot_top := 0.0;
-
        define_pixels (swoosh_width);
        define_whole_pixels (reduced_ss);
+       define_whole_blacker_pixels (dot_diam, right_thickness);
+
+       right_offset = 0.05 staff_space;
+       bulb_y_offset := 0.15 staff_space;
+       bulb_flare := 2.5 linethickness;
+%      tip_protude := (-linethickness, -.2 staff_space);
+       tip_protude := (0, 0);
 
        set_char_box (-xpart exact_center,
                      xpart exact_center + swoosh_width# + 7/12 reduced_ss#,
@@ -221,48 +222,52 @@ def draw_bass_clef (expr exact_center, reduction) =
        x2 = .5 [x1, x3];
        x2l = x2r = x2;
 
-       y2l := vround_pixels (reduced_ss#  + 0.5 linethickness#);
-       y2l - y2r = (1.0 + overshoot_top) * linethickness;
+       y2l := vround_pixels (reduced_ss# + 0.5 linethickness#);
+       y2l - y2r = linethickness;
 
        x3l - x1 = swoosh_width;
        x3l - x3r = right_thickness;
 
        % optical correction: the top dot seems farther away if y3l = 0.
-       y3l = 0.05 staff_space;
+       y3l = right_offset;
 
        z4 = -(0, 2.0 reduced_ss) + tip_protude;
-       z5 = (x3l + 1/3 reduced_ss, .5 reduced_ss);
 
        penpos3 (whatever, 185);
        penpos4 (linethickness, 135);
 
        fill new_bulb (z2l, 180, z1, z2r, 0,
                       0.45 reduced_ss, 0.4 reduced_ss,
-                      2.5 linethickness, 1, 1)
+                      bulb_flare, 1, 1)
             .. z3r{down}
             .. {curl 0}simple_serif (z4r, z4l, 90){curl 0}
             .. z3l{up}
             ..tension 0.9.. cycle;
 
-       penlabels (1, 2, 3, 4, 5);
-
        pickup pencircle scaled dot_diam;
 
+       lft x5 = hround (x3l + 1/3 reduced_ss - dot_diam / 2);
+       bot y5 = vfloor (.5 reduced_ss - dot_diam / 2);
+       z6 = z5 yscaled -1;
+
+       % for symmetry
+       y5 := y5 + feta_shift;
+
        drawdot z5;
-       drawdot z5 yscaled -1;
-enddef;
+       drawdot z6;
 
+       penlabels (1, 2, 3, 4, 5, 6);
 
-fet_beginchar ("F clef ", "F")
-       if test_staff = 1:
-               draw_staff (-3,1, 0.0);
-       fi;
+       draw_staff (-3, 1, 0);
+enddef;
 
+
+fet_beginchar ("F clef ", "F");
        draw_bass_clef ((0, 0), 1.0);
 fet_endchar;
 
 
-fet_beginchar ("F clef (reduced)", "F_change")
+fet_beginchar ("F clef (reduced)", "F_change");
        draw_bass_clef ((0, 0), 0.8);
 fet_endchar;
 
@@ -271,7 +276,7 @@ fet_endchar;
 %
 % Inspired by Baerenreiter
 %
-
+%
 % Beste lezers, kijk,
 %
 % Een bolletje hebben we bij toeval allemaal wel eens getekend, maar begint u
@@ -321,14 +326,15 @@ def draw_gclef (expr reduction) =
        x1 = xpart center - .28 reduced_ss;
        penpos1 (thinnib, inner_start_angle);
 
-       z2r = center + (0, reduced_ss + stafflinethickness / 2);
+       x2r = xpart center;
+       y2r = vround_pixels (reduced_ss# + .5 stafflinethickness#);
        penpos2 (thickness, 90);
 
        z3 = (z4 - center) rotated inner_thick_end + center;
        penpos3 (thinnib, -90 + inner_thick_end);
 
        x4 = xpart center - .1 reduced_ss;
-       y4r = -(reduced_ss + .5 stafflinethickness);
+       y4r = -y2r + feta_shift;
        penpos4 (thinnib, -90);
 
        x5r = -breapth_factor * reduced_ss + xpart center;
@@ -414,19 +420,17 @@ def draw_gclef (expr reduction) =
 
        penlabels (range 1 thru 16);
        penlabels (10', 11');
+
+       draw_staff (-1, 3, 0);
 enddef;
 
 
-fet_beginchar ("G clef", "G")
-       if test_staff = 1:
-               draw_staff (-1,3, 0.0);
-       fi;
-
+fet_beginchar ("G clef", "G");
        draw_gclef (1.0);
 fet_endchar;
 
 
-fet_beginchar ("G clef", "G_change")
+fet_beginchar ("G clef", "G_change");
        draw_gclef (0.8);
 fet_endchar;
 
@@ -450,26 +454,31 @@ def draw_percussion_clef (expr reduction) =
        set_char_box (-.67 reduced_ss#, 2.0 reduced_ss#,
                      reduced_ss#, reduced_ss#);
 
-       razt := 0.45 reduced_ss;
+       razt := hround (0.45 reduced_ss);
+
+       d := d - feta_shift;
 
        draw_block ((-b, -d), (-b + razt, h));
        draw_block ((w - razt, -d), (w, h));
+
+       draw_staff (-3, 1, 1);
 enddef;
 
 
-fet_beginchar ("percussion clef", "percussion")
+fet_beginchar ("percussion clef", "percussion");
        draw_percussion_clef (1.0);
 fet_endchar;
 
 
-fet_beginchar ("percussion clef (reduced)", "percussion_change")
+fet_beginchar ("percussion clef (reduced)", "percussion_change");
        draw_percussion_clef (.8);
 fet_endchar;
 
 
 def draw_tab_T (expr pos, siz, slant) =
 begingroup;
-       pair vx,vy;
+       save vx, vy;
+       pair vx, vy;
 
        clearxy;
 
@@ -478,8 +487,9 @@ begingroup;
 
        penpos1 (.75 penh, 100);
        z1 = z2 + (1/6 * vx - .15 * vy);
-       penpos2 (.9 penw, 0);
-       z2l = pos + .75 vy;
+       penpos2 (hround (.9 penw), 0);
+       x2l = hround xpart (pos + .75 vy);
+       y2l = ypart (pos + .75 vy);
        penpos3 (penh, -100);
        z3l = pos + .4 vx + vy;
        penpos4 (penh, -90);
@@ -517,7 +527,9 @@ enddef;
        
 def draw_tab_A (expr pos, siz, slant) =
 begingroup;
-       pair vx,vy;
+       save vx, vy, p;
+       pair vx, vy;
+       path p;
 
        clearxy;
 
@@ -542,8 +554,12 @@ begingroup;
        penpos8 (.75 penh, -70);
        z8r = (xpart (pos + siz), y7r + .075 ypart (siz));
 
-       penpos10 (penh, -105);
-       z10 = .2 [z3, z4];
+       p := z2
+            .. z3
+            .. z4;
+
+       penpos10 (penh, angle (direction 1.2 of p) - 180);
+       z10 = point 1.2 of p;
        penpos11 (.9 penh, -90);
        z11 = .4 [z10, z6] - 0.05 vy;
        penpos12 (.75 penh, -75);
@@ -573,7 +589,8 @@ enddef;
 
 def draw_tab_B (expr pos, siz, slant) =
 begingroup;
-       pair vx,vy;
+       save vx, vy;
+       pair vx, vy;
 
        clearxy;
 
@@ -582,8 +599,9 @@ begingroup;
 
        penpos1 (.75 penh, 100);
        z1 = z2 + (.15 * vx - .1 * vy);
-       penpos2 (.9 penw, 0);
-       z2l = pos+.75 vy;
+       penpos2 (hround (.9 penw), 0);
+       x2l = hround xpart (pos + .75 vy);
+       y2l = ypart (pos + .75 vy);
        penpos3 (penh, -100);
        z3l = pos + .4 vx + 1.05 vy;
        penpos4 (.8 [penh, penw], -180);
@@ -640,8 +658,6 @@ def draw_tab_clef (expr reduction) =
        set_char_box (-.2 reduced_ss#, 2.8 reduced_ss#,
                      1.6 letterheight#, 1.6 letterheight#);
 
-       % draw_staff (-3,2, 0.5);
-
        penw = .45 reduced_ss;
        penh = .2 reduced_ss;
 
@@ -651,15 +667,17 @@ def draw_tab_clef (expr reduction) =
                    (2.2 reduced_ss, letterheight), 0.4);
        draw_tab_B ((-b + .025 reduced_ss, -d),
                    (2.1 reduced_ss, letterheight), 0.25);
+
+       draw_staff (-3, 2, 0.5);
 enddef;
 
 
-fet_beginchar ("tab clef", "tab")
+fet_beginchar ("tab clef", "tab");
        draw_tab_clef (1.0);
 fet_endchar;
 
 
-fet_beginchar ("tab clef (reduced)", "tab_change")
+fet_beginchar ("tab clef (reduced)", "tab_change");
        draw_tab_clef (.8);
 fet_endchar;
 
index d50946054dc381e80351dd181c3f4bad553b51ee..d8b7028cd110bee3270ee378d0681c040b48a05a 100644 (file)
@@ -36,8 +36,10 @@ def draw_staff (expr first, last, offset) =
                pickup pencircle scaled stafflinethickness;
 
                for i := first step 1 until last:
-                       draw (-staff_space, (i + offset) * staff_space)
-                            .. (4 staff_space, (i + offset) * staff_space);
+                       draw (-staff_space,
+                             (i + offset) * staff_space_rounded)
+                            -- (4 staff_space,
+                                (i + offset) * staff_space_rounded);
                endfor;
        fi;
 enddef;
@@ -55,8 +57,10 @@ def draw_staff_outline (expr first, last, offset) =
                pickup pencircle scaled 2;
 
                for i := first step 1 until last:
-                       p := (-staff_space, (i + offset) * staff_space)
-                            .. (4 staff_space, (i + offset) * staff_space);
+                       p := (-staff_space,
+                             (i + offset) * staff_space_rounded)
+                            -- (4 staff_space,
+                                (i + offset) * staff_space_rounded);
 
                        draw p shifted (0, .5 stafflinethickness);
                        draw p shifted (0, -.5 stafflinethickness);
@@ -178,31 +182,33 @@ enddef;
 
 def draw_rounded_block (expr bottom_left, top_right, roundness) =
 begingroup;
-       save round;
+       save size;
        save x, y;
 
-       round = floor min (roundness,
-                          xpart (top_right - bottom_left),
-                          ypart (top_right - bottom_left));
+       % Originally, there was `floor' instead of `round', but this is
+       % not correct because pens use `round' also.
+       size = round min (roundness,
+                         xpart (top_right - bottom_left),
+                         ypart (top_right - bottom_left));
 
-       pickup pencircle scaled round;
-
-       z2 + (round / 2, round / 2) = top_right;
-       z4 - (round / 2, round / 2) = bottom_left;
+       z2 + (size / 2, size / 2) = top_right;
+       z4 - (size / 2, size / 2) = bottom_left;
        y3 = y2;
        y4 = y1;
        x2 = x1;
        x4 = x3;
 
-       fill bot z1
-            .. rt z1
-            --- rt z2
-            .. top z2
-            --- top z3
-            .. lft z3
-            --- lft z4
-            .. bot z4
-            --- cycle;
+       pickup pencircle scaled size;
+
+       fill bot z1{right}
+            .. rt z1{up}
+            -- rt z2{up}
+            .. top z2{left}
+            -- top z3{left}
+            .. lft z3{down}
+            -- lft z4{down}
+            .. bot z4{right}
+            -- cycle;
 endgroup;
 enddef;
 
@@ -221,10 +227,10 @@ def draw_square_block (expr bottom_left, top_right) =
        y2 = ypart top_right;
 
        fill (x1, y1)
-            --- (x2, y1)
-            --- (x2, y2)
-            --- (x1, y2)
-            --- cycle;
+            -- (x2, y1)
+            -- (x2, y2)
+            -- (x1, y2)
+            -- cycle;
 enddef;
 
 
@@ -284,34 +290,44 @@ enddef;
 % line = diameter of line attachment
 % direction = is ink on left or right side (1 or -1)
 %
+% Note that `currentpen' must be set correctly -- only circular pens
+% are supported properly.
 
 def flare_path (expr pos, alpha, beta, line, flare, direction) =
 begingroup;
+       save thick;
+
+       thick = pen_top + pen_bot;
+
        clearxy;
 
-       penpos1 (line, 180 + beta + alpha);
-       z1r = pos;
+       penpos1' (line - thick, 180 + beta + alpha);
+       top z1'r = pos;
 
-       penpos2 (flare, 180 + beta + alpha);
-       z2 = z3;
+       penpos2' (flare - thick, 180 + beta + alpha);
+       z2' = z3';
 
-       penpos3 (flare, 0 + alpha);
-       z3l = z1r + (1/2 + 0.43) * flare * dir (alpha + beta);
+       penpos3' (flare - thick, 0 + alpha);
+       rt x3'l = hround (x1'r
+                         + (1/2 + 0.43) * flare * xpart dir (alpha + beta));
+       bot y2'l = vround (y1'r
+                          + (1 + 0.43) * flare * ypart dir (alpha + beta));
 
-       z4 = z2r - line * dir (alpha);
+       rt x4' = x2'r - line * xpart dir (alpha);
+       y4' = y2'r - line * ypart dir (alpha);
 
-       penlabels (1, 2, 3, 4);
+       penlabels (1', 2', 3', 4');
 
        save t, p;
        t = 0.833;
        path p;
 
-       p := z1r{dir (alpha)}
-            .. z3r{dir (180 + alpha - beta)}
-            .. z2l{dir (alpha + 180)}
-            .. z3l{dir (180 + alpha + beta)}
-            ..tension t.. z4{dir (180 + alpha + beta)}
-            .. z1l{dir (alpha + 180)};
+       p := z1'r{dir (alpha)}
+            .. z3'r{dir (180 + alpha - beta)}
+            .. z2'l{dir (alpha + 180)}
+            .. z3'l{dir (180 + alpha + beta)}
+            ..tension t.. z4'{dir (180 + alpha + beta)}
+            .. z1'l{dir (alpha + 180)};
 
        if direction <> 1:
                p := reverse p;
@@ -404,7 +420,7 @@ begingroup;
 
        rad = bulb_rad;
 
-       z1' = z0' + radius_factor* rad * dir (ang + turndir * 100);
+       z1' = z0' + radius_factor * rad * dir (ang + turndir * 100);
        z2' = z0' + rad * dir (ang + turndir * 300);
 
        labels (0', 1', 2');
@@ -416,4 +432,23 @@ begingroup;
 endgroup
 enddef;
 
+
 pi := 3.14159;
+
+
+%
+% To get symmetry at low resolutions we need to shift some points and
+% paths, but not if mf2pt1 is used.
+%
+
+if known miterlimit:
+       vardef hfloor primary x = x enddef;
+       vardef vfloor primary y = y enddef;
+       vardef hceiling primary x = x enddef;
+       vardef vceiling primary y = y enddef;
+else:
+       vardef hfloor primary x = floor x enddef;
+       vardef vfloor primary y = (floor y.o_)_o_ enddef;
+       vardef hceiling primary x = ceiling x enddef;
+       vardef vceiling primary y = (ceiling y.o_)_o_ enddef;
+fi;
index 94a7e487bfdd7825f49c9a9194b2feac2a1f1042..1323b7f41e219a2f47611dc167c704f9be1e3199 100644 (file)
@@ -1,18 +1,22 @@
 
-stafflines = 5;
+stafflines := 5;
 
 %
 % The design size of a staff should really be the 
 % staff_space, but we use staffsize for historical reasons.
 % 
-staff_space# = staffsize#/(stafflines-1);
 
+staff_space# := staffsize# / (stafflines - 1);
+staff_space_rounded# := staff_space#;
 
-% measuring on pocket scores turns out: stafflinethickness is
+
+%
+% Measuring on pocket scores turns out: stafflinethickness is
 % largely independent on staff size, and generally about 0.5 pt.
 %
-% by request of WL, we tune down the blackness a little
+% By request of WL, we tune down the blackness a little
 % for increased contrast with beams.
+%
 
 %% !! synchronize with paper.scm
 
@@ -20,48 +24,184 @@ save fixed_line_thickness, variable_line_factor;
 fixed_line_thickness + variable_line_factor * 5 pt# = 0.50 pt#;
 fixed_line_thickness + variable_line_factor * 4.125 pt# = 0.47 pt#;
 
-stafflinethickness#  = fixed_line_thickness + variable_line_factor * staff_space#; 
+stafflinethickness# := fixed_line_thickness
+                      + variable_line_factor * staff_space#; 
+stafflinethickness_rounded# := stafflinethickness#;
 
 %
 % The following tunes the general blackness of the glyphs. 
 %
-linethickness# = stafflinethickness#; %%   0.5 pt#;
+
+linethickness# := stafflinethickness#;         %% 0.5 pt#;
+linethickness_rounded# := linethickness#;
 
 %
 % bigger puff_up_factor, relatively thicker stafflines.
-% 20 pt = puff_up_factor 0.
-% 10 pt = puff_up_factor 1
 %
-puff_up_factor =  (linethickness# - 0.1 staff_space#) / (0.1 staff_space#);
+%   20 pt = puff_up_factor 0
+%   10 pt = puff_up_factor 1
+%
 
+puff_up_factor = (linethickness# - 0.1 staff_space#) / (0.1 staff_space#);
 
 
 stemthickness# := 1.3 stafflinethickness#;
+stemthickness_rounded# := stemthickness#;
 ledgerlinethickness# := 2 stafflinethickness#;
+ledgerlinethickness_rounded# := ledgerlinethickness#;
 
-define_pixels(staff_space, stemthickness);
-define_pixels(stafflinethickness, ledgerlinethickness, linethickness);
+define_pixels (staff_space, stemthickness, stafflinethickness,
+              ledgerlinethickness, linethickness);
+define_whole_pixels (staff_space_rounded);
+define_whole_blacker_pixels (stemthickness_rounded);
+define_whole_vertical_blacker_pixels (stafflinethickness_rounded,
+                                     ledgerlinethickness_rounded,
+                                     linethickness_rounded);
 
+if ledgerlinethickness_rounded > 2 stafflinethickness_rounded:
+       ledgerlinethickness_rounded := 2 stafflinethickness_rounded;
+fi;
 
 % 
 % Because of the engraving/stamping process, no traditional
-% characters have sharp edges and corners
-% The following variable controls the amount of "roundness"
+% characters have sharp edges and corners.
+% The following variable controls the amount of `roundness'.
 %
-% this is not a meta variable: it is related to absolute sizes.
+% %his is not a meta variable: it is related to absolute sizes.
 %
 % FIXME: According to [Wanske], only outside corners should be round
 %        I don't think we do this anywhere -- jcn
-numeric blot_diameter;
+%
+
 blot_diameter# = .35 pt#;
 if (blot_diameter# * hppp) < 1:
-       blot_diameter# := 1/hppp;
+       blot_diameter# := 1 / hppp;
 fi
 if (blot_diameter# * vppp) < 1:
-       blot_diameter# := 1/vppp;
+       blot_diameter# := 1 / vppp;
 fi
-define_pixels(blot_diameter);
 
+define_pixels (blot_diameter);
+
+
+%
+% symmetry
+% --------
+%
+% Some glyphs have to be positioned exactly between stafflines (clefs,
+% note heads).  This needs some care at lower resolutions.
+%
+% Most glyphs use the staffline thickness and the space between two
+% staff lines as the fundamental parameters.  The latter is the distance
+% between the middle of one staff line to the middle of the next.  To
+% say it differently, the value `staff_space' is the sum of one staff line
+% thickness and the whitespace between two adjacent staff lines.
+%
+% Normally, feta's vertical origin for glyphs is either the middle
+% between two staff lines or the middle of a staff line.  For example, the
+% lower edge of the central staff line is at the vertical position
+% `-<staffline thickness> / 2', and the upper edge at
+% `<staffline thickness> / 2'.  Here we need a value rounded to an integer
+% (the feta code uses `stafflinethickness_rounded' for that purpose).
+%
+% If we have an odd number of pixels as the staffline thickness, Metafont
+% rounds `-stafflinethickness_rounded / 2' towards zero and
+% `stafflinethickness_rounded / 2' towards infinity.  Example: `round -1.5'
+% yields -1, `round 1.5' yields 2.  The whitespace between staff lines is
+% handled similarly.  If we assume that stafflinethickness_rounded is odd,
+% we have the following cases:
+%
+% o The glyph is centered between three stafflines or five stafflines
+%   (clef, `c' meter).  We have this:
+%
+%          ___________  a
+%          ___________  1
+%          ___________  a
+%
+%                            whitespace
+%
+%          ___________  a
+%   ...... ___________  1 ..................  x axis
+%          ___________  a
+%
+%                            whitespace
+%
+%          ___________  a
+%          ___________  1
+%          ___________  a
+%
+%   As can be seen, we get symmetry if we split staff lines into two
+%   equal parts `a' and a pixel line with thickness 1.  Consequently, we
+%   use the following algorithm:
+%
+%   . Decrease the height `h' by 1 temporarily.
+%
+%   . Compute the path for the upper half of the glyph.
+%
+%   . Mirror the path at the x axis.
+%
+%   . Shift the upper half one pixel up and connect it with the lower path.
+%
+%   . Restore height and decrease `d' by 1.
+%
+% o The glyph is centered between two or four staff lines, and the origin is
+%   the middle of the whitespace.  Assuming that the the whitespace consists
+%   of an odd number of pixels, we have this:
+%
+%          -----------
+%                       b
+%                       1
+%                       b
+%          ___________
+%                       b
+%   ..................  1  .................  x axis
+%                       b
+%          ___________
+%                       b
+%                       1
+%                       b
+%          ___________
+%
+%   For symmetrical glyphs, this leads to a similar algorithm as above.
+%   Glyphs which can't be constructed from an upper and lower part need
+%   to be handled differently, namely to shift up the vertical center by
+%   half a pixel:
+%
+%          ___________
+%                       b
+%
+%                       0.5
+%   ..................  0.5 ................  x axis
+%
+%                       b
+%          ___________
+%
+
+feta_eps := 0;
+feta_shift := 0;
+feta_space_shift := 0;
+
+% Use this for paths with a slant of 45 degrees to assure that
+% the middle point of a penpos gets covered.
+pair feta_offset;
+feta_offset := (0, 0);
+
+if known miterlimit:
+       pickup nullpen;
+else:
+       feta_eps := eps;
+
+       if odd stafflinethickness_rounded:
+               feta_shift := 1;
+       fi;
+
+       if odd (staff_space_rounded - stafflinethickness_rounded):
+               feta_space_shift := 1;
+       fi;
 
+       feta_offset := (0.5, 0.5);
 
+       pickup pencircle scaled 1;
+fi;
 
+feta_fillpen := savepen;
index 3b0cd296cc61f7aab5d0f6ac29e3345d5fe837ac..2a31d293f1b63739374473b8d5666de640b87186 100644 (file)
@@ -15,7 +15,7 @@
 % ed = -0.27 pedalh == -0.53 staff-space
 
 
-fet_begingroup ("pedal")
+fet_begingroup ("pedal");
 
 pedalpha = 40;
 pedbeta = 25;
@@ -29,7 +29,7 @@ pedalbh# = 4/7 pedalh#;
 define_pixels (pedalh, pedalbh);
 
 
-fet_beginchar ("Pedal asterisk", "*")
+fet_beginchar ("Pedal asterisk", "*");
        save bulb, p, radius, thin, inner_r;
        path p;
 
@@ -59,7 +59,7 @@ fet_beginchar ("Pedal asterisk", "*")
        z4 = .5 [z4l, z4r];
        z3 = .75 [z1, z4];
 
-       penlabels (1, 2, 3, 4);
+       penlabels (0, 1, 2, 3, 4);
 
        p := z3r{up}
             .. z1l{up}
@@ -88,30 +88,33 @@ fet_endchar;
 
 %% ugh. rounded corners!
 
-fet_beginchar ("Pedal dash", "-")
-       set_char_box (0, 3 penw#, 0, pedalbh#);
+fet_beginchar ("Pedal dash", "-");
+       save dash_thickness;
 
-       pickup pencircle scaled penh;
+       dash_thickness# := penw#;
+       define_whole_vertical_blacker_pixels (dash_thickness);
+
+       set_char_box (0, 3 penw#, 0, pedalbh#);
 
-       penpos1 (penw, 60);
-       penpos2 (penw, 60);
+       penpos1 (dash_thickness, 60);
+       penpos2 (dash_thickness, 60);
 
-       z1l = (0, 2/3 h - 1/2 penw);
-       z2r = (w, y1l + 1.2 penw);
+       z1l = (0, vround (2/3 h - 1/2 penw));
+       z2r = (w, vround (y1l + 1.2 penw));
 
-       penlabels (1, 2);
+       penlabels (1, 2, 3);
 
        penstroke z1e{dir 40}
                  ..tension 1.2.. z2e{dir 40};
 fet_endchar;
 
 
-fet_beginchar ("Pedal dot", ".")
+fet_beginchar ("Pedal dot", ".");
        set_char_box (0, penw#, 0, penw#);
 
        pickup pencircle scaled penw;
 
-       drawdot (1/2 penw, 1/2 penw);
+       drawdot (hround (1/2 penw), vround (1/2 penw));
 fet_endchar;
 
 
@@ -119,7 +122,7 @@ def draw_pedal_P (expr show_labels) =
 begingroup;
        clearxy;
 
-       penpos1 (penh, 0);
+       penpos1 (hround penh, 0);
        penpos2 (penw, 55);
        penpos3 (penw, pedalpha);
        penpos4 (1.2 penh, -pedalpha);
@@ -131,10 +134,10 @@ begingroup;
        penpos10 (1.4 penw, 50);
        penpos11 (penh, 90 + pedalpha);
 
-       z1r = (0.6 w, h);
-       x2l = x1l - penw;
-       y2 = 0.7 h;
-       x3r = x2l + 2 penw;
+       z1r = (hround 0.6 w, h);
+       x2l = hround (x1l - penw) + xpart feta_offset;
+       y2 = vround (0.7 h) + ypart feta_offset;
+       x3r = hround (x2l + 2 penw);
        y3r = 0.4 h;
        z4l = z5r + 1/4 (z3r - z5r);
        x5 = 1/4 w;
@@ -149,7 +152,7 @@ begingroup;
        x11l = w;
        y11 = 1/5 h;
 
-       z1' = 0.9 [z2, z1];
+       z1' = round (0.9 [z2, z1]) + (xpart feta_offset, 0);
        penpos1' (penh, 0);
 
        if show_labels = 1:
@@ -169,13 +172,13 @@ begingroup;
                       .. z10e
                       ..tension 2.5.. z11e;
 
-       penpos12 (penh, 0);
+       penpos12 (hround penh, 0);
        penpos13 (penw, -90 - pedbeta);
-       penpos14 (penh, 90);
+       penpos14 (vround penh, 90);
        penpos15 (penw, -90 + pedbeta);
        penpos16 (penh, 180 + pedbeta);
 
-       z12 = (5/9 x1, y2);
+       z12r = (hround (5/9 x1 + 1/2 hround penh), y2);
        z13l = (1/2 x12r, y15r);
        z14r = z1r;
        z15l = (1/2 [x16, w], y2l + 0.5 penw);
@@ -199,18 +202,18 @@ def draw_pedal_d (expr show_labels) =
 begingroup;
        clearxy;
 
-       penpos1 (penh, -10 - 90);
-       penpos2 (penw, 190);
-       penpos3 (2 penh, 90);
-       penpos4 (3/4 penw, 0);
+       penpos1 (vround penh, -10 - 90);
+       penpos2 (hround penw, 190);
+       penpos3 (vround (2 penh), 90);
+       penpos4 (hround (3/4 penw), 0);
        penpos5 (penh, -70);
 
        x1r = 0;
        y1l = h;
-       z2 = (w - 1/2 penw, 1/2 pedalbh + penh);
-       z3l = (x5l, 0);
-       z4l = (1/3 w, 1/2 pedalbh);
+       z2 = (w - 1/2 hround penw, 1/2 pedalbh + penh);
+       z4l = (hround (1/3 w), 1/2 pedalbh);
        z5l = (2/3 w, pedalbh);
+       z3l = (hround x5l, 0);
 
        if show_labels = 1:
                penlabels (1, 2, 3, 4, 5);
@@ -239,9 +242,11 @@ begingroup;
        penpos8 (penh, pedalpha - 90);
 
        z1l = (0, 1/5 pedalh);
-       z2 = z1 + dir pedalpha * penw;
+       % this helps to make the path go through z2 at low resolutions
+       z2 = round (z1 + dir pedalpha * penw) + feta_offset;
        z3 = (3/5 w, 8/9 h);
        z4 = (2/9 w,  y3);
+       x4r := hround x4r;
        x5r = 0;
        y5 = y2;
        x6 = 3/8 w;
@@ -250,52 +255,51 @@ begingroup;
        x8r = w;
        y8 = 1/5 pedalh;
 
-       if show_labels = 1:
-               penlabels (range 1 thru 8);
-       fi;
-
        soft_penstroke z1e
-                      --- z2e
+                      -- z2e{z2 - z1}
                       ..tension 1.1.. z3e
                       ..tension 1.05.. z4e
                       ..tension 1.1.. z5e
                       ..tension 1.5.. z6e{dir - pedalpha}
                       ..tension 1.1.. z7e
                       ..tension 2.5.. z8e;
+
+       if show_labels = 1:
+               penlabels (range 1 thru 8);
+       fi;
 endgroup;
 enddef;
 
 
-fet_beginchar ("Pedal P", "P")
+fet_beginchar ("Pedal P", "P");
        set_char_box (0, 5/6 pedalh#, 0, pedalh#);
 
        draw_pedal_P (1);
 fet_endchar;
 
 
-fet_beginchar ("Pedal d", "d")
+fet_beginchar ("Pedal d", "d");
        set_char_box (0, 2/3 pedalh#, 0, 7/8 pedalh#);
 
        draw_pedal_d (1);
 fet_endchar;
 
 
-fet_beginchar ("Pedal e", "e")
+fet_beginchar ("Pedal e", "e");
        set_char_box (0, 2/5 pedalh#, 0, pedalbh#);
 
        draw_pedal_e (1);
 fet_endchar;
 
 
-fet_beginchar ("Pedal Ped", "Ped")
+fet_beginchar ("Pedal Ped", "Ped");
        P_width# = 5/6 pedalh#;
        e_width# = 2/5 pedalh#;
        d_width# = 2/3 pedalh#;
        define_pixels (P_width, e_width, d_width);
 
-       e_height# = pedalbh#;
-       d_height# = 7/8 pedalh#;
-       define_pixels (e_height, d_height);
+       e_height = pedalbh;
+       d_height = 7/8 pedalh;
 
        % Pe = -0.034 pedalh == -0.07 staff-space
        % ed = -0.27 pedalh == -0.53 staff-space
@@ -303,18 +307,20 @@ fet_beginchar ("Pedal Ped", "Ped")
        ed_kern# = -0.27 pedalh#;
        define_pixels (Pe_kern, ed_kern);
 
-       w := d_width;
-       h := d_height;
+       w := hround d_width;
+       h := vround d_height;
        draw_pedal_d (0);
-       currentpicture := currentpicture shifted (e_width + ed_kern, 0);
+       currentpicture := currentpicture
+                           shifted (hround (e_width + ed_kern), 0);
 
-       w := e_width;
-       h := e_height;
+       w := hround e_width;
+       h := vround e_height;
        draw_pedal_e (0);
-       currentpicture := currentpicture shifted (P_width + Pe_kern, 0);
+       currentpicture := currentpicture
+                           shifted (hround (P_width + Pe_kern), 0);
 
-       w := P_width;
-       h := pedalh;
+       w := hround P_width;
+       h := vround pedalh;
        draw_pedal_P (0);
 
        set_char_box (0, P_width# + Pe_kern# + e_width# + ed_kern# + d_width#,
@@ -322,4 +328,4 @@ fet_beginchar ("Pedal Ped", "Ped")
 fet_endchar;
 
 
-fet_endgroup ("pedal")
+fet_endgroup ("pedal");
index 5a038af02ac0d8c6532ab1220de843fa2c86eea7..e518e4c225b248fd47ff6c90750de29eca33e42e 100644 (file)
@@ -1,13 +1,19 @@
 fet_begingroup ("dots");
 
-save dot_radius;
-4 dot_radius# = staff_space# - stafflinethickness#;
-define_whole_blacker_pixels (dot_radius);
-
-fet_beginchar ("duration dot", "dot")
-       pickup pencircle scaled 2 dot_radius;
-       drawdot (dot_radius, 0);
-       set_char_box (0, 2*dot_radius#, dot_radius#, dot_radius#);
+save dot_diam;
+
+2 dot_diam# = staff_space# - stafflinethickness#;
+define_whole_blacker_pixels (dot_diam);
+
+fet_beginchar ("duration dot", "dot");
+       pickup pencircle scaled dot_diam;
+
+       lft x0 = 0;
+       top y0 = vround (.5 dot_diam);
+
+       drawdot z0;
+
+       set_char_box (0, dot_diam#, .5 dot_diam#, .5 dot_diam#);
 fet_endchar;
 
-fet_endgroup("dots");
+fet_endgroup ("dots");
index 5822941af2179d7f807619e7d8c714f9be7d7a96..6e36b003a46714ef38b5143bf4d5019b419add81 100644 (file)
@@ -9,10 +9,10 @@
 %
 
 
-fet_begingroup ("scripts")
+fet_begingroup ("scripts");
 
 def draw_fermata =
-       save alpha, radius, crook_thinness, crook_fatness, dot_radius;
+       save alpha, radius, crook_thinness, crook_fatness, dot_size;
        save pat;
        path pat;
 
@@ -30,7 +30,9 @@ def draw_fermata =
        set_char_box (w#, w#, crook_thinness# / 2, h#);
 
        define_pixels (radius, crook_thinness, crook_fatness);
-       dot_radius = round (4/6 crook_fatness);
+
+       dot_size# = 8/6 crook_fatness#;
+       define_whole_blacker_pixels (dot_size);
 
        penpos1 (crook_thinness, 0);
        penpos2 (crook_fatness, -90);
@@ -42,38 +44,38 @@ def draw_fermata =
               .. {dir (90 - alpha)}z1r
               .. {right}z2r;
        pat := pat
-              & reverse pat xscaled -1
-              & cycle;
+              -- reverse pat xscaled -1 shifted (-feta_eps, 0)
+              -- cycle;
        fill pat;
 
-       pickup pencircle scaled 2 dot_radius;
+       pickup pencircle scaled dot_size;
        x4 = 0;
-       bot y4 = -crook_thinness / 2;
+       bot y4 = vround (-crook_thinness / 2);
        drawdot z4;
 enddef;
 
 
-fet_beginchar ("fermata up", "ufermata")
+fet_beginchar ("fermata up", "ufermata");
        draw_fermata;
        penlabels (1, 2, 4);
 fet_endchar;
 
 
-fet_beginchar ("fermata down", "dfermata")
+fet_beginchar ("fermata down", "dfermata");
        draw_fermata;
        y_mirror_char;
 fet_endchar;
 
 
 def draw_short_fermata =
-       save fat_factor, thinness, dot_radius;
-       save left_dist, right_dist;
-       pair left_dist, right_dist;
+       save fat_factor, thinness, dot_size;
+       save left_dist, right_dist, se, ne;
+       pair left_dist, right_dist, se, ne;
 
        set_char_box (staff_space#, staff_space#, 0, 2.2 staff_space#);
 
-       dot_radius# = 0.133 staff_space# + 1.33 linethickness#;
-       define_pixels (dot_radius)
+       dot_size# = 0.266 staff_space# + 2.666 linethickness#;
+       define_whole_blacker_pixels (dot_size);
 
        fat_factor = .11;
        thinness = 1.5 linethickness;
@@ -90,24 +92,27 @@ def draw_short_fermata =
        z1 - z4 = whatever * (charwd, -charht);
        z4 = fat_factor [z3, z5];
 
-       left_dist = (unitvector (z3 - z5) rotated 90) * 0.5 thinness;
-       right_dist = (unitvector (z2 - z3) rotated 90) * 0.5 thinness;
-
-       fill bot z5
-            .. (z5 - left_dist)
-            --- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
-                  ((z1 - right_dist) -- (z4 - right_dist)))
-            --- (z1 - right_dist)
-            .. bot z1
-            --- bot z2
-            .. (z2 + right_dist)
-            --- (z3 + right_dist)
+       ne = unitvector (z3 - z5);
+       se = unitvector (z2 - z3);
+
+       left_dist = (ne rotated 90) * 0.5 thinness;
+       right_dist = (se rotated 90) * 0.5 thinness;
+
+       fill bot z5{right}
+            .. (z5 - left_dist){ne}
+            -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
+                 ((z1 - right_dist) -- (z4 - right_dist)))
+            -- (z1 - right_dist){se}
+            .. bot z1{right}
+            -- bot z2{right}
+            .. (z2 + right_dist){-se}
+            -- (z3 + right_dist){-se}
             .. top z3
-            .. (z3 + left_dist)
-            --- (z5 + left_dist)
+            .. (z3 + left_dist){-ne}
+            -- (z5 + left_dist){-ne}
             .. cycle;
 
-       pickup pencircle scaled 2 dot_radius;
+       pickup pencircle scaled dot_size;
 
        x1 - 2x6 = x2;
        bot y6 = -d;
@@ -115,29 +120,29 @@ def draw_short_fermata =
        drawdot z6;
 enddef;
 
-fet_beginchar ("short fermata up", "ushortfermata")
+fet_beginchar ("short fermata up", "ushortfermata");
        draw_short_fermata;
        labels (1, 2, 3, 4, 5, 6);
 fet_endchar;
 
 
-fet_beginchar ("short fermata down", "dshortfermata")
+fet_beginchar ("short fermata down", "dshortfermata");
        draw_short_fermata;
        xy_mirror_char;
 fet_endchar;
 
 
 def draw_long_fermata =
-       save stemthick, beamheight, dot_radius, wd;
+       save stemthick, beamheight, dot_size, wd;
        save pat;
        path pat;
 
-       define_pixels (wd, dot_radius);
-
        wd# = 2.5 staff_space#;
-       stemthick = 1.5 linethickness;
+       stemthick = hround (1.5 linethickness);
        beamheight = 0.3 staff_space + linethickness;
-       dot_radius# = 0.133 staff_space# + 1.333 * linethickness#;
+       dot_size# = 0.266 staff_space# + 2.666 * linethickness#;
+       define_pixels (wd);
+       define_whole_blacker_pixels (dot_size);
 
        set_char_box (wd# / 2, wd# / 2, 0, 3/2 staff_space#);
 
@@ -145,49 +150,44 @@ def draw_long_fermata =
 
        top y1 = h;
        lft x1 = -b;
-       x2 = x3 = 0;
-       y2 = h;
-       y3 = h - beamheight;
 
-       pat := z2
-              --- top z1
-              .. lft z1;
+       pat := top z1{left}
+              .. {down}lft z1;
 
        pickup pencircle scaled stemthick;
 
-       x4 = -b + stemthick;
-       y4 = y3;
-       lft x5 = -b;
-       bot y5 = -d;
+       x2 = -b + stemthick;
+       y2 = h - beamheight;
+       lft x3 = -b;
+       bot y3 = -d;
 
        pat := pat
-              --- lft z5
-              .. bot z5
-              .. rt z5
-              --- z4
-              --- z3;
+              -- lft z3
+              .. bot z3
+              .. rt z3
+              -- z2;
        pat := pat
-              & reverse pat xscaled -1
-              & cycle;
+              -- reverse pat xscaled -1 shifted (-feta_eps, 0)
+              -- cycle;
 
        fill pat;
 
-       pickup pencircle scaled 2 dot_radius;
+       pickup pencircle scaled dot_size;
 
-       x6 = 0;
-       bot y6 = -d;
+       x4 = 0;
+       bot y4 = -d;
 
-       drawdot z6;
+       drawdot z4;
 enddef;
 
 
-fet_beginchar ("long fermata up", "ulongfermata")
+fet_beginchar ("long fermata up", "ulongfermata");
        draw_long_fermata;
-       labels (1, 2, 3, 4, 5, 6);
+       labels (1, 2, 3, 4);
 fet_endchar;
 
 
-fet_beginchar ("long fermata down", "dlongfermata")
+fet_beginchar ("long fermata down", "dlongfermata");
        draw_long_fermata;
        y_mirror_char;
 fet_endchar;
@@ -196,21 +196,23 @@ fet_endchar;
 def draw_very_long_fermata =
        save ibeamheight, obeamheight;
        save ihwd, ohwd, iht, oht;      % inner/outer half_width/height
-       save stemthick, dot_radius;
+       save stemthick, dot_size;
        save opat, ipat;
        path opat, ipat;
 
-       define_pixels (ihwd, ohwd, iht, oht)
-
        ihwd# = 1.0 staff_space#;
        ohwd# = 1.5 staff_space#;
        iht# = 0.9 staff_space#;
        oht# = 1.6 staff_space#;
+       define_pixels (ihwd, ohwd, iht, oht)
 
-       stemthick = 1.5 linethickness;
-       ibeamheight = 0.3 staff_space;
-       obeamheight = 0.5 staff_space;
-       dot_radius = (iht - ibeamheight) * 4/10;
+       stemthick = hround (1.5 linethickness);
+       ibeamheight# = 0.3 staff_space#;
+       obeamheight# = 0.5 staff_space#;
+       define_pixels (ibeamheight, obeamheight);
+
+       dot_size# = (iht# - ibeamheight#) * 8/10;
+       define_whole_blacker_pixels (dot_size);
 
        set_char_box (ohwd#, ohwd#, 0, oht#);
 
@@ -218,71 +220,61 @@ def draw_very_long_fermata =
 
        top y1 = oht;
        lft x1 = -ohwd;
-       x2 = x3 = 0;
-       y2 = oht;
-       y3 = oht - obeamheight;
        top y11 = iht;
        lft x11 = -ihwd;
-       x12 = x13 = 0;
-       y12 = iht;
-       y13 = iht - ibeamheight;
 
-       opat := z2
-               --- top z1
-               .. lft z1;
-       ipat := z12
-               --- top z11
-               .. lft z11;
+       opat := top z1{left}
+               .. {down}lft z1;
+       ipat := top z11{left}
+               .. {down}lft z11;
 
        pickup pencircle scaled stemthick;
 
-       x4 = -ohwd + stemthick;
-       y4 = y3;
-       lft x5 = -ohwd;
-       bot y5 = 0;
-       x14 = -ihwd + stemthick;
-       y14 = y13;
-       lft x15 = -ihwd;
-       bot y15 = 0;
+       x2 = -ohwd + stemthick;
+       y2 = oht - obeamheight;
+       lft x3 = -ohwd;
+       bot y3 = 0;
+       x12 = -ihwd + stemthick;
+       y12 = iht - ibeamheight;
+       lft x13 = -ihwd;
+       bot y13 = 0;
 
        opat := opat
-               --- lft z5
-               .. bot z5
-               .. rt z5
-               --- z4
-               --- z3;
+               -- lft z3
+               .. bot z3
+               .. rt z3
+               -- z2;
        opat := opat
-               & reverse opat xscaled -1
-               & cycle;
+               -- reverse opat xscaled -1 shifted (-feta_eps, 0)
+               -- cycle;
        ipat := ipat
-               --- lft z15
-               .. bot z15
-               .. rt z15
-               --- z14
-               --- z13;
+               -- lft z13
+               .. bot z13
+               .. rt z13
+               -- z12;
        ipat := ipat
-               & reverse ipat xscaled -1
-               & cycle;
+               -- reverse ipat xscaled -1 shifted (-feta_eps, 0)
+               -- cycle;
 
        fill opat;
        fill ipat;
 
-       pickup pencircle scaled 2 dot_radius;
+       pickup pencircle scaled dot_size;
 
-       x6 = 0;
-       bot y6 = -d;
+       x4 = 0;
+       bot y4 = -d;
 
-       drawdot z6;
+       drawdot z4;
 enddef;
 
 
-fet_beginchar ("very long fermata up", "uverylongfermata")
+fet_beginchar ("very long fermata up", "uverylongfermata");
        draw_very_long_fermata;
-       labels (1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 6);
+       labels (1, 2, 3, 11, 12, 13, 4);
 fet_endchar;
 
 
-fet_beginchar ("very long fermata down", "dverylongfermata")
+fet_beginchar ("very long fermata down", "dverylongfermata");
        draw_very_long_fermata;
        y_mirror_char;
 fet_endchar;
@@ -294,7 +286,7 @@ fet_endchar;
 % the same way in the score.
 %
 
-fet_beginchar ("Thumb", "thumb")
+fet_beginchar ("Thumb", "thumb");
        save thin, height, width, thick, depth;
        height# = 5/4 width#;
        height# = staff_space#;
@@ -365,24 +357,24 @@ def draw_accent (expr bottom_left, top_right, thickness, diminish) =
        y7 = y4;
 
        fill z1l
-            --- z3l
-            --- z7
-            --- z5l
-            --- z6l
+            -- z3l
+            -- z7
+            -- z5l
+            -- z6l
             .. lft z6{down}
             .. bot z6
             .. z6r
-            --- z4l
+            -- z4l
             ..tension 0.8.. rt z4
             ..tension 0.8.. z4r
-            --- z1r
+            -- z1r
             .. top z1
             .. lft z1{down}
             .. cycle;
 enddef;
 
 
-fet_beginchar ("> accent", "sforzato")
+fet_beginchar ("> accent", "sforzato");
        set_char_box (.9 staff_space#, .9 staff_space#,
                      .5 staff_space#, .5 staff_space#);
 
@@ -393,7 +385,7 @@ fet_beginchar ("> accent", "sforzato")
 fet_endchar;
 
 
-fet_beginchar ("espr", "espr")
+fet_beginchar ("espr", "espr");
        set_char_box (1.9 staff_space#, 1.9 staff_space#,
                      .5 staff_space#, .5 staff_space#);
 
@@ -403,7 +395,7 @@ fet_beginchar ("espr", "espr")
 fet_endchar;
 
 
-fet_beginchar ("staccato dot", "staccato")
+fet_beginchar ("staccato dot", "staccato");
        save radius;
        radius# = 0.20 * staff_space#;
        define_whole_pixels (radius);
@@ -419,7 +411,7 @@ def draw_staccatissimo =
        save radius, height;
        height# = .8 staff_space#;
        radius# = linethickness# + .1 staff_space#;
-       define_whole_pixels (radius);
+       define_whole_blacker_pixels (radius);
        define_pixels (height);
 
        draw_brush ((0, 0), linethickness, (0, height), 2 radius);
@@ -429,52 +421,51 @@ def draw_staccatissimo =
 enddef;
 
 
-fet_beginchar ("staccatissimo/martellato up", "ustaccatissimo")
+fet_beginchar ("staccatissimo/martellato up", "ustaccatissimo");
        draw_staccatissimo;
 fet_endchar;
 
 
-fet_beginchar ("staccatissimo/martellato down", "dstaccatissimo")
+fet_beginchar ("staccatissimo/martellato down", "dstaccatissimo");
        draw_staccatissimo;
        y_mirror_char;
 fet_endchar;
 
 
-fet_beginchar ("portato/single tenuto", "tenuto")
+fet_beginchar ("portato/single tenuto", "tenuto");
        save thick;
        thick# = 1.6 linethickness#;
-       define_whole_pixels (thick);
+       define_whole_blacker_pixels (thick);
 
        set_char_box (.6 staff_space#, .6 staff_space#,
-                     thick# / 2,thick# / 2);
+                     thick# / 2, thick# / 2);
 
-       pickup pencircle scaled thick;
        draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
 fet_endchar;
 
 
 def draw_portato =
-       save thick, radius;
+       save thick, dot_size;
        thick# = 1.4 linethickness#;
-       radius# = 1.2 linethickness# + 0.04 staff_space#;
-       define_whole_pixels (thick, radius);
+       dot_size# = 2.4 linethickness# + 0.08 staff_space#;
+       define_whole_blacker_pixels (thick, dot_size);
 
        set_char_box (.6 staff_space#, .6 staff_space#,
-                     thick# / 2, .5 staff_space# + radius#);
+                     thick# / 2, .5 staff_space# + .5 dot_size#);
 
        draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
 
-       pickup pencircle scaled 2 radius;
+       pickup pencircle scaled dot_size;
        drawdot (0, h);
 enddef;
 
 
-fet_beginchar ("portato/tenuto with staccato", "uportato")
+fet_beginchar ("portato/tenuto with staccato", "uportato");
        draw_portato;
 fet_endchar;
 
 
-fet_beginchar ("portato/tenuto with staccato", "dportato")
+fet_beginchar ("portato/tenuto with staccato", "dportato");
        draw_portato;
        y_mirror_char
 fet_endchar;
@@ -482,8 +473,8 @@ fet_endchar;
 
 def draw_marcato =
        save fat_factor, thinness;
-       save left_dist, right_dist;
-       pair left_dist, right_dist;
+       save left_dist, right_dist, ne, se;
+       pair left_dist, right_dist, ne, se;
 
        set_char_box (staff_space# / 2, staff_space# / 2,
                      0, 1.1 staff_space#);
@@ -503,26 +494,29 @@ def draw_marcato =
        z1 - z4 = whatever * (charwd, -charht);
        z4 = fat_factor [z3, z5];
 
-       left_dist = (unitvector (z3 - z5) rotated 90) * 0.5 thinness;
-       right_dist = (unitvector (z2 - z3) rotated 90) * 0.5 thinness;
-
-       fill bot z5
-            .. (z5 - left_dist)
-            --- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
-                  ((z1 - right_dist) -- (z4 - right_dist)))
-            --- (z1 - right_dist)
-            .. bot z1
-            --- bot z2
-            .. (z2 + right_dist)
-            --- (z3 + right_dist)
+       ne = unitvector (z3 - z5);
+       se = unitvector (z2 - z3);
+
+       left_dist = (ne rotated 90) * 0.5 thinness;
+       right_dist = (se rotated 90) * 0.5 thinness;
+
+       fill bot z5{right}
+            .. (z5 - left_dist){ne}
+            -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint
+                 ((z1 - right_dist) -- (z4 - right_dist)))
+            -- (z1 - right_dist){se}
+            .. bot z1{right}
+            -- bot z2{right}
+            .. (z2 + right_dist){-se}
+            -- (z3 + right_dist){-se}
             .. top z3
-            .. (z3 + left_dist)
-            --- (z5 + left_dist)
+            .. (z3 + left_dist){-ne}
+            -- (z5 + left_dist){-ne}
             .. cycle;
 enddef;
 
 
-fet_beginchar ("marcato up", "umarcato")
+fet_beginchar ("marcato up", "umarcato");
        draw_marcato;
        labels (1, 2, 3, 4, 5);
 fet_endchar;
@@ -534,7 +528,7 @@ fet_endchar;
 % it is *point*-symmetric with the "up" version
 %
 
-fet_beginchar ("marcato down", "dmarcato")
+fet_beginchar ("marcato down", "dmarcato");
        draw_marcato;
        xy_mirror_char;
 fet_endchar;
@@ -546,7 +540,7 @@ fet_endchar;
 % TODO: too light at 20pt
 %
 
-fet_beginchar ("open (unstopped)", "open")
+fet_beginchar ("open (unstopped)", "open");
        save thin, height, width, thick;
 
        height# = 5/4 width#;
@@ -578,20 +572,29 @@ fet_beginchar ("open (unstopped)", "open")
 fet_endchar;
 
 
-fet_beginchar ("plus (stopped)", "stopped")
-       save thick, size;
+fet_beginchar ("plus (stopped)", "stopped");
+       save hthick, vthick, size, outer_hsize, outer_vsize;
 
-       thick = 2 linethickness;
+       hthick# = vthick# = 2 linethickness#;
        size# = 1.1 staff_space#;
+       define_whole_blacker_pixels (vthick);
+       define_whole_vertical_blacker_pixels (hthick);
 
        set_char_box (size# / 2, size# / 2, size# / 2, size# / 2);
 
-       draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick);
-       addto currentpicture also currentpicture rotated 90;
+       outer_hsize = hround ((b + w - vthick) / 2);
+       outer_vsize = vround ((h + d - hthick) / 2);
+       w := b := (2 outer_hsize + vthick) / 2;
+       h := d := (2 outer_vsize + hthick) / 2;
+
+       draw_rounded_block ((-b, -d + outer_vsize),
+                           (w, -d + outer_vsize + hthick), hthick);
+       draw_rounded_block ((-b + outer_hsize, -d),
+                           (-b + outer_hsize + vthick, h), vthick);
 fet_endchar;
 
 
-fet_beginchar ("Upbow", "upbow")
+fet_beginchar ("Upbow", "upbow");
        save ht, wd, thick;
 
        thick = 1.4 linethickness;
@@ -605,15 +608,15 @@ fet_beginchar ("Upbow", "upbow")
 fet_endchar;
 
 
-fet_beginchar ("Downbow", "downbow")
+fet_beginchar ("Downbow", "downbow");
        save stemthick, beamheight, wd;
        save pat;
        path pat;
 
+       wd# = 1.5 staff_space#;
        define_pixels (wd);
 
-       wd# = 1.5 staff_space#;
-       stemthick = 1.2 linethickness;
+       stemthick = hround (1.2 linethickness);
 
        set_char_box (wd# / 2, wd# / 2, 0, 4/3 staff_space#);
 
@@ -623,32 +626,29 @@ fet_beginchar ("Downbow", "downbow")
 
        top y1 = h;
        lft x1 = -b;
-       x2 = x3 = 0;
-       y2 = h;
-       y3 = h - beamheight;
 
-       pat := z2
-              --- top z1
-              .. lft z1;
+       pat := top z1{left}
+              .. {down}lft z1;
 
        pickup pencircle scaled stemthick;
 
-       x4 = -b + stemthick;
-       y4 = y3;
-       lft x5 = -b;
-       bot y5 = -d;
+       x2 = -b + stemthick;
+       y2 = h - beamheight;
+       lft x3 = -b;
+       bot y3 = -d;
 
        pat := pat
-              --- lft z5
-              .. bot z5
-              .. rt z5
-              --- z4
-              --- z3;
+              -- lft z3
+              .. bot z3
+              .. rt z3
+              -- z2;
        pat := pat
-              & reverse pat xscaled -1
-              & cycle;
+              -- reverse pat xscaled -1 shifted (-feta_eps, 0)
+              -- cycle;
 
        fill pat;
+
+       labels (1, 2, 3);
 fet_endchar;
 
 %
@@ -695,7 +695,7 @@ def draw_turn =
                  .. z3r{down}
                  .. z2r{left};
        fill swoosh
-            .. (swoosh scaled -1)
+            .. swoosh scaled -1 shifted (-feta_eps, -feta_eps)
             .. cycle;
 
        x5r = x4;
@@ -710,17 +710,17 @@ def draw_turn =
                 .. z6l
                 -- cycle;
        fill ploop;
-       fill ploop scaled -1;
+       fill ploop scaled -1 shifted (-feta_eps, -feta_eps);
 enddef;
 
 
-fet_beginchar ("Reverse turn","reverseturn")
+fet_beginchar ("Reverse turn", "reverseturn");
        draw_turn;
        currentpicture := currentpicture yscaled -1;
 fet_endchar;
 
 
-fet_beginchar ("Turn","turn")
+fet_beginchar ("Turn", "turn");
        draw_turn;
        penlabels (1, 2, 3, 4, 5, 6, 7);
 fet_endchar;
@@ -735,7 +735,7 @@ fet_endchar;
 % FIXME generic macros for serifs: top of the t and bottom of r
 %
 
-fet_beginchar ("Trill (`tr')", "trill")
+fet_beginchar ("Trill (`tr')", "trill");
        save start_nib_angle, ascender_extra, ex, hair_thick, fatness;
        save slant, t_fatness, r_fatness, kerning, t_overshoot;
        save uitschieter, bulb_size, krul_ang;
@@ -805,8 +805,8 @@ fet_beginchar ("Trill (`tr')", "trill")
        krul_p := z4{up}
                  ..tension 0.98.. z5
                  .. z6
-                 .. z5
-                 --- z7;
+                 .. z5{z7 - z5}
+                 -- z7;
 
        z4' = point 0.85 of krul_p;
        penpos4' (hair_thick, angle (direction 0.85 of krul_p) + 90);
@@ -874,17 +874,17 @@ fet_beginchar ("Trill (`tr')", "trill")
        before := z13l{up}
                  .. {down}z11l;
        after := z9r{up}
-                .. z7r
-                --- z7'r;
+                .. z7r{z7' - z7}
+                -- z7'r;
        (u, v) = before intersectiontimes after;
 
        % the connection between `t' and `r', the body of the `r',
        % and part of the bulb
-       fill z7'l
-            --- z7l
+       fill z7'l{z7 - z7'}
+            -- z7l
             .. z9l{down}
-            --- simple_serif (z10l, z10r, -30)
-            --- z9r{up}
+            -- simple_serif (z10l, z10r, -30)
+            -- z9r{up}
             ..tension 0.94.. z13r{down}
             -- z15{down}
             .. z13l{up}
@@ -909,11 +909,10 @@ def draw_heel =
        path pat;
 
        radius# := .5 staff_space#;
-       define_pixels (radius);
 
        set_char_box (radius#, radius#, radius#, 2/3 staff_space#);
 
-       thickness := 1.5 linethickness;
+       thickness := hround (1.5 linethickness);
 
        pickup pencircle scaled thickness;
 
@@ -928,25 +927,25 @@ def draw_heel =
 
        pat := top z3{right}
               .. lft z2{up}
-              .. lft z1{up}
+              -- lft z1
               .. top z1
-              .. rt z1{down}
-              .. rt z2{down}
+              .. rt z1
+              -- rt z2{down}
               .. bot z3{left};
        pat := pat
-              & reverse pat xscaled -1
-              & cycle;
+              -- reverse pat xscaled -1 shifted (-feta_eps, 0)
+              -- cycle;
        fill pat;
 enddef;
 
 
-fet_beginchar ("left heel", "upedalheel")
+fet_beginchar ("left heel", "upedalheel");
        draw_heel;
        labels (1, 2, 3);
 fet_endchar;
 
 
-fet_beginchar ("right heel", "dpedalheel")
+fet_beginchar ("right heel", "dpedalheel");
        draw_heel;
        y_mirror_char;
 fet_endchar;
@@ -966,49 +965,60 @@ def draw_toe =
 enddef;
 
 
-fet_beginchar ("left toe", "upedaltoe")
+fet_beginchar ("left toe", "upedaltoe");
        draw_toe;
 fet_endchar;
 
 
-fet_beginchar ("right toe", "dpedaltoe")
+fet_beginchar ("right toe", "dpedaltoe");
        draw_toe;
        y_mirror_char;
 fet_endchar;
 
 
-fet_beginchar ("Flageolet", "flageolet")
-       save height, width, thickness;
-       height #= 4/15 staffsize#;
-       width #= height#;
-       thickness #= blot_diameter#;
-       define_pixels (height, width, thickness);
+fet_beginchar ("Flageolet", "flageolet");
+       save height, width, thickness, superness;
 
-       set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
+       height# = 4/15 staffsize#;
+       width# = height#;
+       thickness# = blot_diameter#;
+       define_pixels (height, width);
+       define_whole_blacker_pixels (thickness);
 
-       pickup pencircle scaled thickness;
+       set_char_box (width# / 2, width# / 2, height# / 2, height# / 2);
 
        penpos1 (thickness, 90);
        penpos2 (thickness, 180);
        penpos3 (thickness, 270);
        penpos4 (thickness, 0);
 
-       x1= .5 [x2, x4];
        x1 = 0;
-       top y1 = height / 2;
-       rt x4 - lft x2 = width;
+       y1r = h;
+       x4r = w;
+       x2r = -x4r;
        y2 = 0;
        y4 = y2;
        x3 = x1;
-       bot y3 = -height / 2;
+       y3r = -y1r;
 
        penlabels (1, 2, 3, 4);
 
-       penstroke z1e
-                 .. z2e
-                 .. z3e
-                 .. z4e
-                 .. cycle;
+       % mf doesn't handle pixel dropouts in outline objects, so we use
+       % `draw' if not called by mpost
+       if known miterlimit:
+               penstroke z1e
+                         .. z2e
+                         .. z3e
+                         .. z4e
+                         .. cycle;
+       else:
+               pickup pencircle scaled thickness;
+               draw z1
+                    .. z2
+                    .. z3
+                    .. z4
+                    .. cycle;
+       fi;
 fet_endchar;
 
 
@@ -1016,7 +1026,7 @@ fet_endchar;
 % TODO:  ARGRGHGH code dup.
 %
 
-fet_beginchar ("Segno", "segno")
+fet_beginchar ("Segno", "segno");
        save thin, thick, ball_diam, darkness, pointheight;
        save wd, ht, thick_nibangle, ball_nib_thick;
        save turndir;
@@ -1092,7 +1102,7 @@ fet_beginchar ("Segno", "segno")
 fet_endchar;
 
 
-fet_beginchar ("Coda", "coda")
+fet_beginchar ("Coda", "coda");
        save stickout, thin, thick, codawidth, codaheight;
 
        stickout# = 0.35 staff_space#;
@@ -1126,12 +1136,12 @@ fet_beginchar ("Coda", "coda")
                  .. z4e{left}
                  .. cycle;
 
-       draw_gridline ((0,-h),(0,h),thin);
-       draw_gridline ((-w,0),(w,0),thin);
+       draw_gridline ((0, -h), (0, h), thin);
+       draw_gridline ((-w, 0), (w, 0), thin);
 fet_endchar;
 
 
-fet_beginchar ("Varied Coda", "varcoda")
+fet_beginchar ("Varied Coda", "varcoda");
        save thin, thick, codawidth, codaheight;
        thin# = 1.2 linethickness#;
        thick# = 1.0 linethickness# + 0.25 staff_space#;
@@ -1146,13 +1156,13 @@ fet_beginchar ("Varied Coda", "varcoda")
        y1 = y2 - thin;
        x2 = codawidth;
        y2 = codaheight;
-       draw_rounded_block (z1, z2, blot_diameter);
+       draw_block (z1, z2);
 
        x3 = x1;
        y3 = -codaheight;
        x4 = x1 + thick;
        y4 = y2;
-       draw_rounded_block (z3, z4, blot_diameter);
+       draw_block (z3, z4);
 
        labels (1, 2, 3, 4);
 
@@ -1189,7 +1199,7 @@ def draw_comma =
             .. z2r{dir alpha}
             .. z1r{dir (alpha - 90)}
             .. z3l{dir (270 - alpha)}
-            .. z4l{dir (alpha + 180)}
+            .. z4l{dir (180 - alpha)}
             .. z3r{dir (90-alpha)}
             .. cycle;
 enddef;
@@ -1277,22 +1287,20 @@ def draw_arpeggio =
        z9 = 2 [z7, (width / 2, height / 2)];
 
        fill z1l{se}
-            --- z6
+            -- z6
             .. z3l
             .. z7{se}
-            --- z5l
+            -- z5l
             .. z5r{nw}
-            --- z8
+            -- z8
             .. z3r
             .. z9{nw}
-            --- z1r
+            -- z1r
             .. cycle;
 enddef;
 
 
 fet_beginchar ("Arpeggio", "arpeggio");
-%      draw_staff (-2, 2, 0.0);
-
        save height, overshoot, width;
        height# = staff_space#;
        width# = 0.8 height#;
@@ -1302,6 +1310,8 @@ fet_beginchar ("Arpeggio", "arpeggio");
        set_char_box (0, width#, 0, height#);
        draw_arpeggio;
        penlabels (range 1 thru 9);
+
+       draw_staff (-2, 2, 0.0);
 fet_endchar;
 
 
@@ -1365,14 +1375,14 @@ def draw_arpeggio_arrow =
        z6 = z2l + 1/2 rthin * sw;
        z9 = (width / 2, height) + overshoot * se;
 
+       pickup pencircle scaled vround (0.5 rthin);
+
        bot z10 = (0.5 w, 0);
        lft z11 = (-0.3 w, 0.8 h);
        rt z12 = (1.3 w, 0.8 h);
 
-       pickup pencircle scaled 0.5 rthin;
-
        before_left := z1l
-                      --- z6
+                      -- z6{z6 - z1l}
                       .. {down}z3l;
        after_left := (z3 + (0, -0.25 rthin / cosd (angle (nw))))
                      -- (z11 + 0.25 rthin * ne);
@@ -1381,8 +1391,8 @@ def draw_arpeggio_arrow =
        before_right := (z12 + 0.25 rthin * nw)
                        -- (z3 + (0, -0.25 rthin / cosd (angle (nw))));
        after_right := z3r{up}
-                      .. z9
-                      --- z1r;
+                      .. z9{z1r - z9}
+                      -- z1r;
        (u_right, v_right) = before_right intersectiontimes after_right;
 
        fill subpath (0, u_left) of before_left
@@ -1400,19 +1410,13 @@ def draw_arpeggio_arrow =
             .. subpath (v_right, infinity) of after_right
             .. cycle;
 
-%      fill (z3 + (0, -0.25 rthin / cosd (angle (nw))))
-%           -- (z12 + 0.25 rthin * nw)
-%           .. top z12
-%           .. rt z12
-%           .. (z12 + 0.25 rthin * se){dir -130}
-%           .. {dir -110}(z10 + 0.25 rthin * se)
-%           .. bot z10
-%           .. (z10 + 0.25 rthin * sw){dir 110}
-%           .. {dir 130}(z11 + 0.25 rthin * sw)
-%           .. lft z11
-%           .. top z11
-%           .. (z11 + 0.25 rthin * ne)
-%           -- cycle;
+       % mf doesn't handle pixel dropouts in outline objects, so we use
+       % `draw' if not called by mpost
+       if not known miterlimit:
+               pickup pencircle scaled 0.7 rthin;
+               draw z1
+                    -- (z9 + 0.5 rthin * dir (alpha - 90));
+       fi;
 enddef;
 
 
@@ -1425,8 +1429,7 @@ fet_endchar;
 fet_beginchar ("Arpeggio arrow up", "arpeggio.arrow.1");
        draw_arpeggio_arrow;
        currentpicture := currentpicture scaled -1
-                                        shifted (0.8 staff_space,
-                                                 staff_space);
+                                        shifted (w - feta_eps, h - feta_eps);
 fet_endchar;
 
 
@@ -1459,7 +1462,8 @@ fet_beginchar ("Caesura", "caesura");
 
        set_char_box (0, 2.0 staff_space#,
                      staff_space# - clearance#, height#);
-       define_pixels (space_between, clearance, height);
+       define_pixels (clearance, height);
+       define_whole_pixels (space_between);
 
        bot y1 = -d;
        top y2 = h;
index bc23437c2125a439d577a089f8ad6f86b382ae00..cdc7f1ec7209b4a89916f1865b3820eb9bf0b40d 100644 (file)
 % this file is included by feta-scripts.mf
 
 trill_thin# = 0.1 staff_space# + 0.6 stafflinethickness#;
-trill_thick# = 1/2 staff_space#;
-trill_width# = 5/12 staff_space#;
+trill_stemwidth# = trill_thin#;
+define_pixels (trill_thin);
+define_whole_blacker_pixels (trill_stemwidth);
+
+trill_thick = 1/2 staff_space;
+trill_overlap = 1/6 staff_space;
+
+trill_width# = 5/6 staff_space#;
 trill_height# = 1/2 staff_space#;
-trill_overlap# = 1/6 staff_space#;
+define_pixels (trill_height);
+define_whole_pixels (trill_width);
 
 pair trill_ne;
 trill_ne := unitvector ((2, 3));
 
-define_pixels (trill_thick, trill_thin,
-              trill_width, trill_overlap, trill_height);
-
 
 %
 % The trill element sticks out on both the left and right side
@@ -37,42 +41,41 @@ begingroup;
 
        pickup pencircle scaled trill_thin;
 
-       x1 = -trill_width;
+       x1 = -.5 trill_width;
        y1 = 0;
        z3 = whatever * trill_ne + z1;
-       top y3 = trill_height;
+       top y3 = vround trill_height;
        z2 = z3 - (trill_thick - trill_thin) * trill_ne;
 
        z4 = z1 - trill_ne * trill_overlap;
+       x4 := hround x4;
        x5 = x2;
        y5 = 0;
 
-       z3' = z3 scaled -1;
-       z5' = z5 scaled -1;
+       bot z3' = (top z3) scaled -1;
 
        nw := unitvector (z2 - z3');
 
        path p;
        p := z5
-            --- (z4 - 0.5 trill_thin * nw)
+            -- (z4 - 0.5 trill_thin * nw)
             .. bot z4
             .. lft z4
             .. (z4 + 0.5 trill_thin * nw)
-            --- (z3 + 0.5 trill_thin * nw)
+            -- (z3 + 0.5 trill_thin * nw)
             .. top z3
-            .. (z3 + 0.5 trill_thin * trill_ne)
-            --- z5';
+            .. (z3 + 0.5 trill_thin * trill_ne);
        p := p
-            & p scaled -1
-            & cycle;
+            -- p scaled -1 shifted (-feta_eps, -feta_eps)
+            -- cycle;
        p := p shifted (offset, 0);
        fill p;
 endgroup;
 enddef;
 
 
-fet_beginchar ("trilelement", "trilelement")
-       set_char_box (trill_width#, trill_width#,
+fet_beginchar ("trilelement", "trilelement");
+       set_char_box (.5 trill_width#, .5 trill_width#,
                      trill_height#, trill_height#);
 
        draw_trillelement (0);
@@ -80,62 +83,65 @@ fet_beginchar ("trilelement", "trilelement")
 fet_endchar;
 
 
-fet_beginchar ("prall", "prall")
-       set_char_box (2 trill_width#, 2 trill_width#,
+fet_beginchar ("prall", "prall");
+       set_char_box (trill_width#, trill_width#,
                      trill_height#, trill_height#);
 
-       draw_trillelement (-trill_width);
-       draw_trillelement (trill_width);
+       draw_trillelement (-hround (.5 trill_width));
+       draw_trillelement (-hround (.5 trill_width) + trill_width);
 fet_endchar;
 
 
-fet_beginchar ("mordent", "mordent")
-       set_char_box (2 trill_width#, 2 trill_width#,
+fet_beginchar ("mordent", "mordent");
+       set_char_box (trill_width#, trill_width#,
                      4/3 trill_height#, 4/3 trill_height#);
 
-       draw_trillelement (-trill_width);
-       draw_trillelement (trill_width);
+       draw_trillelement (-hround (.5 trill_width));
+       draw_trillelement (-hround (.5 trill_width) + trill_width);
 
        clearxy;
-       pickup pencircle scaled trill_thin;
+
+       pickup pencircle scaled trill_stemwidth;
 
        top y1 = h;
        bot y2 = -d;
        x1 = x2;
        x2 = 0;
 
-       draw_gridline (z2, z1, trill_thin);
+       draw_gridline (z2, z1, trill_stemwidth);
 
        labels (1, 2);
 fet_endchar;
 
 
-fet_beginchar ("prallprall", "prallprall")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("prallprall", "prallprall");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      trill_height#, trill_height#);
 
-       draw_trillelement (-trill_width);
+       draw_trillelement (-trill_width);
        draw_trillelement (0);
-       draw_trillelement (trill_width);
+       draw_trillelement (trill_width);
 fet_endchar;
 
 
-fet_beginchar ("prallmordent", "prallmordent")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("prallmordent", "prallmordent");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      4/3 trill_height#, 4/3 trill_height#);
-       draw_trillelement (-2 trill_width);
+
+       draw_trillelement (-trill_width);
        draw_trillelement (0);
-       draw_trillelement (trill_width);
+       draw_trillelement (trill_width);
 
        clearxy;
-       pickup pencircle scaled trill_thin;
+
+       pickup pencircle scaled trill_stemwidth;
 
        top y1 = h;
        bot y2 = -d;
        x1 = x2 ;
-       x2 = trill_width;
+       x2 = good.x (.5 trill_width);
 
-       draw_gridline (z2, z1, trill_thin);
+       draw_gridline (z2, z1, trill_stemwidth);
 
        labels (1, 2);
 fet_endchar;
@@ -145,139 +151,140 @@ save remember_pic;
 picture remember_pic;
 
 
-fet_beginchar ("upprall", "upprall")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("upprall", "upprall");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      trill_height#, trill_height#);
-       draw_trillelement (-2 trill_width);
-       draw_trillelement (0);
-       draw_trillelement (2 trill_width);
 
-       clearxy;
+       draw_trillelement (-trill_width);
+       draw_trillelement (0);
+       draw_trillelement (trill_width);
 
-       z1 = (-b, 0) - trill_overlap * trill_ne;
-       z2 = z1 + (0, -2 trill_height);
+       z11 = z4 shifted (-trill_width, 0);
+       z12 = z11 + (0, -2 trill_height);
 
-       penpos1 (trill_thin, angle (trill_ne) - 90);
-       penpos2 (trill_thin, angle (trill_ne yscaled -1) + 90);
-       penlabels (12);
+       penpos11 (trill_thin, angle (trill_ne) - 90);
+       penpos12 (trill_thin, angle (trill_ne yscaled -1) + 90);
+       penlabels (11, 12);
 
-       pickup pencircle scaled trill_thin;
+       pickup pencircle scaled trill_stemwidth;
 
-       fill z1l{-trill_ne}
-            .. z2l{trill_ne yscaled -1}
-            .. bot z2
-            .. rt z2
-            .. z2r{-trill_ne yscaled -1}
-            .. z1r{trill_ne}
+       fill z11l{-trill_ne}
+            .. z12l{trill_ne yscaled -1}
+            .. bot z12
+            .. rt z12
+            .. z12r{-trill_ne yscaled -1}
+            .. z11r{trill_ne}
             -- cycle;
 
        remember_pic := currentpicture;
 fet_endchar;
 
 
-fet_beginchar ("upmordent", "upmordent")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("upmordent", "upmordent");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      4/3 trill_height#, 4/3 trill_height#);
 
        currentpicture := remember_pic;
 
        clearxy;
-       pickup pencircle scaled trill_thin;
+
+       pickup pencircle scaled trill_stemwidth;
 
        top y1 = h;
        bot y2 = -d;
-       x1 = x2 ;
-       x2 = trill_width;
+       x1 = x2;
+       x2 = good.x (.5 trill_width);
 
-       draw_gridline (z2, z1, trill_thin);
+       draw_gridline (z2, z1, trill_stemwidth);
 
        labels (1, 2);
 fet_endchar;
 
 
-fet_beginchar ("pralldown", "pralldown")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("pralldown", "pralldown");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      trill_height#, trill_height#);
 
        currentpicture := remember_pic xscaled -1;
 fet_endchar;
 
 
-fet_beginchar ("downprall", "downprall")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("downprall", "downprall");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      trill_height#, trill_height#);
 
-       remember_pic := currentpicture;
-
-       draw_trillelement (-2 trill_width);
+       draw_trillelement (-trill_width);
        draw_trillelement (0);
-       draw_trillelement (trill_width);
+       draw_trillelement (trill_width);
 
-       clearxy;
-       z1 = (-b, 0) - trill_overlap * trill_ne;
-       z2 = z1 + (0, 2 trill_height);
+       z11 = z4 shifted (-trill_width, 0);
+       z12 = z11 + (0, 2 trill_height);
 
-       penpos1 (trill_thin, angle (trill_ne xscaled -1) - 90);
-       penpos2 (trill_thin, angle (trill_ne) - 90);
-       penlabels (12);
+       penpos11 (trill_thin, angle (trill_ne xscaled -1) - 90);
+       penpos12 (trill_thin, angle (trill_ne) - 90);
+       penlabels (11, 12);
 
-       pickup pencircle scaled trill_thin;
+       pickup pencircle scaled trill_stemwidth;
 
-       fill z1l{trill_ne xscaled -1}
-            .. z2l{trill_ne}
-            .. top z2
-            .. rt z2
-            .. z2r{-trill_ne}
-            .. z1r{-trill_ne xscaled -1}
+       fill z11l{trill_ne xscaled -1}
+            .. z12l{trill_ne}
+            .. top z12
+            .. rt z12
+            .. z12r{-trill_ne}
+            .. z11r{-trill_ne xscaled -1}
             -- cycle;
 
        remember_pic := currentpicture;
 fet_endchar;
 
 
-fet_beginchar ("downmordent", "downmordent")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("downmordent", "downmordent");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      4/3 trill_height#, 4/3 trill_height#);
 
        currentpicture := remember_pic;
 
        clearxy;
-       pickup pencircle scaled trill_thin;
+
+       pickup pencircle scaled trill_stemwidth;
 
        top y1 = h;
        bot y2 = -d;
-       x1 = x2 ;
-       x2 = trill_width;
+       x1 = x2;
+       x2 = good.x (.5 trill_width);
 
-       draw_gridline (z2, z1, trill_thin);
+       draw_gridline (z2, z1, trill_stemwidth);
 
        labels (1, 2);
 fet_endchar;
 
 
-fet_beginchar ("prallup", "prallup")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("prallup", "prallup");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      trill_height#, trill_height#);
 
        currentpicture := remember_pic xscaled -1;
 fet_endchar;
 
 
-fet_beginchar ("lineprall", "lineprall")
-       set_char_box (3 trill_width#, 3 trill_width#,
+fet_beginchar ("lineprall", "lineprall");
+       set_char_box (1.5 trill_width#, 1.5 trill_width#,
                      trill_height#, 4 trill_height#);
 
-       remember_pic := currentpicture;
+       draw_trillelement (-trill_width);
 
-       draw_trillelement (-2 trill_width);
-       draw_trillelement (0);
-       draw_trillelement (2 trill_width);
+       labels (1, 2, 3, 3', 4, 5, 5');
 
-       clearxy;
-       z1 = (-b, 0) - trill_overlap * trill_ne ;
-       z2 = z1 + (0, h);
+       pickup pencircle scaled trill_stemwidth;
 
-       labels (1, 2);
+       lft x10 = x4 - .5 trill_thin - trill_width;
+       y10 = y4;
+       z11 = z10 + (0, h);
+
+       labels (10, 11);
 
-       draw_gridline (z1, z2, trill_thin);
+       draw_gridline (z10, z11, trill_stemwidth);
+
+       draw_trillelement (0);
+       draw_trillelement (trill_width);
 fet_endchar;
index 4c656d8e59209db4f06e924307bef7005c2e6f26..2124fd460f24eb5ac6cd0af3ca8c1ad37cec86d6 100644 (file)
@@ -2,17 +2,17 @@
 % test stuff.
 % in a separate file to avoid tainting non-test font files for testing.
 %
-%
 
+input feta-eindelijk;
+input feta-toevallig;
+input feta-puntje;
 input feta-bolletjes;  
-%input feta-banier;
-%input feta-slag;
-%input feta-eindelijk;
-%input feta-klef;
-%      input feta-toevallig;
-%      input feta-schrift;
+input feta-schrift;
+input feta-banier;
+%      input feta-slag;
+input feta-klef;
 %      input feta-haak;
-%      input feta-timesig;
-%      input feta-pendaal;
-%      input feta-accordion;
+input feta-timesig;
+input feta-pendaal;
+input feta-accordion;
 %      input feta-solfa;
index 26f177075905f8b7af3e36043d2d6dce89913c21..33bcccccba719144af724173e1013862fc85ea1e 100644 (file)
@@ -24,38 +24,42 @@ fet_begingroup ("timesig");
 def draw_C =
        save hair, bulb_rad, left_fatness;
        save left_width, right_width;
-       save width;
+       save width, lower_offset;
 
        width# := 1.8 staff_space# - stafflinethickness#;
-       define_pixels (width);
 
-       left_width# := 1.0 staff_space#;
-       right_width# := 0.8 staff_space#;
-       define_pixels (left_width, right_width);
+       left_width := 1.0 staff_space;
+       right_width := 0.8 staff_space;
 
-       hair# := stafflinethickness#;
-       bulb_rad# := 0.4 staff_space#;
-       define_pixels (hair, bulb_rad);
-       left_fatness = 0.55;
+       hair := stafflinethickness;
 
-       x1r - x3r = width;
-       x3r = 0.0;
-       y1r = .45 staff_space;
-       y2 = -y4 = staff_space;
+       bulb_rad := 0.40 staff_space - .6 stafflinethickness;
+       left_fatness := 0.55 * staff_space;
+       lower_offset := 0.3 stafflinethickness;
+
+       set_char_box (0, width#, staff_space#, staff_space#);
+
+       d := d - feta_shift;
+
+       x1r = w;
+       x3r = 0;
+       y1r = .45 h;
+       y2r = h + vround (.5 stafflinethickness_rounded);
+       y4r = -d - vround (.5 stafflinethickness_rounded);
        x2 = x4;
-       x2 = x3r + staff_space;
-       y3r = 0;
+       x2 = x3r + h;
+       y3r = .5 (h - d);
 
-       x5r = x1r + 0.3 stafflinethickness;
-       y5r = -0.37 staff_space;
+       x5r = x1r + lower_offset;
+       y5r = -0.37 h;
 
        penpos1 (hair, 10);
-       penpos2 (stafflinethickness, 90);
-       penpos3 (left_fatness * staff_space, 180);
-       penpos4 (stafflinethickness, -90);
+       penpos2 (stafflinethickness_rounded, 90);
+       penpos3 (left_fatness, 180);
+       penpos4 (stafflinethickness_rounded, -90);
        penpos5 (hair, -13);
 
-       draw_bulb (-1, z1l,  z1r, bulb_rad, .8);
+       draw_bulb (-1, z1l, z1r, bulb_rad, .8);
 
        save s;
        s := 0.735;
@@ -73,31 +77,32 @@ def draw_C =
             .. {dir (-80)}z1r
             -- cycle;
 
-       set_char_box (0, width#, staff_space#, staff_space#);
-
        penlabels (1, 2, 3, 4, 5);
+
+       draw_staff (-2, 2, 0);
 enddef;
 
 
-fet_beginchar ("4/4 meter", "C44")
+fet_beginchar ("4/4 meter", "C44");
        draw_C;
 fet_endchar;
 
 
-fet_beginchar ("2/2 meter", "C22")
-       save excentricity, stemlen, thick;
-       pair excentricity;
+fet_beginchar ("2/2 meter", "C22");
+       save excentricity, top_stemlen, bottom_stemlen, thick, left_pos;
 
        draw_C;
 
-       xpart excentricity = x2 - 1.25 stafflinethickness;
-       ypart excentricity = 0;
+       excentricity = -1.75 stafflinethickness - 0.025 staff_space;
+       top_stemlen# = bottom_stemlen# = 1.4 staff_space#;
+       thick# = stafflinethickness# + 0.05 staff_space#;
+       define_whole_pixels (top_stemlen, bottom_stemlen);
+       define_whole_blacker_pixels (thick);
 
-       stemlen = 1.4 staff_space;
-       thick = stafflinethickness / 2 + 0.025 staff_space;
+       bottom_stemlen := bottom_stemlen - feta_shift;
 
-       draw_block ((-thick, -stemlen) + excentricity,
-                   (thick, stemlen) + excentricity);
+       draw_block ((x2 + excentricity, -bottom_stemlen),
+                   (x2 + excentricity + thick, top_stemlen));
 fet_endchar;
 
 fet_endgroup ("timesig");
index 99d5d0b5efa397fbe7411549be3e0cc18aba1ad6..de5f013ecdc153f2e9beb2f3789328c0eaaf178f 100644 (file)
 % Accidentals from various sources, notably
 %
 %   Baerenreiter edition of Schuberts `Auf dem Strom' (sharp, natural)
-%   F Hofmeister edition of Muellers `Etueden fuer Horn'  (double sharp, flat)
+%   F Hofmeister edition of Muellers `Etueden fuer Horn' (double sharp, flat)
 %
 
 
-%tracingall;
-%proofing := 2;
-%\tracingequations:= tracingonline := 1;
-
 fet_begingroup ("accidentals");
 
+
+save remember_pic;
+picture remember_pic;
+
+
 %
 % The beams of most sharps have horizontal endings (as if drawn with
 % a square pen).  [Wanske] does not mention this, so we'll just ignore
 % this fact.
 %
 
-def draw_meta_sharp (expr width) =
-       save interbeam, interstem;
+def draw_meta_sharp (expr width, offset) =
        save beamheight, beamwidth, beamslope;
-       save spanheight, spanwidth;
-       save stemwidth;
 
-       save center;
-       pair center;
-
-       interbeam := 1.05 staff_space;
-       beamheight := 0.3 staff_space + stafflinethickness;
        beamwidth := width;
-       stemwidth := stafflinethickness + .05 staff_space;
-       roundness := 2 blot_diameter;
-
-       center := (.5 w, 0);
-
-       roundness + 2 spanwidth = beamwidth;
-       roundness + 2 spanheight = beamheight;
-
-       z2 - z1 = (beamwidth - roundness, beamheight);
-       z1 + z2 = 2 * center;
-       beamslope = (y2 - y1) / (x2 - x1);
-
-       pair hspan, vspan;
-       hspan = (spanwidth, beamslope * spanwidth);
-       vspan = (0, spanheight);
-
-       pickup pencircle scaled roundness;
-       path beam;
-       beam := (rt (hspan + vspan)
-                .. top (hspan + vspan)
-                --- top (-hspan + vspan)
-                .. lft (-hspan + vspan)
-                --- lft (-hspan - vspan)
-                .. bot (-hspan - vspan)
-                --- bot (hspan - vspan)
-                .. rt (hspan - vspan)
-                --- cycle) shifted center;
-       fill (beam shifted (0, -interbeam / 2));
 
-       pickup pencircle scaled stemwidth;
-       x3 = x4 = xpart center;
+       beamheight# := 0.3 staff_space# + stafflinethickness#;
+       define_whole_vertical_blacker_pixels (beamheight);
+
+       clearxy;
+
+       beamslope = beamheight / beamwidth;
+
+       pickup pencircle scaled 2 blot_diameter;
+
+       rt x2 - lft x1 = beamwidth;
+       y2 - y1 = beamheight;
+       .5 [z1, z3] = (.5 w, offset);
+       x3 = x2;
+       top y2 - bot y3 = beamheight;
+       x4 = x1;
+       top y1 - bot y4 = beamheight;
+
+       fill lft z1{up}
+            .. top z1{z2 - z1}
+            -- top z2{z2 - z1}
+            .. rt z2{down}
+            -- rt z3{down}
+            .. bot z3{z4 - z3}
+            -- bot z4{z4 - z3}
+            .. lft z4{up}
+            -- cycle;
+
+       labels (1, 2, 3, 4);
 enddef;
 
 
-fet_beginchar ("Sharp" , "2");
+fet_beginchar ("Sharp", "2");
+       save stem, stemx, stemwidth;
+       save outer_space, interbeam;
+
+       stemwidth# := stafflinethickness# + .05 staff_space#;
+       define_whole_blacker_pixels (stemwidth);
+
+       interbeam := 1.05 staff_space_rounded;
+
        set_char_box (0, 1.1 staff_space#,
                      1.5 staff_space#, 1.5 staff_space#);
-       draw_meta_sharp (w);
 
-       save stemx;
-       stemx := 7 / 32 * w;
+       stem := 7 / 16 * w;
+       stemx := hround stem;
+       outer_space := hround ((w - stemx - stemwidth) / 2);
 
-       (bot y3) + -stemx * beamslope = -1.5 staff_space + ypart center;
-       (top y4) + stemx * beamslope = 1.5 staff_space + ypart center;
+       w := 2 outer_space + stemx + stemwidth;
+       d := d - feta_space_shift;
 
-       labels (1, 2, 3, 4);
+       draw_meta_sharp (w, -.5 interbeam);
+       draw_meta_sharp (w, -.5 interbeam + vround interbeam);
 
-       draw_gridline (z3 - (stemx, stemx * beamslope),
-                      z4 - (stemx, stemx * beamslope),
-                      stemwidth);
-       addto currentpicture also currentpicture rotated 180 shifted (w, 0);
+       pickup pencircle scaled stemwidth;
+
+       lft x5 = lft x6 = outer_space;
+       lft x7 = lft x8 = outer_space + stemx;
+       bot y5 = -d;
+       top y6 = vround (1.5 staff_space - stem * beamslope);
+       bot y7 = -top y6 + feta_space_shift;
+       top y8 = h;
+
+       labels (5, 6, 7, 8);    
+
+       draw_gridline (z5, z6, stemwidth);
+       draw_gridline (z7, z8, stemwidth);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("1/2 Sharp" , "1");
+if test > 0:
+       fet_beginchar ("Sharp", "2");
+
+               set_char_box (0, 1.1 staff_space#,
+                             1.5 staff_space#, 1.5 staff_space#);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("1/2 Sharp", "1");
+       save stem, stemwidth;
+       save outer_space, interbeam;
+
+       stemwidth# := stafflinethickness# + .05 staff_space#;
+       define_whole_blacker_pixels (stemwidth);
+
+       interbeam := 1.05 staff_space_rounded;
+
        set_char_box (0, 0.7 staff_space#,
                      1.5 staff_space#, 1.5 staff_space#);
 
-       draw_meta_sharp (w);
-       stemx := 7 / 32 * w;
+       stem := 7 / 16 * w;
+       outer_space := hround ((w - stemwidth) / 2);
 
-       (bot y3) + -stemx * beamslope = -1.5 staff_space + ypart center;
-       (top y4) + stemx * beamslope = 1.5 staff_space + ypart center;
+       w := 2 outer_space + stemwidth;
+       d := d - feta_space_shift;
 
-       labels (1, 2, 3, 4);
+       draw_meta_sharp (w, -.5 interbeam);
+       draw_meta_sharp (w, -.5 interbeam + vround interbeam);
+
+       pickup pencircle scaled stemwidth;
 
-       draw_gridline (z3, z4, stemwidth);
-       addto currentpicture also currentpicture rotated 180 shifted (w, 0);
+       lft x5 = lft x6 = outer_space;
+       top y6 = vround (1.5 staff_space - .5 stem);
+       bot y5 = -top y6 + feta_space_shift;
+
+       labels (5, 6);
+
+       draw_gridline (z5, z6, stemwidth);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
+if test > 0:
+       fet_beginchar ("1/2 Sharp", "1");
+
+               set_char_box (0, 0.7 staff_space#,
+                             1.5 staff_space#, 1.5 staff_space#);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
 fet_beginchar ("3/4 Sharp", "3");
+       save stem, stemx, stemwidth;
+       save outer_space, interbeam;
+
+       stemwidth# := stafflinethickness# + .05 staff_space#;
+       define_whole_blacker_pixels (stemwidth);
+
+       interbeam := 1.05 staff_space_rounded;
+
        set_char_box (0, 1.6 staff_space#,
                      1.5 staff_space#, 1.5 staff_space#);
 
-       draw_meta_sharp (w);
-       stemx := 9 / 32 * w;
+       stem := 9 / 32 * w;
+       stemx := hround stem;
+       outer_space := hround ((w - 2 stemx - stemwidth) / 2);
 
-       (bot y3) + -stemx * beamslope = -1.5 staff_space + ypart center;
-       (top y4) + stemx * beamslope = 1.5 staff_space + ypart center;
+       w := 2 outer_space + 2 stemx + stemwidth;
+       d := d - feta_space_shift;
 
-       labels (1, 2, 3, 4);
+       draw_meta_sharp (w, -.5 interbeam);
+       draw_meta_sharp (w, -.5 interbeam + vround interbeam);
+
+       pickup pencircle scaled stemwidth;
+
+       lft x5 = lft x6 = outer_space;
+       lft x7 = lft x8 = outer_space + stemx;
+       lft x9 = lft x10 = outer_space + 2 stemx;
+       bot y5 = -d;
+       top y6 = vround (1.5 staff_space - 2 stem * beamslope);
+       bot y9 = -top y6 + feta_space_shift;
+       top y10 = h;
+       y7 = .5 [y5, y9];
+       y8 = .5 [y6, y10];
+
+       labels (5, 6, 7, 8, 9, 10);
 
-       draw_gridline (z3 - (stemx, stemx * beamslope),
-                      z4 - (stemx, stemx * beamslope),
-                      stemwidth);
-       draw_gridline (z3, z4, stemwidth);
-       addto currentpicture also currentpicture rotated 180 shifted (w,0);
+       draw_gridline (z5, z6, stemwidth);
+       draw_gridline (z7, z8, stemwidth);
+       draw_gridline (z9, z10, stemwidth);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
+if test > 0:
+       fet_beginchar ("3/4 Sharp", "3");
+
+               set_char_box (0, 1.6 staff_space#,
+                             1.5 staff_space#, 1.5 staff_space#);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
 %
 % The stems of the natural are brushed (at least, in Barenreiter SCS)
 %
 
-fet_beginchar ("Natural", "0")
-       save height, xcenter;
+fet_beginchar ("Natural", "0");
+       save beam_shift;
        save interbeam, interstem;
        save beamheight, beamwidth;
        save stemwidth, top_stem_thick;
 
        beamheight# = 0.35 staff_space# + .5 stafflinethickness#;
-       height# = 1.5 staff_space#;
-
-       set_char_box (0, 2/3 staff_space#, height#, height#);
-
-       define_pixels (height);
-       define_blacker_pixels (beamheight);
+       top_stem_thick# = stafflinethickness# + .09 staff_space#;
+       stemwidth# = 0.08 staff_space# + .5 stafflinethickness#;
+       define_whole_vertical_blacker_pixels (beamheight);
+       define_whole_blacker_pixels (top_stem_thick, stemwidth);
 
-       top_stem_thick = round (stafflinethickness + .09 staff_space) + 0.4;
-       stemwidth = 0.08 staff_space + .5 stafflinethickness;
+       set_char_box (0, 2/3 staff_space#,
+                     1.5 staff_space#, 1.5 staff_space#);
 
        interstem + stemwidth = w;
 
        z2 - z1 = (interstem, slope * interstem);
-       xpart .5 [z2, z1] = xcenter;
-       xcenter = w / 2;
+       xpart .5 [z2, z1] = w / 2;
+
+       d := d - feta_space_shift;
 
        pickup penrazor scaled beamheight rotated 90;
-       top y2 = staff_space - 3/2 stafflinethickness;
+       top y2 = vround (staff_space - 3/2 stafflinethickness);
        slope = stafflinethickness / interstem;
 
+       x1 := round x1;
+       y1 := round y1;
+       x2 := round x2;
+       y2 := round y2;
+
+       x1' = x1;
+       bot y1' = -d + (h - top y2);
+       z1 - z1' = z2 - z2';
+
        draw z1
             .. z2;
-       draw (xpart z1, -y2)
-            .. (xpart z2, -y1);
+       draw z1'
+            .. z2';
 
        beamtop = top y2;
 
        pickup pencircle scaled stemwidth;
-       x3 := round (xpart z1);
-       x4 := round (xpart z2);
+       x3 = x1;
+       x4 = x2;
 
        penpos3 (top_stem_thick, 0);
        penpos5 (top_stem_thick, 0);
        penpos4 (stemwidth, 0);
        penpos6 (stemwidth, 0);
 
-       y3 = height;
+       y3 = h;
        top y4 = beamtop;
-
        x5 = x4;
        x6 = x3;
-       bot y6 = -beamtop;
-       y5 = - height;
+       y6 = -y4 + feta_space_shift;
+       y5 = -d;
 
        fill simple_serif (z3l, z3r, -30)
             -- z6r
@@ -197,68 +302,86 @@ fet_beginchar ("Natural", "0")
             -- cycle;
 
        penlabels (3, 4, 5, 6);
-       labels (1, 2);
+       labels (1, 1', 2, 2');
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
+if test > 0:
+       fet_beginchar ("Natural", "0");
+               set_char_box (0, 2/3 staff_space#,
+                             1.5 staff_space#, 1.5 staff_space#);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
 %
 % Dedicated to my mom.    (3/10/97)
 %
 % Mamma, ik hou van je; kom je alsjeblieft terug?
 %    -- HW
 %
-
+%
 % TODO: remove crook_fatness
 % TODO: document, simplify!
 %
+
 def draw_meta_flat (expr xcenter, w, crook_fatness) =
-       clearxy;
        save crook_thinness;
-       save bottom_overshoot;
+       save bottom_overshoot, bot_crook_dir;
        save top_stem_thick, bottom_stem_thick, hair, smaller_hole;
        save top_crook_thinness;
        save zwiep;
        save center;
-       pair center;
+       pair center, bot_crook_dir;
        save clearing;
 
-       center = (xcenter, 0);
-
-% the shouldn't reach to the top staff line.
-%% TODO: should take from height.
-       clearing = 1.2 stafflinethickness;
+       clearxy;
 
-%
-%  TODO: parameterize this
-%
+       % the stem shouldn't reach the top staff line.
+       %% TODO: should take from height.
+       %
+       % TODO: parameterize this
+       %
        if w >= 0.75 staff_space:
                smaller_hole = 0.35 stafflinethickness;
        else:
-               smaller_hole = 0.0 stafflinethickness;
+               smaller_hole = 0;
        fi
+       clearing = 1.7 stafflinethickness;
        crook_thinness = .7 stafflinethickness + .06 staff_space;
        top_crook_thinness = 1 stafflinethickness + .065 staff_space;
+       bottom_overshoot = stafflinethickness;
 
-       % this is a somewhat heuristic.  We should probably make it
-       % straight for low resolution (300 dpi and less).
-       top_stem_thick =
-         round (0.1 staff_space + 1.2 stafflinethickness) + 0.74;
+       bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#;
+       top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#;
+       define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick);
 
-       bottom_overshoot = stafflinethickness;
-       bottom_stem_thick = 0.06 staff_space + 0.6 stafflinethickness;
+       if odd (top_stem_thick - bottom_stem_thick):
+               top_stem_thick := top_stem_thick - 1;
+       fi;
 
-       z1 = (0, 2 staff_space)
-            + center
-            - (0, stafflinethickness / 2 + clearing);
-       z2 = (0, -1/2 staff_space - stafflinethickness / 2)
-            + center;
+       center = (xcenter, 0);
+
+       x1l = hround (xcenter - .5 top_stem_thick);
+       y1 = vround (2 staff_space - clearing);
+       x2l = hround (xcenter - .5 bottom_stem_thick);
+       y2 = -.5 staff_space - .5 stafflinethickness;
 
        penpos1 (top_stem_thick, 0);
        penpos2 (bottom_stem_thick, 0);
 
-       y3l = (staff_space - stafflinethickness) / 2 + ypart center;
+       y3l = vfloor ((staff_space - stafflinethickness) / 2);
        z3l = whatever [z2r, z1r];
        z3r = .3 [z2r, z1r] + (smaller_hole, 0);
+       x3r := hceiling x3r;
 
        % we insert z3l to get better conversion with mf2pt1
        fill simple_serif (z1r, z1l, 30)
@@ -268,36 +391,33 @@ def draw_meta_flat (expr xcenter, w, crook_fatness) =
             -- cycle;
 
        z10 = whatever [z2r, z1r] + (smaller_hole, 0);
-       z11 = center
-             + (bottom_overshoot / 3,
-                -staff_space / 2 - stafflinethickness / 2)
-             - (0, bottom_overshoot);
+       y10 = -1/10 staff_space;
+       x10 := hceiling x10;
+
+       x11 = xcenter + bottom_overshoot / 3;
+       y11 = -vround (.5 (staff_space + stafflinethickness)
+                      + bottom_overshoot);
 
        penpos4 (whatever, 53);
 
        y4l - y4r = top_crook_thinness;
-       y5r = .15 staff_space + ypart center;
-       x5l = w + xpart center;
-       y4 = ypart center + staff_space / 2;
+       y5r = .15 staff_space;
+       x5l = hround (w + xcenter);
+       y4 = staff_space / 2;
        x4r = .45 [x5r, x3r];
+       y4l := vround y4l;
 
        penpos5 (crook_fatness, -175);
 
-       save bot_crook_dir;
-       pair bot_crook_dir;
        bot_crook_dir = unitvector ((x5l, 0) - z11);
        z8 = z11 + whatever * bot_crook_dir;
-       y8 = -staff_space / 2 + 0.0 * stafflinethickness;
+       y8 = -staff_space / 2;
 
        z7 = z8
             + whatever * bot_crook_dir
             + crook_thinness * (bot_crook_dir rotated 90);
        x7 = .1 [x3r, x8];
 
-       y10 = -1/10 staff_space;
-%      draw_staff (-2, 2, 0.5);
-%      draw_staff (-2, 2, 0.0);
-
        unfill z3r{z3r - z10}
               .. z4r{right}
               .. z5r{down}
@@ -320,16 +440,32 @@ enddef;
 % unfortunately, 600dpi is not enough to show the brush of the stem.
 %
 
-fet_beginchar ("Flat", "-2")
+fet_beginchar ("Flat", "-2");
        set_char_box (1.2 stafflinethickness#, .8 staff_space#,
                      0.6 staff_space#, 1.9 staff_space#);
 
        draw_meta_flat (0, w, 0.31 staff_space);
        penlabels (range 0 thru 11);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Semi flat", "-1")
+if test > 0:
+       fet_beginchar ("Flat", "-2");
+               set_char_box (1.2 stafflinethickness#, .8 staff_space#,
+                             0.6 staff_space#, 1.9 staff_space#);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Semi flat", "-1");
        set_char_box (1.2 stafflinethickness#, .8 staff_space#,
                      0.6 staff_space#, 1.9 staff_space#);
 
@@ -338,14 +474,15 @@ fet_beginchar ("Semi flat", "-1")
 fet_endchar;
 
 
-fet_beginchar ("Double Flat", "-4")
+fet_beginchar ("Double Flat", "-4");
        save left_wid, overlap, right_wid;
+
        left_wid = .7;
        right_wid = .8;
        overlap = .05;
 
        set_char_box (1.2 stafflinethickness#,
-                     (left_wid + right_wid -overlap) * staff_space#,
+                     (left_wid + right_wid - overlap) * staff_space#,
                      .6 staff_space#, 1.9 staff_space#);
        draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space);
        draw_meta_flat (round ((left_wid - overlap) * staff_space),
@@ -353,8 +490,9 @@ fet_beginchar ("Double Flat", "-4")
 fet_endchar;
 
 
-fet_beginchar ("3/4 Flat", "-3")
+fet_beginchar ("3/4 Flat", "-3");
        save left_wid, overlap, right_wid;
+
        left_wid = .7;
        right_wid = .8;
        overlap = .05;
@@ -370,33 +508,61 @@ fet_beginchar ("3/4 Flat", "-3")
        %% or make the 1st flat smaller?
        %% or reverse it?
        pickup pencircle scaled 2 stafflinethickness;
-       z12 = (-.25 w - b, .55 staff_space);
-       z13 = (.75 w, 1.45 staff_space);
+
+       z12 = round (-.25 w - b, .55 staff_space) + feta_offset;
+       z13 = round (.75 w, 1.45 staff_space) + feta_offset;
        penpos12 (2 stafflinethickness, angle (z13 - z12) - 90);
        penpos13 (2 stafflinethickness, angle (z13 - z12) - 90);
+
        z14 = z12 - stafflinethickness * unitvector (z13 - z12);
        z15 = z13 + stafflinethickness * unitvector (z13 - z12);
 
        fill z13r
             .. z15
             .. z13l
-            --- z12l
+            -- z12l
             .. z14
             .. z12 r
-            --- z13r
+            -- z13r
             .. cycle;
 
        penlabels (12, 13);
        labels (14, 15);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Double Sharp", "4")
-       set_char_box (0, staff_space#, .5 staff_space#, .5 staff_space#);
+if test > 0:
+       fet_beginchar ("3/4 Flat", "-3");
+               save left_wid, overlap, right_wid;
+
+               left_wid = .7;
+               right_wid = .8;
+               overlap = .05;
+
+               set_char_box (1.2 stafflinethickness#,
+                             (left_wid + right_wid - overlap) * staff_space#,
+                             .6 staff_space#, 1.9 staff_space#);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Double Sharp", "4");
        save klaverblad, klaversteel;
+       save pat;
+       path pat;
 
        klaversteel = 1/15 staff_space;
-       klaverblad = .40 staff_space - .5 stafflinethickness;
+       klaverblad = .4 staff_space - .5 stafflinethickness;
+
+       set_char_box (0, staff_space#, .5 staff_space#, .5 staff_space#);
 
        z1 = (klaversteel, 0);
        z2 = (w / 2 - klaverblad / 10, h - klaverblad);
@@ -404,42 +570,68 @@ fet_beginchar ("Double Sharp", "4")
        z4 = z2 reflectedabout ((0, 0), (1, 1));
        z5 = z1 reflectedabout ((0, 0), (1, 1));
 
-       % labels (1, 2, 3, 4, 5);
-
-       save pat;
-       path pat;
+       labels (1, 2, 3, 4, 5);
 
        pickup pencircle scaled blot_diameter;
+
+       x2 := hfloor (rt x2) - blot_diameter / 2;
+       x3 := hfloor (rt x3) - blot_diameter / 2;
+       y3 := vfloor (top y3) - blot_diameter / 2;
+       y4 := vfloor (top y4) - blot_diameter / 2;
+
        pat = (rt z1){dir45}
              .. {right}(bot z2)
              .. rt z2
-             --- rt z3
-             .. top z3
-             --- top z4
+             -- rt z3{z3 - z2}
+             .. top z3{z4 - z3}
+             -- top z4{z4 - z3}
              .. (lft z4){down}
              .. {dir 225}(top z5);
        pat := pat
-              & reverse pat xscaled (-1);
-       pat := pat
-              & reverse pat yscaled (-d / h)
-              & cycle;
-       fill pat;
+              -- reverse pat xscaled -1 shifted (-feta_eps, 0);
+
+       % assure symmetry -- it's more important to center the glyph on the
+       % staff line than centering it between staff lines, so we use
+       % feta_shift, not feta_space_shift.
+       h := h + feta_shift;
+
+       fill pat shifted (0, feta_shift)
+            -- reverse pat yscaled -1 shifted (0, -feta_eps)
+            -- cycle;
 
        % ugh
-       currentpicture := currentpicture shifted (w / 2, 0);
+       currentpicture := currentpicture shifted (hround (w / 2), 0);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
+if test > 0:
+       fet_beginchar ("Double Sharp", "4");
+               set_char_box (0, staff_space#,
+                             .5 staff_space#, .5 staff_space#);
+
+               currentpicture := remember_pic;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
 def draw_paren =
        save leftindent;
-       leftindent# := .2 staff_space#;
-       define_pixels (leftindent);
+
+       leftindent := .2 staff_space;
 
        set_char_box (0, .5 staff_space# + stafflinethickness#,
                      staff_space#, staff_space#);
 
+       d := d - feta_shift;
+
        z1 = (leftindent, h);
-       z2 = (w - stafflinethickness, 0);
+       z2 = (w - stafflinethickness, .5 (h - d));
        z3 = (leftindent, -d);
 
        penpos1 (stafflinethickness, 35);
@@ -455,15 +647,33 @@ def draw_paren =
 enddef;
 
 
-fet_beginchar ("Right Parenthesis", "rightparen")
+fet_beginchar ("Right Parenthesis", "rightparen");
        draw_paren;
        penlabels (1, 2, 3);
+
+       remember_pic := currentpicture;
+
+       draw_staff (-2, 2, 0);
 fet_endchar;
 
 
-fet_beginchar ("Left Parenthesis", "leftparen")
+if test > 0:
+       fet_beginchar ("Right Parenthesis", "rightparen");
+               draw_paren;
+               penlabels (1, 2, 3);
+
+               remember_pic := currentpicture;
+
+               draw_staff (-2, 2, 0.5);
+       fet_endchar;
+fi;
+
+
+fet_beginchar ("Left Parenthesis", "leftparen");
        draw_paren;
+
        currentpicture := currentpicture xscaled -1;
+
        set_char_box (charwd, charbp, chardp, charht);
 fet_endchar;