]> git.donarmstrong.com Git - lilypond.git/commitdiff
Add improved shape note support
authorCarl Sorensen <c_sorensen@byu.edu>
Tue, 6 Apr 2010 04:42:54 +0000 (22:42 -0600)
committerCarl Sorensen <c_sorensen@byu.edu>
Tue, 20 Apr 2010 00:09:10 +0000 (18:09 -0600)
Add Christian Harmony, Sacred Harp, and Southern Harmony styles

Add variable-thickness open note shapes to the shape note font

Change the starting character value for the Feta font to accomodate
  the extra characters.

Add new commands to base shape note scale degrees on the relative
  major.

Add regression tests for various note styles.

Update docs to reflect new settings.

Move noteheads to separate sub-font to allow space for shape note heads

24 files changed:
Documentation/included/font-table.ly
Documentation/notation/pitches.itely
input/regression/note-head-aiken.ly [new file with mode: 0644]
input/regression/note-head-sacred-harp.ly [new file with mode: 0644]
input/regression/note-head-shape-minor.ly [new file with mode: 0644]
input/regression/note-head-solfa.ly
input/regression/note-head-southern-harmony.ly [new file with mode: 0644]
ly/property-init.ly
mf/GNUmakefile
mf/bigcheese.pe.in
mf/feta-autometric.mf
mf/feta-generic.mf
mf/feta-noteheads-generic.mf [new file with mode: 0644]
mf/feta-noteheads-test-generic.mf [new file with mode: 0644]
mf/feta-noteheads.mf
mf/feta-noteheads11.mf [new file with mode: 0644]
mf/feta-noteheads13.mf [new file with mode: 0644]
mf/feta-noteheads14.mf [new file with mode: 0644]
mf/feta-noteheads16.mf [new file with mode: 0644]
mf/feta-noteheads18.mf [new file with mode: 0644]
mf/feta-noteheads20.mf [new file with mode: 0644]
mf/feta-noteheads23.mf [new file with mode: 0644]
mf/feta-noteheads26.mf [new file with mode: 0644]
mf/feta-test-generic.mf

index 3bdb80a6c82c29b6a762bc4b84f5f2184dc80bc5..3a5f6ebd8803ad665af836e7e3cad105ec380dc7 100644 (file)
@@ -63,7 +63,7 @@
 
   (define shape-note-noteheads
     (get-group glyph-list
-      "^noteheads.[dsu][012](do|re|mi|fa|sol|la|ti)$"))
+      "^noteheads.[dsu][012](do|re|mi|fa|sol|la|ti)(Thin|Mirror)*$"))
 
   (define clefs       (get-group glyph-list "^clefs\\."))
   (define timesig     (get-group glyph-list "^timesig\\."))
index 31af761a7e8f38a5950a697d58c9dba3a35803de..7e33d7a91c7eea8eb4c4f12589e3edf0a91317a9 100644 (file)
@@ -2681,33 +2681,65 @@ Internals Reference:
 @cindex shape notes
 @cindex Aiken shape note heads
 @cindex sacred harp note heads
+@cindex note heads, Southern Harmony
+@cindex Southern Harmony note heads
 
-@funindex \key
-@funindex key
 @funindex \aikenHeads
 @funindex aikenHeads
 @funindex \sacredHarpHeads
 @funindex sacredHarpHeads
+@funindex \southernHarmonyHeads
+@funindex southernHarmonyHeads
 
 In shape note head notation, the shape of the note head
 corresponds to the harmonic function of a note in the scale.  This
 notation was popular in nineteenth-century American song books.
-Shape note heads can be produced:
+Shape note heads can be produced in Sacred Harp, Southern Harmony,
+and Aiken (Christian Harmony) styles:
 
 @lilypond[verbatim,quote,relative=2]
 \aikenHeads
-c, d e f g a b c
+c, d e f g2 a b1 c \break
 \sacredHarpHeads
-c, d e f g a b c
+c,4 d e f g2 a b1 c \break
+\southernHarmonyHeads
+c,4 d e f g2 a b1 c \break
 @end lilypond
 
+@funindex \key
+@funindex key
+@funindex \aikenHeadsMinor
+@funindex aikenHeadsMinor
+@funindex \sacredHarpHeadsMinor
+@funindex sacredHarpHeadsMinor
+@funindex \southernHarmonyHeadsMinor
+@funindex southernHarmonyHeadsMinor
+
 Shapes are typeset according to the step in the scale, where the
 base of the scale is determined by the @code{\key} command.
+When when writing in a minor key, the scale step can be determined
+from the relative major:
+
+@lilypond[verbatim,quote,relative=2]
+\key a \minor
+\aikenHeads
+a b c d e2 f g1 a \break
+\aikenHeadsMinor
+a,4 b c d e2 f g1 a \break
+\sacredHarpHeadsMinor
+a,2 b c d \break
+\southernHarmonyHeadsMinor
+a2 b c d \break
+@end lilypond
 
 
 @predefined
 @code{\aikenHeads},
-@code{\sacredHarpHeads}.
+@code{\aikenHeadsMinor},
+@code{\sacredHarpHeads},
+@code{\sacredHarpHeadsMinor},
+@code{\southernHarmonyHeads},
+@code{\southernHarmonyHeadsMinor}.
 @endpredefined
 
 
diff --git a/input/regression/note-head-aiken.ly b/input/regression/note-head-aiken.ly
new file mode 100644 (file)
index 0000000..30134ff
--- /dev/null
@@ -0,0 +1,15 @@
+\header {
+
+  texidoc = "Notes can be set in the Aiken (Christian Harmony) style."
+
+}
+\version "2.12.0"
+
+\relative c' {
+  \key c \major
+  \aikenHeads
+  c1 d e f g a b c d e f g a b c
+  c,,2 d e f g a b c d e f g a b c
+  c,,4 d e f g a b c d e f g a b c
+}
+
diff --git a/input/regression/note-head-sacred-harp.ly b/input/regression/note-head-sacred-harp.ly
new file mode 100644 (file)
index 0000000..fdd2eb1
--- /dev/null
@@ -0,0 +1,15 @@
+\header {
+
+  texidoc = "Notes can be set in the Sacred Harp style."
+
+}
+\version "2.12.0"
+
+\relative c' {
+  \key c \major
+  \sacredHarpHeads
+  c1 d e f g a b c d e f g a b c
+  c,,2 d e f g a b c d e f g a b c
+  c,,4 d e f g a b c d e f g a b c
+}
+
diff --git a/input/regression/note-head-shape-minor.ly b/input/regression/note-head-shape-minor.ly
new file mode 100644 (file)
index 0000000..d7356d3
--- /dev/null
@@ -0,0 +1,18 @@
+\header {
+
+  texidoc = "Shape notes can be set to work properly in minor keys."
+
+}
+\version "2.12.0"
+
+\relative c' {
+  \key c \major
+  \sacredHarpHeads
+  c2^"C major" d | e f | g a | b c |
+  \key a \minor
+  \sacredHarpHeadsMinor
+  a2^"A minor" b | c d | e f | g a |
+  \sacredHarpHeads
+  c,,2^"A minor with major heads" d | e f | g a | b c |
+}
+
index b4d24ca852036dd0df8d9975ec63c8307043a5db..d6b163dfcb05e51f2689da6db2ae9e36c9ea26bf 100644 (file)
@@ -9,7 +9,7 @@ to the @code{tonic} property."
 
 fragment = {
   \key c \major
-  \set shapeNoteStyles = #'#(do re mi fa #f la ti)
+  \set shapeNoteStyles = #'#(do re mi fa sol la ti)
   c1 d e f g a b c d e f g a b c
   c,,2 d e f g a b c d e f g a b c
   c,,4 d e f g a b c d e f g a b c
diff --git a/input/regression/note-head-southern-harmony.ly b/input/regression/note-head-southern-harmony.ly
new file mode 100644 (file)
index 0000000..3e20a01
--- /dev/null
@@ -0,0 +1,15 @@
+\header {
+
+  texidoc = "Notes can be set in the Southern Harmony style."
+
+}
+\version "2.12.0"
+
+\relative c' {
+  \key c \major
+  \southernHarmonyHeads
+  c1 d e f g a b c d e f g a b c
+  c,,2 d e f g a b c d e f g a b c
+  c,,4 d e f g a b c d e f g a b c
+}
+
index 4238dd14e03d772758d1cce3aba263ef8746009a..0b1f2a2ea78fd52bce237d3765059cf09b555668 100644 (file)
@@ -342,8 +342,15 @@ predefinedFretboardsOn =
 
 %% shape note heads
 
-aikenHeads      = \set shapeNoteStyles = #'#(do re mi fa sol la ti)
+aikenHeads      = \set shapeNoteStyles = #'#(do re miMirror fa sol la ti)
+aikenHeadsMinor = \set shapeNoteStyles = #'#(la ti do re miMirror fa sol)
 sacredHarpHeads = \set shapeNoteStyles = #'#(fa sol la fa sol la mi)
+sacredHarpHeadsMinor = \set shapeNoteStyles = #'#(la mi fa sol la fa sol)
+southernHarmonyHeads = 
+  \set shapeNoteStyles = #'#(faThin sol laThin faThin sol laThin miThin)
+southernHarmonyHeadsMinor =
+  \set shapeNoteStyles = #'#(laThin miThin faThin sol laThin faThin sol)
+
 
 
 %% shifts
index 956c8fa47c7ef83a8cbc7614a41cc40a231c1625..329d673bfb92d237093749a95718c601f77f2451 100644 (file)
@@ -16,6 +16,7 @@ EXTRA_DIST_FILES += README mf2pt1.mp
 FETA_MF_FILES = $(call src-wildcard,feta[0-9]*.mf) \
                $(call src-wildcard,feta-braces-[a-z].mf) \
                $(call src-wildcard,feta-alphabet*[0-9].mf) \
+               $(call src-wildcard,feta-notehead*[0-9].mf) \
                $(call src-wildcard,parmesan[0-9]*.mf)
 
 STAFF_SIZES = 11 13 14 16 18 20 23 26
@@ -61,6 +62,7 @@ $(outdir)/emmentaler-brace.otf-gtable: $(BRACES:%=$(outdir)/feta-braces-%.otf-gt
 $(outdir)/emmentaler-%.otf \
 $(outdir)/emmentaler-%.svg: $(outdir)/emmentaler-%.pe \
                            $(outdir)/feta%.pfb \
+                           $(outdir)/feta-noteheads%.pfb \
                            $(outdir)/feta-alphabet%.pfb \
                            $(outdir)/parmesan%.pfb \
                            $(outdir)/feta%.otf-table \
@@ -77,32 +79,41 @@ $(outdir)/%.pfb: $(outdir)/%.log
 
 $(outdir)/%.otf-table: $(outdir)/%.lisp
        cat $< $(if $(findstring brace,$<),,$(subst feta,parmesan,$<)) \
+              $(if $(findstring brace,$<),,$(subst feta,feta-noteheads,$<)) \
               $(if $(findstring brace,$<),,$(subst feta,feta-alphabet,$<)) > $@
 
 
 ## ugh -- we want this to prevent failing -j2 compiles.
 $(outdir)/feta26.otf-table: $(outdir)/feta26.lisp \
+                           $(outdir)/feta-noteheads26.lisp \
                            $(outdir)/parmesan26.lisp \
                            $(outdir)/feta-alphabet26.lisp
 $(outdir)/feta23.otf-table: $(outdir)/feta23.lisp \
+                           $(outdir)/feta-noteheads23.lisp \
                            $(outdir)/parmesan23.lisp \
                            $(outdir)/feta-alphabet23.lisp
 $(outdir)/feta20.otf-table: $(outdir)/feta20.lisp \
+                           $(outdir)/feta-noteheads23.lisp \
                            $(outdir)/parmesan20.lisp \
                            $(outdir)/feta-alphabet20.lisp
 $(outdir)/feta18.otf-table: $(outdir)/feta18.lisp \
+                           $(outdir)/feta-noteheads18.lisp \
                            $(outdir)/parmesan18.lisp \
                            $(outdir)/feta-alphabet18.lisp
 $(outdir)/feta16.otf-table: $(outdir)/feta16.lisp \
+                           $(outdir)/feta-noteheads16.lisp \
                            $(outdir)/parmesan16.lisp \
                            $(outdir)/feta-alphabet16.lisp
 $(outdir)/feta14.otf-table: $(outdir)/feta14.lisp \
+                           $(outdir)/feta-noteheads14.lisp \
                            $(outdir)/parmesan14.lisp \
                            $(outdir)/feta-alphabet14.lisp
 $(outdir)/feta13.otf-table: $(outdir)/feta13.lisp \
+                           $(outdir)/feta-noteheads13.lisp \
                            $(outdir)/parmesan13.lisp \
                            $(outdir)/feta-alphabet13.lisp
 $(outdir)/feta11.otf-table: $(outdir)/feta11.lisp \
+                           $(outdir)/feta-noteheads11.lisp \
                            $(outdir)/parmesan11.lisp \
                            $(outdir)/feta-alphabet11.lisp
 
index 46b74f0abf3a912201fa34eaa06a544e6b92f0aa..e1d1843ba4d1d782257fe063c9757c928ee41eab 100644 (file)
@@ -10,6 +10,7 @@ New();
 SetFontNames("bigcheese20", "LilyPond", "LilyPond BigCheese 20", "20", "GNU GPL", "@TOPLEVEL_VERSION@");
 
 MergeFonts("feta20.pfa");
+MergeFonts("feta-noteheads20.pfa");
 MergeFonts("parmesan20.pfa");
 
 # load nummer/din after setting PUA.
index b77e4827dba6cdbc41b325735ebb15911713c6cd..c5c7e4836d7da07726b2341a1635090036840c85 100644 (file)
@@ -196,7 +196,7 @@ enddef;
 
 
 %
-% we leave the ctrl characters alone.
+% we leave the ctrl characters alone
 %
 code := 32;
 
index 5006b1f99d20006d3d2dcd24e5b6699221d3b87d..3472715e1639947541e33e846f72efd8b72f2b6e 100644 (file)
@@ -2,7 +2,7 @@
 % This file is part of LilyPond, the GNU music typesetter.
 %
 % Copyright (C) 1997--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
-% 
+%
 %
 % LilyPond is free software: you can redistribute it and/or modify
 % it under the terms of the GNU General Public License as published by
@@ -38,12 +38,11 @@ black_notehead_width# := 1.0 staff_space#;
 
 fet_beginfont ("feta", design_size, "fetaMusic");
 
-if test = 0: 
+if test = 0:
        input feta-rests;
        input feta-accidentals;
        input feta-arrowheads;
        input feta-dots;
-       input feta-noteheads;
        input feta-scripts;
        input feta-flags;
        input feta-clefs;
diff --git a/mf/feta-noteheads-generic.mf b/mf/feta-noteheads-generic.mf
new file mode 100644 (file)
index 0000000..89de7d0
--- /dev/null
@@ -0,0 +1,56 @@
+% Feta (not the Font-En-Tja) music font --  generic stuff: include lots of files, but don't
+% This file is part of LilyPond, the GNU music typesetter.
+%
+% Copyright (C) 1997--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
+%
+%
+% LilyPond is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% LilyPond is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
+
+
+if test = -1:
+       mode := smoke;
+fi
+
+staffsize# := design_size * pt#;
+
+mode_setup;
+
+input feta-macros;
+
+input feta-params;
+
+font_x_height staff_space#;
+
+%% this is a fallback so we can run the font without
+%%    including feta-noteheads.
+black_notehead_width# := 1.0 staff_space#;
+
+
+fet_beginfont ("feta", design_size, "fetaMusic");
+
+if test = 0:
+       input feta-noteheads;
+else:
+       input feta-noteheads-test-generic.mf;
+fi
+
+autometric_parameter ("staffsize", staffsize#);
+autometric_parameter ("stafflinethickness", stafflinethickness#);
+autometric_parameter ("staff_space", staff_space#);
+autometric_parameter ("linethickness", linethickness#);
+autometric_parameter ("black_notehead_width", black_notehead_width#);
+autometric_parameter ("ledgerlinethickness", ledgerlinethickness#);
+autometric_parameter ("blot_diameter", blot_diameter#);
+
+fet_endfont;
diff --git a/mf/feta-noteheads-test-generic.mf b/mf/feta-noteheads-test-generic.mf
new file mode 100644 (file)
index 0000000..7baeb9b
--- /dev/null
@@ -0,0 +1,6 @@
+%
+% test stuff.
+% in a separate file to avoid tainting non-test font files for testing.
+%
+
+input feta-noteheads;
index c413eac33e7635d7e1b7a43dcb9495f120f0c54c..8b7068ed1fb980e957268f48e0f02670f487b88a 100644 (file)
 %
 % LilyPond is distributed in the hope that it will be useful,
 % but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 % GNU General Public License for more details.
 %
 % You should have received a copy of the GNU General Public License
-% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+% along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
 
 test_outlines := 0;
 
@@ -1004,7 +1004,7 @@ fi;
 %
 
 save solfa_pen_thick;
-solfa_pen_thick# = 1.75 stafflinethickness#;
+solfa_pen_thick# = 1.3 stafflinethickness#;
 define_blacker_pixels (solfa_pen_thick);
 
 
@@ -1015,17 +1015,25 @@ solfa_whole_width := 1.0;
 solfa_half_width := 1.0;
 solfa_quarter_width := 1.0;
 
-def draw_do_head (expr width_factor, dir) =
+def draw_do_head (expr width_factor, dir, thickness_factor) =
        save p_in, p_out;
-       save left_dist, right_dist;
+       save left_dist, right_dist, bottom_dist;
        path p_in, p_out;
-       pair left_dist, right_dist;
+       pair left_dist, right_dist, bottom_dist;
 
        set_char_box (0, width_factor * solfa_base_notewidth#,
                      0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
 
        pickup pencircle scaled solfa_pen_thick;
 
+
+       bottom_thick_factor := thickness_factor;
+       % no different thickness for left side if we want uniform thickness
+       left_thick_factor := if thickness_factor = 1 :
+                               1;
+                            else :
+                               0.7 * thickness_factor;
+                            fi
        bot y1 = -d;
        y1 = y2;
        lft x1 = 0;
@@ -1035,14 +1043,25 @@ def draw_do_head (expr width_factor, dir) =
 
        left_dist = (unitvector (z3 - z1) rotated 90) * 0.5 solfa_pen_thick;
        right_dist = (unitvector (z2 - z3) rotated 90) * 0.5 solfa_pen_thick;
+       bottom_dist = (0,1) * 0.5 solfa_pen_thick;
 
-       p_in := (((z1 - left_dist) -- (z3 - left_dist)) intersectionpoint
-                 (top z1 -- top z2))
-               -- ((top z1 -- top z2) intersectionpoint
-                   ((z2 - right_dist) -- (z3 - right_dist)))
-               -- (((z2 - right_dist) -- (z3 - right_dist)) intersectionpoint
-                   ((z1 - left_dist) -- (z3 - left_dist)))
-               -- cycle;
+       save pa, pb, pc;
+       path pa, pb, pc;
+       save point_a, point_b, point_c;
+       pair point_a, point_b, point_c;
+
+       pa := (z1 - left_thick_factor * left_dist) --
+             (z3 - left_thick_factor * left_dist);
+       pb := (z1 + bottom_thick_factor * bottom_dist) --
+             (z2 + bottom_thick_factor * bottom_dist);
+       pc := (z2 - right_dist) -- (z3 - right_dist);
+
+
+       point_a := pa intersectionpoint pb;
+       point_b := pb intersectionpoint pc;
+       point_c := pc intersectionpoint pa;
+
+       p_in := point_a -- point_b -- point_c -- cycle;
 
        p_out := bot z1
                 -- bot z2{right}
@@ -1055,7 +1074,6 @@ def draw_do_head (expr width_factor, dir) =
                 .. lft z1{down}
                 .. {right}cycle;
 
-
        labels (1, 2, 3);
 
        charwx := charwd;
@@ -1067,47 +1085,86 @@ enddef;
 
 
 fet_beginchar ("Whole dohead", "s0do");
-       draw_do_head (solfa_whole_width, 1);
+       draw_do_head (solfa_whole_width, 1, 3.25);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Half dohead", "d1do");
-       draw_do_head (solfa_half_width, -1);
+       draw_do_head (solfa_half_width, -1, 3.25);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Half dohead", "u1do");
-       draw_do_head (solfa_half_width, 1);
+       draw_do_head (solfa_half_width, 1, 3.25);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Quart dohead", "d2do");
-       draw_do_head (solfa_quarter_width, -1);
+       draw_do_head (solfa_quarter_width, -1, 3.25);
        fill p_out;
 fet_endchar;
 
 
 fet_beginchar ("Quart dohead", "u2do");
-       draw_do_head (solfa_quarter_width, 1);
+       draw_do_head (solfa_quarter_width, 1, 3.25);
+       fill p_out;
+fet_endchar;
+
+
+
+fet_beginchar ("Whole thin dohead", "s0doThin");
+       draw_do_head (solfa_whole_width, 1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Half thin dohead", "d1doThin");
+       draw_do_head (solfa_half_width, -1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Half thin dohead", "u1doThin");
+       draw_do_head (solfa_half_width, 1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Quart thin dohead", "d2doThin");
+       draw_do_head (solfa_quarter_width, -1, 1);
        fill p_out;
 fet_endchar;
 
 
+fet_beginchar ("Quart thin dohead", "u2doThin");
+       draw_do_head (solfa_quarter_width, 1, 1);
+       fill p_out;
+fet_endchar;
+
+
+
 %
 % re - flat top, curved bottom:
-%                (0,h/2) {dir -90} .. (w/2,-h/2) .. {dir 90} (w,h/2) -- cycle;
+%               (0,h/2) {dir -90} .. (w/2,-h/2) .. {dir 90} (w,h/2) -- cycle;
 % (broader along the base and with more vertical sides for half and
 % whole notes)
+%
+% Note:  According to some shape-note singers, there should be no size
+%       differences for half and whole notes, contrary to the comment above
+%
 % stem attachment: h/2
 %
 
-def draw_re_head (expr width_factor, dir) =
+def draw_re_head (expr width_factor, dir, thickness_factor) =
        save p_in, p_out;
        path p_in, p_out;
 
@@ -1116,6 +1173,7 @@ def draw_re_head (expr width_factor, dir) =
 
        pickup pencircle scaled solfa_pen_thick;
 
+
        save curve_start;
        curve_start = 0.7;
        lft x1 = 0;
@@ -1131,11 +1189,11 @@ def draw_re_head (expr width_factor, dir) =
 
        labels (range 1 thru 5);
 
-       p_in := (z1 + 0.5 solfa_pen_thick * (1, -1))
+       p_in := (z1 + 0.5 solfa_pen_thick * (1, -1 * thickness_factor))
                -- rt z2{down}
-               .. top z3
+               .. ((top z3) + (0, thickness_factor * 0.5 solfa_pen_thick))
                .. lft z4{up}
-               -- (z5 + 0.5 solfa_pen_thick * (-1, -1))
+               -- (z5 + 0.5 solfa_pen_thick * (-1, -1 * thickness_factor))
                -- cycle;
 
        p_out := lft z1
@@ -1157,43 +1215,84 @@ enddef;
 
 
 fet_beginchar ("Whole rehead", "s0re");
-       draw_re_head (solfa_whole_width, 1);
+       draw_re_head (solfa_whole_width, 1, 2.5);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Half up rehead", "u1re");
-       draw_re_head (solfa_half_width, 1);
+       draw_re_head (solfa_half_width, 1, 2.5);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Half down rehead", "d1re");
-       draw_re_head (solfa_half_width, -1);
+       draw_re_head (solfa_half_width, -1, 2.5);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Quart rehead", "u2re");
-       draw_re_head (solfa_quarter_width, 1);
+       draw_re_head (solfa_quarter_width, 1, 2.5);
        fill p_out;
 fet_endchar;
 
 
 fet_beginchar ("Quart rehead", "d2re");
-       draw_re_head (solfa_quarter_width, -1);
+       draw_re_head (solfa_quarter_width, -1, 2.5);
        fill p_out;
 fet_endchar;
 
 
-def draw_mi_head (expr width_factor) =
+fet_beginchar ("Whole thin rehead", "s0reThin");
+       draw_re_head (solfa_whole_width, 1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Half up thin rehead", "u1reThin");
+       draw_re_head (solfa_half_width, 1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Half down thin rehead", "d1reThin");
+       draw_re_head (solfa_half_width, -1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Quart thin rehead", "u2reThin");
+       draw_re_head (solfa_quarter_width, 1, 1);
+       fill p_out;
+fet_endchar;
+
+
+fet_beginchar ("Quart thin rehead", "d2reThin");
+       draw_re_head (solfa_quarter_width, -1, 1);
+       fill p_out;
+fet_endchar;
+
+
+
+
+%%%% mi head -- diamond shape
+
+def draw_mi_head (expr width_factor, thickness_factor, mirror) =
        save path_out, path_in;
        save ne_dist, se_dist, ne, se;
+       save path_a, path_b, path_c, path_d;
        path path_out, path_in;
        pair ne_dist, se_dist, ne, se;
+       path path_a, path_b, path_c, path_d;
+       save inner_path;
+       path inner_path;
 
        set_char_box (0, width_factor * solfa_base_notewidth#,
                      0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
@@ -1209,6 +1308,7 @@ def draw_mi_head (expr width_factor) =
        y3 = y1;
        top y4 = h;
 
+       % inner sides are parallel to outer sides
        z6 - z5 = whatever * (z2 - z1);
        z8 - z7 = whatever * (z2 - z1);
        z8 - z5 = whatever * (z4 - z1);
@@ -1220,19 +1320,30 @@ def draw_mi_head (expr width_factor) =
        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 se_dist;
+       path_a := (z1 - se_dist) -- (z2 - se_dist);
+       path_b := (z2 + (ne_dist * thickness_factor)) --
+                 (z3 + (ne_dist * thickness_factor));
+       path_c := (z3 + se_dist) -- (z4 + se_dist);
+       path_d := (z4 - (ne_dist * thickness_factor)) --
+                 (z1 - (ne_dist * thickness_factor));
 
-       z5 - z1 = -(z7 - z3);
+       z5 = path_a intersectionpoint path_d;
+       z7 = path_b intersectionpoint path_c;
 
        labels (range 1 thru 8);
 
-       path_in := z5
+       inner_path := z5
                   -- z6
                   -- z7
                   -- z8
                   -- cycle;
 
+       path_in := if mirror:
+                     inner_path;
+                  else:
+                     inner_path reflectedabout (z2, z4);
+                  fi
+
        path_out := lft z1
                    .. (z1 + se_dist){-se}
                    -- (z2 + se_dist){-se}
@@ -1250,31 +1361,75 @@ enddef;
 
 
 fet_beginchar ("Whole mihead", "s0mi");
-       draw_mi_head (solfa_whole_width);
+       draw_mi_head (solfa_whole_width, 3, false);
        fill path_out;
        unfill path_in;
 fet_endchar;
 
 
 fet_beginchar ("Half mihead", "s1mi");
-       draw_mi_head (solfa_quarter_width);
+       draw_mi_head (solfa_quarter_width, 3, false);
        fill path_out;
        unfill path_in;
 fet_endchar;
 
-
 fet_beginchar ("Quart mihead", "s2mi");
-       draw_mi_head (solfa_quarter_width);
+       draw_mi_head (solfa_quarter_width, 3, false);
        fill path_out;
 fet_endchar;
 
 
-def draw_fa_head (expr width_factor) =
+
+fet_beginchar ("Whole mirror mihead", "s0miMirror");
+       draw_mi_head (solfa_whole_width, 3, true);
+       fill path_out;
+       unfill path_in;
+fet_endchar;
+
+fet_beginchar ("Half  mirror mihead", "s1miMirror");
+       draw_mi_head (solfa_quarter_width, 3, true);
+       fill path_out;
+       unfill path_in;
+fet_endchar;
+
+fet_beginchar ("Quart mirror mihead", "s2miMirror");
+       draw_mi_head (solfa_quarter_width, 3, true);
+       fill path_out;
+fet_endchar;
+
+
+
+fet_beginchar ("Whole thin mihead", "s0miThin");
+       draw_mi_head (solfa_whole_width, 1, false);
+       fill path_out;
+       unfill path_in;
+fet_endchar;
+
+
+fet_beginchar ("Half thin mihead", "s1miThin");
+       draw_mi_head (solfa_quarter_width, 1, false);
+       fill path_out;
+       unfill path_in;
+fet_endchar;
+
+
+fet_beginchar ("Quart thin mihead", "s2miThin");
+       draw_mi_head (solfa_quarter_width, 1, false);
+       fill path_out;
+fet_endchar;
+
+
+
+%%%%  fa head
+
+def draw_fa_head (expr width_factor, thickness_factor) =
        set_char_box (0, width_factor * solfa_base_notewidth#,
                      0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
 
        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;
+       save path_a, path_b, path_c;
+       path path_a, path_b, path_c;
        pair nw_dist, nw;
 
        pickup pencircle scaled solfa_pen_thick;
@@ -1295,12 +1450,16 @@ def draw_fa_head (expr width_factor) =
        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;
+       path_a := (z1 - (0,1) * thickness_factor * solfa_pen_thick) --
+                 (z2 - (0,1) * thickness_factor * solfa_pen_thick);
+       path_b := (z2 - (1,0) * 0.5 solfa_pen_thick) --
+                 (z3 - (1,0) * 0.5 solfa_pen_thick);
+       path_c := (z3 - nw_dist) -- (z1 - nw_dist);
+
+       p_up_in := (path_a intersectionpoint path_b) --
+                  (path_b intersectionpoint path_c) --
+                  (path_c intersectionpoint path_a) --
+                  cycle;
 
        p_up_out := lft z1{down}
                    .. (z1 + nw_dist){-nw}
@@ -1321,51 +1480,99 @@ enddef;
 
 
 fet_beginchar ("Whole fa up head", "u0fa");
-       draw_fa_head (solfa_whole_width);
+       draw_fa_head (solfa_whole_width, 1.5);
        fill p_up_out;
        unfill p_up_in;
 fet_endchar;
 
 
 fet_beginchar ("Whole fa down head", "d0fa");
-       draw_fa_head (solfa_whole_width);
+       draw_fa_head (solfa_whole_width, 1.5);
        fill p_down_out;
        unfill p_down_in;
 fet_endchar;
 
 
 fet_beginchar ("half fa up head", "u1fa");
-       draw_fa_head (solfa_half_width);
+       draw_fa_head (solfa_half_width, 1.5);
        fill p_up_out;
        unfill p_up_in;
 fet_endchar;
 
 
 fet_beginchar ("Half fa down head", "d1fa");
-       draw_fa_head (solfa_half_width);
+       draw_fa_head (solfa_half_width, 1.5);
        fill p_down_out;
        unfill p_down_in;
 fet_endchar;
 
 
 fet_beginchar ("Quarter fa up head", "u2fa");
-       draw_fa_head (solfa_quarter_width);
+       draw_fa_head (solfa_quarter_width, 1.5);
        fill p_up_out;
 fet_endchar;
 
 
 fet_beginchar ("Quarter fa down head", "d2fa");
-       draw_fa_head (solfa_quarter_width);
+       draw_fa_head (solfa_quarter_width, 1.5);
+       fill p_down_out;
+fet_endchar;
+
+
+fet_beginchar ("Whole thin fa up head", "u0faThin");
+       draw_fa_head (solfa_whole_width, 1);
+       fill p_up_out;
+       unfill p_up_in;
+fet_endchar;
+
+
+fet_beginchar ("Whole thin fa down head", "d0faThin");
+       draw_fa_head (solfa_whole_width, 1);
        fill p_down_out;
+       unfill p_down_in;
 fet_endchar;
 
 
+fet_beginchar ("half thin fa up head", "u1faThin");
+       draw_fa_head (solfa_half_width, 1);
+       fill p_up_out;
+       unfill p_up_in;
+fet_endchar;
+
+
+fet_beginchar ("Half thin fa down head", "d1faThin");
+       draw_fa_head (solfa_half_width, 1);
+       fill p_down_out;
+       unfill p_down_in;
+fet_endchar;
+
+
+fet_beginchar ("Quarter thin fa up head", "u2faThin");
+       draw_fa_head (solfa_quarter_width, 1);
+       fill p_up_out;
+fet_endchar;
+
+
+fet_beginchar ("Quarter thin fa down head", "d2faThin");
+       draw_fa_head (solfa_quarter_width, 1);
+       fill p_down_out;
+fet_endchar;
+
+
+
+%%%% sol head
+%%
+%%  Note -- sol head is the same shape as a standard music
+%%         head, and doesn't vary from style to style.
+%%         However, width is constant with duration, so we
+%%         can't just use the standard note font.
+
 def draw_sol_head (expr filled) =
        draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17);
-        if not filled:
+       if not filled:
          undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#);
-        fi
-        draw_staff (-2, 2, 0);
+       fi
+       draw_staff (-2, 2, 0);
 enddef;
 
 fet_beginchar ("Whole solhead", "s0sol");
@@ -1384,9 +1591,9 @@ fet_endchar;
 
 
 
+%%%% la head
 
-
-def draw_la_head (expr width_factor) =
+def draw_la_head (expr width_factor, thickness_factor) =
        set_char_box (0, width_factor * solfa_base_notewidth#,
                      0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
        save p_in, p_out;
@@ -1407,10 +1614,10 @@ def draw_la_head (expr width_factor) =
 
        labels (range 1 thru 4);
 
-       p_in := (z1 + 0.5 solfa_pen_thick * (1, -1))
-               -- (z2 + 0.5 solfa_pen_thick * (-1, -1))
-               -- (z3 + 0.5 solfa_pen_thick * (-1, 1))
-               -- (z4 + 0.5 solfa_pen_thick * (1, 1))
+       p_in := (z1 + 0.5 solfa_pen_thick * (1, -thickness_factor))
+               -- (z2 + 0.5 solfa_pen_thick * (-1, -thickness_factor))
+               -- (z3 + 0.5 solfa_pen_thick * (-1, thickness_factor))
+               -- (z4 + 0.5 solfa_pen_thick * (1, thickness_factor))
                -- cycle;
 
        p_out := top z1
@@ -1426,31 +1633,54 @@ enddef;
 
 
 fet_beginchar ("Whole lahead", "s0la");
-       draw_la_head (solfa_whole_width);
+       draw_la_head (solfa_whole_width, 3);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Half lahead", "s1la");
-       draw_la_head (solfa_half_width);
+       draw_la_head (solfa_half_width, 3);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Quart lahead", "s2la");
-       draw_la_head (solfa_quarter_width);
+       draw_la_head (solfa_quarter_width, 3);
+       fill p_out;
+fet_endchar;
+
+
+fet_beginchar ("Whole thin lahead", "s0laThin");
+       draw_la_head (solfa_whole_width, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Half thin lahead", "s1laThin");
+       draw_la_head (solfa_half_width, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Quart lahead", "s2laThin");
+       draw_la_head (solfa_quarter_width, 1);
        fill p_out;
 fet_endchar;
 
 
-def draw_ti_head (expr width_factor, dir) =
+
+%%%% ti head
+
+def draw_ti_head (expr width_factor, dir, thickness_factor) =
        set_char_box (0, width_factor * solfa_base_notewidth#,
                      0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
-       save p_in, p_out, p_top;
+       save p_in, p_out, p_top, p_top_in;
        save nw_dist, sw_dist, nw, sw;
-       path p_in, p_out, p_top;
+       path p_in, p_out, p_top, p_top_in;
        pair nw_dist, sw_dist, nw, sw;
        save cone_height;
        cone_height = 0.64;
@@ -1465,6 +1695,8 @@ def draw_ti_head (expr width_factor, dir) =
        y4 = y2;
        x3 = x1;
        top y3 = h;
+       x5 = x1;
+       y5 = y1 + thickness_factor * 0.5 * solfa_pen_thick;
 
        labels (range 1 thru 4);
 
@@ -1478,14 +1710,19 @@ def draw_ti_head (expr width_factor, dir) =
                 .. (top z3){right}
                 .. (z4 - nw_dist);
 
-       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 + nw_dist)) intersectionpoint
-                    ((z1 - sw_dist) -- (z4 - sw_dist)))
-               -- cycle;
+       p_top_in := (z2 + sw_dist * thickness_factor) {- sw}
+                   .. ((top z3) - (0,1) * thickness_factor * 0.5 solfa_pen_thick) {right}
+                   .. (z4 + nw_dist * thickness_factor){- nw};
+
+       save path_a, path_b;
+       path path_a, path_b;
+       path_a := z2 -- z5;
+       path_b := z5 -- z4;
+
+       z6 = path_a intersectionpoint p_top_in;
+       z7 = path_b intersectionpoint p_top_in;
+
+       p_in := z5 -- z6 .. bot z3 .. z7 -- cycle;
 
        p_out := bot z1
                 .. (z1 + nw_dist)
@@ -1508,41 +1745,76 @@ enddef;
 
 
 fet_beginchar ("Whole up tihead", "s0ti");
-       draw_ti_head (solfa_whole_width, 1);
+       draw_ti_head (solfa_whole_width, 1, 3);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Half up tihead", "u1ti");
-       draw_ti_head (solfa_half_width, 1);
+       draw_ti_head (solfa_half_width, 1, 3);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Half down tihead", "d1ti");
-       draw_ti_head (solfa_half_width, -1);
+       draw_ti_head (solfa_half_width, -1, 3);
        fill p_out;
        unfill p_in;
 fet_endchar;
 
 
 fet_beginchar ("Quart up tihead", "u2ti");
-       draw_ti_head (solfa_quarter_width, 1);
+       draw_ti_head (solfa_quarter_width, 1, 3);
        fill p_out;
 fet_endchar;
 
 
 fet_beginchar ("Quart down tihead", "d2ti");
-       draw_ti_head (solfa_quarter_width, -1);
+       draw_ti_head (solfa_quarter_width, -1, 3);
        fill p_out;
 fet_endchar;
 
 
+fet_beginchar ("Whole thin up tihead", "s0tiThin");
+       draw_ti_head (solfa_whole_width, 1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Half thin up tihead", "u1tiThin");
+       draw_ti_head (solfa_half_width, 1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Half thin down tihead", "d1tiThin");
+       draw_ti_head (solfa_half_width, -1, 1);
+       fill p_out;
+       unfill p_in;
+fet_endchar;
+
+
+fet_beginchar ("Quart thin up tihead", "u2tiThin");
+       draw_ti_head (solfa_quarter_width, 1, 1);
+       fill p_out;
+fet_endchar;
+
+
+fet_beginchar ("Quart thin down tihead", "d2tiThin");
+       draw_ti_head (solfa_quarter_width, -1, 1);
+       fill p_out;
+fet_endchar;
+
+
+
 fet_endgroup ("noteheads");
 
 
+
 %
 % we derive black_notehead_width# from the quarter head,
 % so we have to define black_notehead_width (pixel qty)
diff --git a/mf/feta-noteheads11.mf b/mf/feta-noteheads11.mf
new file mode 100644 (file)
index 0000000..b02844a
--- /dev/null
@@ -0,0 +1,13 @@
+% feta-noteheads11.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 11.22;
+test := 0;
+
+
+input feta-noteheads-generic;
+
+end.
+
diff --git a/mf/feta-noteheads13.mf b/mf/feta-noteheads13.mf
new file mode 100644 (file)
index 0000000..e010769
--- /dev/null
@@ -0,0 +1,13 @@
+% feta-noteheads13.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 12.60;
+test := 0;
+
+
+input feta-noteheads-generic;
+
+end.
+
diff --git a/mf/feta-noteheads14.mf b/mf/feta-noteheads14.mf
new file mode 100644 (file)
index 0000000..7d25cb2
--- /dev/null
@@ -0,0 +1,13 @@
+% feta-noteheads14.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 14.14;
+test := 0;
+
+
+input feta-noteheads-generic;
+
+end.
+
diff --git a/mf/feta-noteheads16.mf b/mf/feta-noteheads16.mf
new file mode 100644 (file)
index 0000000..755f9ff
--- /dev/null
@@ -0,0 +1,13 @@
+% feta-noteheads16.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 15.87;
+test := 0;
+
+
+input feta-noteheads-generic;
+
+end.
+
diff --git a/mf/feta-noteheads18.mf b/mf/feta-noteheads18.mf
new file mode 100644 (file)
index 0000000..bdc6918
--- /dev/null
@@ -0,0 +1,13 @@
+% feta-noteheads18.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 17.82;
+test := 0;
+
+
+input feta-noteheads-generic;
+
+end.
+
diff --git a/mf/feta-noteheads20.mf b/mf/feta-noteheads20.mf
new file mode 100644 (file)
index 0000000..072f992
--- /dev/null
@@ -0,0 +1,13 @@
+% feta-noteheads20.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 20;
+test := 0;
+
+
+input feta-noteheads-generic;
+
+end.
+
diff --git a/mf/feta-noteheads23.mf b/mf/feta-noteheads23.mf
new file mode 100644 (file)
index 0000000..ab01548
--- /dev/null
@@ -0,0 +1,13 @@
+% feta-noteheads23.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 22.45;
+test := 0;
+
+
+input feta-noteheads-generic;
+
+end.
+
diff --git a/mf/feta-noteheads26.mf b/mf/feta-noteheads26.mf
new file mode 100644 (file)
index 0000000..b25d214
--- /dev/null
@@ -0,0 +1,13 @@
+% feta-noteheads26.mf
+% part of LilyPond's pretty-but-neat music font
+
+input feta-autometric;
+
+design_size := 25.20;
+test := 0;
+
+
+input feta-noteheads-generic;
+
+end.
+
index c18061b15a32c4f0e6a5b6a9b51e45b359958bd7..00265fc475163bdbf2495b5fa4a0351bc72af815 100644 (file)
@@ -6,7 +6,6 @@
 %input feta-rests;
 input feta-accidentals;
 %input feta-dots;
-%input feta-noteheads;
 %input feta-arrowheads;
 %input feta-scripts;
 %input feta-flags;