diff options
27 files changed, 663 insertions, 104 deletions
diff --git a/Documentation/changes.tely b/Documentation/changes.tely index 8f4c3dc6f3..3bc51314cc 100644 --- a/Documentation/changes.tely +++ b/Documentation/changes.tely @@ -65,6 +65,12 @@ which scares away people. @end ignore @item +Aesthetics of shape note heads have been enhanced. Variable line thicknesses +have been implemented. All note widths have been made consistent. +Minor shape note commands that use the relative major key for scale steps +have been added. + +@item A variant of the segno sign is provided: @lilypond[quote,relative=2] c4 d e f \bar "S" diff --git a/Documentation/included/font-table.ly b/Documentation/included/font-table.ly index 3bdb80a6c8..3a5f6ebd88 100644 --- a/Documentation/included/font-table.ly +++ b/Documentation/included/font-table.ly @@ -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\\.")) diff --git a/Documentation/notation/pitches.itely b/Documentation/notation/pitches.itely index 31af761a7e..7e33d7a91c 100644 --- a/Documentation/notation/pitches.itely +++ b/Documentation/notation/pitches.itely @@ -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 index 0000000000..30134ffa46 --- /dev/null +++ b/input/regression/note-head-aiken.ly @@ -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 index 0000000000..fdd2eb108f --- /dev/null +++ b/input/regression/note-head-sacred-harp.ly @@ -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 index 0000000000..d7356d3e82 --- /dev/null +++ b/input/regression/note-head-shape-minor.ly @@ -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 | +} + diff --git a/input/regression/note-head-solfa.ly b/input/regression/note-head-solfa.ly index b4d24ca852..d6b163dfcb 100644 --- a/input/regression/note-head-solfa.ly +++ b/input/regression/note-head-solfa.ly @@ -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 index 0000000000..3e20a018bc --- /dev/null +++ b/input/regression/note-head-southern-harmony.ly @@ -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 +} + diff --git a/ly/property-init.ly b/ly/property-init.ly index 4238dd14e0..0b1f2a2ea7 100644 --- a/ly/property-init.ly +++ b/ly/property-init.ly @@ -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 diff --git a/mf/GNUmakefile b/mf/GNUmakefile index 956c8fa47c..329d673bfb 100644 --- a/mf/GNUmakefile +++ b/mf/GNUmakefile @@ -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 diff --git a/mf/bigcheese.pe.in b/mf/bigcheese.pe.in index 46b74f0abf..e1d1843ba4 100644 --- a/mf/bigcheese.pe.in +++ b/mf/bigcheese.pe.in @@ -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. diff --git a/mf/feta-autometric.mf b/mf/feta-autometric.mf index b77e4827db..c5c7e4836d 100644 --- a/mf/feta-autometric.mf +++ b/mf/feta-autometric.mf @@ -196,7 +196,7 @@ enddef; % -% we leave the ctrl characters alone. +% we leave the ctrl characters alone % code := 32; diff --git a/mf/feta-generic.mf b/mf/feta-generic.mf index 5006b1f99d..3472715e16 100644 --- a/mf/feta-generic.mf +++ b/mf/feta-generic.mf @@ -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 index 0000000000..89de7d06a2 --- /dev/null +++ b/mf/feta-noteheads-generic.mf @@ -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 index 0000000000..7baeb9b29d --- /dev/null +++ b/mf/feta-noteheads-test-generic.mf @@ -0,0 +1,6 @@ +% +% test stuff. +% in a separate file to avoid tainting non-test font files for testing. +% + +input feta-noteheads; diff --git a/mf/feta-noteheads.mf b/mf/feta-noteheads.mf index c413eac33e..8b7068ed1f 100644 --- a/mf/feta-noteheads.mf +++ b/mf/feta-noteheads.mf @@ -13,11 +13,11 @@ % % 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 index 0000000000..b02844a196 --- /dev/null +++ b/mf/feta-noteheads11.mf @@ -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 index 0000000000..e010769f4b --- /dev/null +++ b/mf/feta-noteheads13.mf @@ -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 index 0000000000..7d25cb2a60 --- /dev/null +++ b/mf/feta-noteheads14.mf @@ -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 index 0000000000..755f9ffdd5 --- /dev/null +++ b/mf/feta-noteheads16.mf @@ -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 index 0000000000..bdc6918bf3 --- /dev/null +++ b/mf/feta-noteheads18.mf @@ -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 index 0000000000..072f99207c --- /dev/null +++ b/mf/feta-noteheads20.mf @@ -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 index 0000000000..ab0154832e --- /dev/null +++ b/mf/feta-noteheads23.mf @@ -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 index 0000000000..b25d21495c --- /dev/null +++ b/mf/feta-noteheads26.mf @@ -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. + diff --git a/mf/feta-test-generic.mf b/mf/feta-test-generic.mf index c18061b15a..00265fc475 100644 --- a/mf/feta-test-generic.mf +++ b/mf/feta-test-generic.mf @@ -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; diff --git a/scripts/build/gen-emmentaler-scripts.py b/scripts/build/gen-emmentaler-scripts.py index 275fccaf89..d7ea193b59 100644 --- a/scripts/build/gen-emmentaler-scripts.py +++ b/scripts/build/gen-emmentaler-scripts.py @@ -1,7 +1,7 @@ #!@PYTHON@ import sys import getopt -import re +import re import os (options, files) = \ @@ -22,7 +22,7 @@ for opt in options: # Ugh for design_size in [11,13,14,16,18,20,23,26]: - name = 'Emmentaler' + name = 'Emmentaler' filename = name.lower () script = '''#!@FONTFORGE@ @@ -41,6 +41,7 @@ notice += "resulting document to be covered by the GNU General Public License."; SetFontNames("%(name)s-%(design_size)d", "%(name)s-%(design_size)d", "%(name)s-%(design_size)d", "", notice, "@TOPLEVEL_VERSION@"); MergeFonts("feta%(design_size)d.pfb"); +MergeFonts("feta-noteheads%(design_size)d.pfb"); MergeFonts("parmesan%(design_size)d.pfb"); # load nummer/din after setting PUA. @@ -87,9 +88,9 @@ Generate("%(filename)s-%(design_size)d.svg"); ns = [] for s in subfonts: ns.append ('%s' % (s % vars())) - + subfonts_str = ' '.join (ns) - + open (os.path.join (outdir, '%(filename)s-%(design_size)d.subfonts' % vars()), 'w').write (subfonts_str) path = os.path.join (outdir, '%s-%d.dep' % (filename, design_size)) diff --git a/scripts/build/mf-to-table.py b/scripts/build/mf-to-table.py index 9a1c8012e6..542ab774d1 100644 --- a/scripts/build/mf-to-table.py +++ b/scripts/build/mf-to-table.py @@ -1,6 +1,6 @@ #!@PYTHON@ -# mf-to-table.py -- convert spacing info in MF logs . +# mf-to-table.py -- convert spacing info in MF logs . # This file is part of LilyPond, the GNU music typesetter. # @@ -55,7 +55,7 @@ font_family = 'feta' def parse_logfile (fn): autolines, deps = read_log_file (fn) charmetrics = [] - + global_info = { 'filename' : os.path.splitext (os.path.basename (fn))[0] } @@ -112,7 +112,7 @@ def parse_logfile (fn): elif tags[0] == 'parameter': global_info[tags[1]] = tags[2]; - + return (global_info, charmetrics, deps) @@ -150,7 +150,7 @@ def global_lisp_table (global_info): keys = ['staffsize', 'stafflinethickness', 'staff_space', 'linethickness', 'black_notehead_width', 'ledgerlinethickness', - 'design_size', + 'design_size', 'blot_diameter' ] for k in keys: @@ -159,7 +159,7 @@ def global_lisp_table (global_info): return str - + def ps_encoding (name, global_info, charmetrics): encs = ['.notdef'] * 256 for m in charmetrics: @@ -220,9 +220,9 @@ for opt in options: depfile_nm = a elif o == '--outdir' or o == '-o': outdir_prefix = a - elif o == '--lisp': + elif o == '--lisp': char_lisp_nm = a - elif o == '--global-lisp': + elif o == '--global-lisp': global_lisp_nm = a elif o == '--enc': enc_nm = a @@ -242,6 +242,8 @@ for filenm in files: enc_name = 'FetaEncoding' if re.search ('parmesan', filenm): enc_name = 'ParmesanEncoding' + elif re.search ('feta-noteheads', filenm): + enc_name = 'FetaNoteheadsEncoding' elif re.search ('feta-brace', filenm): enc_name = 'FetaBraceEncoding' elif re.search ('feta-alphabet', filenm): |