From 127a1c165d3c16f971413ba36de9bb65cf3d8aa4 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Thu, 3 Aug 2000 20:29:02 +0200 Subject: [PATCH] release: 1.3.76 ====== * Lyric_phrasing_engraver now adjusts for melisma. (Glenn Prideaux). * Mudela-book fix for Windows95 (Mark Hindley) * Debian update (Anthony Fok) * Added beam melisma for when automaticMelismata and noAutoBeaming are both #t (primarily for hymns). Courtesy Glenn Prideaux. * Bugfix: .pfa dependency on $(outdir)/mfplain.mem 1.3.75. --- CHANGES | 14 ++ VERSION | 4 +- debian/GNUmakefile | 2 +- debian/changelog | 23 +++ debian/{out => }/control | 15 +- debian/control.foka | 10 +- debian/control.in | 28 ---- debian/copyright | 4 +- debian/rules | 8 +- input/bugs/direction.ly | 1 - input/bugs/dynamic-dir.ly | 12 ++ input/bugs/orchestscore.ly | 109 ++++++++++++ input/test/multistanza.ly | 146 ++++++++++++++++ input/test/two-slurs.ly | 19 +++ lily/beam-engraver.cc | 25 +++ lily/include/lyric-phrasing-engraver.hh | 9 +- lily/lyric-phrasing-engraver.cc | 214 ++++++++++++++++++------ lily/melisma-engraver.cc | 16 +- ly/engraver.ly | 3 + make/out/lilypond.lsm | 8 +- make/out/lilypond.spec | 4 +- scm/slur.scm | 7 + scripts/mudela-book.py | 7 +- stepmake/stepmake/metapost-rules.make | 2 +- 24 files changed, 582 insertions(+), 108 deletions(-) rename debian/{out => }/control (54%) delete mode 100644 debian/control.in delete mode 100644 input/bugs/direction.ly create mode 100644 input/bugs/dynamic-dir.ly create mode 100644 input/bugs/orchestscore.ly create mode 100644 input/test/multistanza.ly create mode 100644 input/test/two-slurs.ly diff --git a/CHANGES b/CHANGES index 1f4dbacfa5..1a35d304ec 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,17 @@ +1.3.76 +====== + +* Lyric_phrasing_engraver now adjusts for melisma. (Glenn Prideaux). + +* Mudela-book fix for Windows95 (Mark Hindley) + +* Debian update (Anthony Fok) + +* Added beam melisma for when automaticMelismata and noAutoBeaming are both + #t (primarily for hymns). Courtesy Glenn Prideaux. + +* Bugfix: .pfa dependency on $(outdir)/mfplain.mem + 1.3.75.mb1 ========== diff --git a/VERSION b/VERSION index c72cdd40ea..2646ad5419 100644 --- a/VERSION +++ b/VERSION @@ -1,8 +1,8 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 -PATCH_LEVEL=75 -MY_PATCH_LEVEL=mb1 +PATCH_LEVEL=76 +MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/debian/GNUmakefile b/debian/GNUmakefile index 7575f87fc2..b9ea31efad 100644 --- a/debian/GNUmakefile +++ b/debian/GNUmakefile @@ -8,7 +8,7 @@ at-ext = EXTRA_DIST_FILES = README.Debian TODO $(CONF_FILES) \ control.foka ex.prerm ex.doc-base -CONF_FILES = changelog copyright emacsen-startup \ +CONF_FILES = changelog control copyright emacsen-startup \ preinst postinst postrm rules watch #OUTCONF_FILES = $(addprefix $(outdir)/, $(basename $(CONF_FILES))) $(OUTIN_FILES) OUTCONF_FILES = $(OUTIN_FILES) diff --git a/debian/changelog b/debian/changelog index 7d6b2976ff..99461b2ef9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,26 @@ +lilypond1.3 (1.3.75-1) unstable; urgency=low + + * New upstream release. + * Updated the link to the http://sca.uwaterloo.ca/lilypond/ mirror in + the package description. + + -- Anthony Fok Wed, 26 Jul 2000 01:56:28 -0600 + +lilypond1.3 (1.3.58-1) unstable; urgency=low + + * New upstream release with patch from Han-wen. + + -- Anthony Fok Thu, 8 Jun 2000 17:19:08 -0600 + +lilypond1.3 (1.3.48-1) unstable; urgency=low + + * New upstream release. + * [debian/control]: Added Depends: guile, for /usr/bin/as2text (Lintian). + * [debian/rules]: Changed the symlink /usr/share/lilypond/cmtfm from + absolute to relative. + + -- Anthony Fok Wed, 10 May 2000 12:17:54 -0600 + lilypond1.3 (1.3.45-1) unstable; urgency=low * New upstream release. diff --git a/debian/out/control b/debian/control similarity index 54% rename from debian/out/control rename to debian/control index 12d811e790..30f1f8caf5 100644 --- a/debian/out/control +++ b/debian/control @@ -1,28 +1,29 @@ Source: lilypond1.3 -Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin (>= 1.0.5-1), tetex-base (>= 1.0-1), tetex-extra (>= 1.0-1), flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1) +Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin (>= 1.0.5-1), tetex-extra (>= 1.0-1), flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1), groff, gs, netpbm, pnmtopng, m4, gettext (>= 0.10.35-13) Section: tex Priority: optional Maintainer: Anthony Fok -Standards-Version: 3.1.0 +Standards-Version: 3.1.1 Package: lilypond1.3 Architecture: any Replaces: lilypond Provides: lilypond -Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1) -Recommends: python-base (>= 1.5.2-4), tetex-base (>= 1.0-1), tetex-extra (>= 1.0-1) +Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1), python-base (>= 1.5.2-4), guile +Recommends: tetex-extra (>= 1.0-1) Conflicts: lilypond, musixtex-fonts Description: A program for printing sheet music. LilyPond is a music typesetter. It produces beautiful sheet music using a high level description file as input. LilyPond is part of the GNU Project. . - This is the unstable 1.3 branch of LilyPond. It is not intended for - use with stable projects! + This is the developmental 1.3 branch of LilyPond. It is not intended for + use with stable projects, although 1.3.75 is most likely to be less buggy + and much more featureful than then the old "stable" 1.2.17. . URLs: http://www.cs.uu.nl/~hanwen/lilypond/ http://www.xs4all.nl/~jantien/lilypond/ - http://sca.uwaterloo.ca/~praetzel/lilypond/ + http://sca.uwaterloo.ca/lilypond/ http://www.lilypond.org/ Authors: Han-Wen Nienhuys Jan Nieuwenhuizen diff --git a/debian/control.foka b/debian/control.foka index 546898f103..30f1f8caf5 100644 --- a/debian/control.foka +++ b/debian/control.foka @@ -9,8 +9,8 @@ Package: lilypond1.3 Architecture: any Replaces: lilypond Provides: lilypond -Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1) -Recommends: python-base (>= 1.5.2-4), tetex-extra (>= 1.0-1) +Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1), python-base (>= 1.5.2-4), guile +Recommends: tetex-extra (>= 1.0-1) Conflicts: lilypond, musixtex-fonts Description: A program for printing sheet music. LilyPond is a music typesetter. It produces beautiful sheet music @@ -18,12 +18,12 @@ Description: A program for printing sheet music. the GNU Project. . This is the developmental 1.3 branch of LilyPond. It is not intended for - use with stable projects, although arguably 1.3.45 is less buggy and much - more featureful than then the "stable" 1.2.17. + use with stable projects, although 1.3.75 is most likely to be less buggy + and much more featureful than then the old "stable" 1.2.17. . URLs: http://www.cs.uu.nl/~hanwen/lilypond/ http://www.xs4all.nl/~jantien/lilypond/ - http://sca.uwaterloo.ca/~praetzel/lilypond/ + http://sca.uwaterloo.ca/lilypond/ http://www.lilypond.org/ Authors: Han-Wen Nienhuys Jan Nieuwenhuizen diff --git a/debian/control.in b/debian/control.in deleted file mode 100644 index 12d811e790..0000000000 --- a/debian/control.in +++ /dev/null @@ -1,28 +0,0 @@ -Source: lilypond1.3 -Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin (>= 1.0.5-1), tetex-base (>= 1.0-1), tetex-extra (>= 1.0-1), flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1) -Section: tex -Priority: optional -Maintainer: Anthony Fok -Standards-Version: 3.1.0 - -Package: lilypond1.3 -Architecture: any -Replaces: lilypond -Provides: lilypond -Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1) -Recommends: python-base (>= 1.5.2-4), tetex-base (>= 1.0-1), tetex-extra (>= 1.0-1) -Conflicts: lilypond, musixtex-fonts -Description: A program for printing sheet music. - LilyPond is a music typesetter. It produces beautiful sheet music - using a high level description file as input. LilyPond is part of - the GNU Project. - . - This is the unstable 1.3 branch of LilyPond. It is not intended for - use with stable projects! - . - URLs: http://www.cs.uu.nl/~hanwen/lilypond/ - http://www.xs4all.nl/~jantien/lilypond/ - http://sca.uwaterloo.ca/~praetzel/lilypond/ - http://www.lilypond.org/ - Authors: Han-Wen Nienhuys - Jan Nieuwenhuizen diff --git a/debian/copyright b/debian/copyright index 95bcbef88d..7f4801cbe4 100644 --- a/debian/copyright +++ b/debian/copyright @@ -5,10 +5,10 @@ The development branch, lilypond1.3, is packaged separately on Tue, 9 Nov 1999 22:30:32 -0700 It was downloaded from - ftp://ftp.lilypond.org/pub/LilyPond/v1.3/lilypond-1.3.45.tar.gz + ftp://ftp.lilypond.org/pub/LilyPond/v1.3/lilypond-1.3.74.tar.gz It is also available at: - ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/v1.3/lilypond-1.3.45.tar.gz + ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/v1.3/lilypond-1.3.74.tar.gz For more information about GNU LilyPond, please visit: http://www.cs.uu.nl/~hanwen/lilypond/ diff --git a/debian/rules b/debian/rules index 531cebd089..d2c9ef813e 100755 --- a/debian/rules +++ b/debian/rules @@ -18,7 +18,7 @@ d = usr/share/doc/$(package) # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -# This is the debhelper compatability version to use. +# This is the debhelper compatibility version to use. export DH_COMPAT=1 build: build-stamp @@ -71,6 +71,12 @@ install: build ln -s ../../../../lilypond/afm $(r)/usr/share/texmf/fonts/afm/public/lilypond ln -s ../../../../lilypond/tfm $(r)/usr/share/texmf/fonts/tfm/public/lilypond + # Change from an absolute symlink to a relative symlink (Lintian) + if [ -L $(r)/usr/share/lilypond/cmtfm ]; then \ + rm -f $(r)/usr/share/lilypond/cmtfm; \ + ln -s ../texmf/fonts/tfm/public/cm $(r)/usr/share/lilypond/cmtfm; \ + fi + # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. diff --git a/input/bugs/direction.ly b/input/bugs/direction.ly deleted file mode 100644 index 8b13789179..0000000000 --- a/input/bugs/direction.ly +++ /dev/null @@ -1 +0,0 @@ - diff --git a/input/bugs/dynamic-dir.ly b/input/bugs/dynamic-dir.ly new file mode 100644 index 0000000000..e56db38adf --- /dev/null +++ b/input/bugs/dynamic-dir.ly @@ -0,0 +1,12 @@ +%non of the dynamics properties work anymore + +\score { + \context Voice \notes\relative c { + \property Voice.verticalDirection = #-1 + \property Voice.dynamicVerticalDirection = #-1 + \property Voice.dynamicDirection = #-1 + \property Voice.dynamicPadding = #40 + c \p c \< \! c \ff\> c \!c-\p + + } +} diff --git a/input/bugs/orchestscore.ly b/input/bugs/orchestscore.ly new file mode 100644 index 0000000000..8ad6ae4ffd --- /dev/null +++ b/input/bugs/orchestscore.ly @@ -0,0 +1,109 @@ +% +% Hara-kiri leaves a big gap +% + +\version "1.3.59"; + +m = \notes \relative c''{ + +c1 | c2 c | c c | c c | \break c c | c c | c c | c c | +} + +M = \notes \relative c''{ + +c1 | c2 c | c c | R1*5 +} + +\score{ < + \context StaffGroup = wood < + \context Staff = flauto < + \property Staff.instrument = "Flauto" + \property Staff.instr = "Fl." + \m + > + \context Staff = oboe < + \property Staff.instrument = "Oboe" + \property Staff.instr = "Ob." + \m + > + \context Staff = clarI < + \property Staff.instrument = "Clarinetto I" + \property Staff.instr = "Cl. I" + \m + > + \context Staff = clarII < + \property Staff.instrument = "Clarinetto II" + \property Staff.instr = "Cl. II" + \m + > + \context Staff = fagotto < + \property Staff.instrument = "Fagotto" + \property Staff.instr = "Fg." + \m + > + > + \context StaffGroup = brass < + \context Staff = cor < + \property Staff.instrument = "2 Corni in F" + \property Staff.instr = "Cor." + \context Voice = corI { \stemup \M } + \context Voice = corII { \stemdown \M } + > + \context Staff = trp < + \property Staff.instrument = "2 Trp. in B\\textflat " + \property Staff.instr = "Trp." + \context Voice = trpI { \stemup \M } + \context Voice = trpII { \stemdown \M } + > + > + \context StaffGroup = percussion <\context Staff = timpani < + \property Staff.instrument = "Timpani" + \property Staff.instr = "Timp." + \notes{c''1 R1*8} + > + > + \context StaffGroup = strings < + \context GrandStaff = violins < + \context Staff = viI < + \property Staff.instrument = "Violin I" + \property Staff.instr = "Vi. I" + \m + > + \context Staff = viII < + \property Staff.instrument = "Violin II" + \property Staff.instr = "Vi. II" + \m + > + > + \context Staff = vla < + \property Staff.instrument = "Viola" + \property Staff.instr = "Vla." + \m + > + \context Staff = vlc < + \property Staff.instrument = "Violoncello" + \property Staff.instr = "Vlc" + \m + > + \context Staff = cb < + \property Staff.instrument = "Contrabasso" + \property Staff.instr = "C.B." + \m + > + > +> + \paper { +% \paper_sixteen; + linewidth = 185.\mm; + textheight = 260.\mm; + \translator { + \OrchestralScoreContext + barNumberScriptPadding = 10; + } + \translator { \HaraKiriStaffContext + marginScriptPadding = 15.0; +% StaffMinimumVerticalExtent = #(cons -0.0 0.0) + } + } +} + diff --git a/input/test/multistanza.ly b/input/test/multistanza.ly new file mode 100644 index 0000000000..8defa2bf18 --- /dev/null +++ b/input/test/multistanza.ly @@ -0,0 +1,146 @@ +% Tests a number of features: +% * Lyric_phrasing_engraver +% * Stanza_number_engraver +% * Automatic melismata on beamed notes + +\version "1.3.59"; +\include "english.ly" + +\header{ + title = "Crowned with Honour"; + composer = "Oliver Holden (1765-1844)"; + poet = "Thomas Kelly (1769-1855)"; +} + +allup = \notes{ + \property Voice.verticalDirection = \up + \property Voice.slurVerticalDirection = \up + \property Voice.tieVerticalDirection = \up + \property Voice.dynamicDirection = \up + \autoBeamOff +} +alldown = \notes{ + \property Voice.verticalDirection = \down + \property Voice.slurVerticalDirection = \down + \property Voice.tieVerticalDirection = \down + \property Voice.dynamicDirection = \down + \autoBeamOff +} + +Global = \notes{ + \key g \major; + \time 4/4; + \partial 4; +} + +Soprano = \notes \relative c' { + \allup + d4 | g g b b a g a b a g b a g2. + + a4 | b a g b [d16 d c8] [b a] b4 % modified to test beam melisma +% a4 | b a g b [d8 \melisma c] \melismaEnd [b \melisma a] \melismaEnd b4 + + d d2 d e d4( cs8 ~ )cs d2. + + b4 | d b g b [a8 g] [a b] a4 +% b4 | d b g b [a8 \melisma g] \melismaEnd [a \melisma b] \melismaEnd a4 + + g d'2 c b4.( c8 )a4 a g2. +} +Alto = \notes \relative c'{ + \alldown + d4 | d d g g fs g fs g fs e g fs d2. + d4 | g d b g' [b8 a] [g fs] g4 fs g2 a g fs4( e8 )g fs2. + d4 | g g d g [fs8 e] [fs g] fs4 g f2 e d4.( d8 )d4 fs4 d2. +} +Tenor = \notes \relative c{ + \allup + d4 | b' b d d c b c d c b d c b2. + a4 | b a g b [d8 c] [b a] b4 a b2 c b a a2. + g4 | b d b d [c8 b] [c d] c4 b g2 g g4.( a8 [fs )a] c4 b2. +} +Bass = \notes \relative c{ + \alldown + d4 | g g g g d d d g d e d d g,2. + d'4 | g d b g' [b8 a] [g fs] g4 d g2 fs e a d,2. + g4 | g g g g d d d e b2 c d2. d4 g,2. +} + +TheLyrics = \lyrics < + { + \context LyricVoice = "Soprano-1" + \property LyricVoice .stanza = "1:" + \property LyricVoice .stz = "(1)" + The4 head that once was crowned with thorns + Is crowned with glo -- ry now; + A roy -- al di -- a -- dem a -- dorns + The might -- y Vic -- tor's brow. + A roy -- al di -- a -- dem a -- dorns + The might -- y Vic -- tor's brow. + } + { + \context LyricVoice = "Soprano-2" + \property LyricVoice .stanza = "2:" + \property LyricVoice .stz = "(2)" + The4 high -- est place that heav'n af -- fords + Is His by sov -- 'reign right; + The King of kings, the Lord of lords, + He reigns in glo -- ry bright, + The King of kings, the Lord of lords, + He reigns in glo -- ry bright. + } + { + \context LyricVoice = "Soprano-3" + \property LyricVoice .stanza = "3:" + \property LyricVoice .stz = "(3)" + The joy of all who dwell a -- bove, + The joy of saints be -- low, + To4 whom He man -- i -- fests His love, + And grants His name to know, + To4 whom He man -- i -- fests His love, + And grants His name to4 know. + } +> + + +\score{ + \context ChoirStaff + \notes + < + \property Score.barNumberScriptPadding = #10.0 + \context Staff = "treblestaff"{ + < + \context Voice = "Soprano" { } + \context Voice = "Alto" { } + > + } + \context Lyrics = mainlyrics { } + \context Staff = "treblestaff"{ + < + \Global + \addlyrics { \context Voice = "Soprano" \Soprano } + { \context Lyrics = mainlyrics \TheLyrics } + \context Voice = "Alto" \Alto + > + \bar "|."; + } + \context Staff = "bassstaff"{ + \clef "bass"; + < + \context Voice = "Tenor" { \Tenor } + \context Voice = "Bass" { \Bass } + > + \bar "|."; + } + > + + \paper { + \translator{ + \VoiceContext + automaticMelismata = ##t; + noAutoBeaming = ##t; + \remove "Auto_beam_engraver"; + } + + } +} diff --git a/input/test/two-slurs.ly b/input/test/two-slurs.ly new file mode 100644 index 0000000000..45b6025b9c --- /dev/null +++ b/input/test/two-slurs.ly @@ -0,0 +1,19 @@ +% +% We'd want to combine the stems, but have two slurs too... +% Looks like the a-due engraver +% +\score{ + \context Staff < + \context Voice=v \notes\relative c''{ + \stemup + a4 c4.()g8 a4 + } + \context Voice=u \notes\relative c''{ + \stemdown + g4 e4.()d8 c4 + } + > + \paper{ + linewidth=60.\mm; + } +} diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index 5574830c37..8b404079f3 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -37,6 +37,7 @@ class Beam_engraver : public Engraver Moment beam_start_mom_; void typeset_beam (); + void set_melisma (bool); protected: virtual void do_pre_move_processing (); virtual void do_post_move_processing (); @@ -75,12 +76,29 @@ Beam_engraver::do_try_music (Music *m) m->origin ()->warning (_ ("can't find start of beam")); return false; } + + if(d == STOP) + { + SCM m = get_property ("automaticMelismata"); + SCM b = get_property("noAutoBeaming"); + if (to_boolean (m) && to_boolean(b)) + { + set_melisma (false); + } + } + reqs_drul_[d ] = c; return true; } return false; } +void +Beam_engraver::set_melisma (bool m) +{ + daddy_trans_l_->set_property ("beamMelismaBusy", m ? SCM_BOOL_T :SCM_BOOL_F); +} + void Beam_engraver::do_process_music () @@ -160,6 +178,13 @@ void Beam_engraver::do_post_move_processing () { reqs_drul_ [START] =0; + if(beam_p_) { + SCM m = get_property ("automaticMelismata"); + SCM b = get_property("noAutoBeaming"); + if (to_boolean (m) && to_boolean(b)) { + set_melisma (true); + } + } } void diff --git a/lily/include/lyric-phrasing-engraver.hh b/lily/include/lyric-phrasing-engraver.hh index f5a410308c..75ac186e62 100644 --- a/lily/include/lyric-phrasing-engraver.hh +++ b/lily/include/lyric-phrasing-engraver.hh @@ -70,6 +70,7 @@ protected: private: void record_notehead(const String &context_id, Score_element * notehead); void record_lyric(const String &context_id, Score_element * lyric); + void record_melisma(const String &context_id); Voice_alist_entry * lookup_context_id(const String &context_id); public: @@ -93,17 +94,23 @@ class Voice_alist_entry Score_element * longest_lyric_l_; Score_element * shortest_lyric_l_; int alignment_i_; - + bool melisma_b_; public: static SCM make_entry(); void set_first_in_phrase(bool f); void set_notehead(Score_element * notehead); void add_lyric(Score_element * lyric); + void set_melisma(); + bool get_melisma() { return melisma_b_; } + int lyric_count() { return lyric_list_.size(); } void clear(); bool is_empty(); bool set_lyric_align(const char *punc, Score_element *default_notehead_l); + void adjust_melisma_align(); int appropriate_alignment(const char *punc); + Real amount_to_translate(); void next_lyric(); + void copy(Voice_alist_entry *); private: Voice_alist_entry(); DECLARE_SIMPLE_SMOBS(Voice_alist_entry,); diff --git a/lily/lyric-phrasing-engraver.cc b/lily/lyric-phrasing-engraver.cc index 2b507ea027..af66efdcfa 100644 --- a/lily/lyric-phrasing-engraver.cc +++ b/lily/lyric-phrasing-engraver.cc @@ -17,6 +17,27 @@ String trim_suffix(String &id); ADD_THIS_TRANSLATOR (Lyric_phrasing_engraver); +/* + We find start and end of phrases, and align lyrics accordingly. + Also, lyrics at start of melismata should be left aligned. + + Alignment and melismata + + I've taken [a different] approach: + | | + | | + O O <-- second note throws a melisma score element + \____/ + + ^ ^ + | | + Lyric (None) + + Lyric_phrasing_engraver keeps track of the current and previous notes and + lyrics for each voice, and when it catches a melisma, it adjusts the + alignment of the lyrics of the previous note. I hope this isn't + unnecessarily convoluted. + */ Lyric_phrasing_engraver::Lyric_phrasing_engraver() { @@ -39,17 +60,30 @@ Lyric_phrasing_engraver::lookup_context_id(const String &context_id) SCM s = scm_assoc(key, voice_alist_); if(! (gh_boolean_p(s) && !to_boolean(s))) { /* match found */ - return unsmob_voice_entry(gh_cdr(s)); + // ( key . ( (alist_entry . old_entry) . previous_entry) ) + if(to_boolean(gh_cdadr(s))) { // it's an old entry ... make it a new one + SCM val = gh_cons(gh_cons(gh_caadr(s), SCM_BOOL_F), gh_cddr(s)); + voice_alist_ = scm_assoc_set_x(voice_alist_, gh_car(s), val); + return unsmob_voice_entry (gh_caar(val)); + } + else { // the entry is current ... return it. + SCM entry_scm = gh_caadr(s); + return unsmob_voice_entry(entry_scm); + } } } - SCM val = Voice_alist_entry::make_entry (); + // ( ( alist_entry . old_entry ) . previous_entry ) + SCM val = gh_cons(gh_cons(Voice_alist_entry::make_entry (), SCM_BOOL_F), + Voice_alist_entry::make_entry ()); + voice_alist_ = scm_acons(key, val, voice_alist_); - return unsmob_voice_entry (val); + return unsmob_voice_entry (gh_caar(val)); } void -Lyric_phrasing_engraver::record_notehead(const String &context_id, Score_element * notehead) +Lyric_phrasing_engraver::record_notehead(const String &context_id, + Score_element * notehead) { Voice_alist_entry * v = lookup_context_id(context_id); v->set_notehead(notehead); @@ -64,9 +98,13 @@ Lyric_phrasing_engraver::record_lyric(const String &context_id, Score_element * v->add_lyric(lyric); } - - - +void +Lyric_phrasing_engraver::record_melisma(const String &context_id) +{ + Voice_alist_entry * v = lookup_context_id(context_id); + v->set_melisma(); +} + void Lyric_phrasing_engraver::acknowledge_element(Score_element_info i) { @@ -100,9 +138,14 @@ Lyric_phrasing_engraver::acknowledge_element(Score_element_info i) record_lyric(trim_suffix(lyric_voice_context_id), h); return; } + /* finally for a melisma */ + if(h->has_interface (ly_symbol2scm ("melisma-interface"))) { + String voice_context_id = get_context_id(i.origin_trans_l_->daddy_trans_l_, "Voice"); + record_melisma(voice_context_id); + return; + } } - String get_context_id(Translator_group * ancestor, const char *type) { @@ -133,15 +176,28 @@ void Lyric_phrasing_engraver::process_acknowledged () /* iterate through entries in voice_alist_ for each, call set_lyric_align(alignment). Issue a warning if this returns false. */ - Voice_alist_entry *entry; String punc; SCM sp = get_property("phrasingPunctuation"); punc = gh_string_p(sp) ? ly_scm2string(sp) : ".,;:?!\""; - for(unsigned v=0; v < gh_length(voice_alist_); v++) { - entry = unsmob_voice_entry(gh_cdr(gh_list_ref(voice_alist_, gh_int2scm(v)))); + for(SCM v=voice_alist_; gh_pair_p(v); v = gh_cdr(v)) { + SCM v_entry = gh_cdar(v); + // ((current . oldflag) . previous) + Voice_alist_entry *entry = unsmob_voice_entry(gh_caar(v_entry)); if(! entry->set_lyric_align(punc.ch_C(), any_notehead_l_)) warning (_ ("lyrics found without any matching notehead")); + + // is this note melismatic? If so adjust alignment of previous one. + if(entry->get_melisma()) { + if(entry->lyric_count()) + warning (_ ("Huh? Melismatic note found to have associated lyrics.")); + SCM previous_scm = gh_cdr(v_entry); + if(previous_scm != SCM_EOL) { + Voice_alist_entry *previous = unsmob_voice_entry(previous_scm); + if (previous->lyric_count()) + previous->adjust_melisma_align(); + } + } } } @@ -149,9 +205,19 @@ void Lyric_phrasing_engraver::process_acknowledged () void Lyric_phrasing_engraver::do_pre_move_processing () { - Voice_alist_entry * entry; - for(unsigned v=0; v < gh_length(voice_alist_); v++) { - entry = unsmob_voice_entry(gh_cdr(gh_list_ref(voice_alist_, gh_int2scm(v)))); + for(SCM v=voice_alist_; gh_pair_p(v); v = gh_cdr(v)) { + SCM entry_scm = gh_cdar(v); + // ((alist_entry . entry_is_old) . previous_entry) + Voice_alist_entry * entry = unsmob_voice_entry(gh_caar(entry_scm)); + + // set previous_entry, set entry_is_old, and resave it to alist_ + // but only change if this current was not old. + if(! to_boolean(gh_cdar(entry_scm))) { + Voice_alist_entry * previous_entry = unsmob_voice_entry(gh_cdr(entry_scm)); + previous_entry->copy(entry); + entry_scm = gh_cons(gh_cons(gh_caar(entry_scm), SCM_BOOL_T), gh_cdr(entry_scm)); + voice_alist_ = scm_assoc_set_x(voice_alist_, gh_caar(v), entry_scm); + } entry->next_lyric(); } any_notehead_l_ = 0; @@ -168,12 +234,10 @@ Lyric_phrasing_engraver::do_pre_move_processing () Voice_alist_entry::Voice_alist_entry() { first_in_phrase_b_=true; + melisma_b_ = false; clear(); } - - - void Voice_alist_entry::clear() { @@ -181,8 +245,21 @@ Voice_alist_entry::clear() lyric_list_.clear(); longest_lyric_l_=0; shortest_lyric_l_=0; + melisma_b_ = false; } +void +Voice_alist_entry::copy( Voice_alist_entry *from) +{ + notehead_l_ = from->notehead_l_; + lyric_list_ = from->lyric_list_; + longest_lyric_l_ = from->longest_lyric_l_; + shortest_lyric_l_ = from->shortest_lyric_l_; + melisma_b_ = from->melisma_b_; + alignment_i_ = from->alignment_i_; + first_in_phrase_b_ = from->first_in_phrase_b_; +} + void Voice_alist_entry::set_first_in_phrase(bool f) { @@ -192,9 +269,10 @@ Voice_alist_entry::set_first_in_phrase(bool f) void Voice_alist_entry::set_notehead(Score_element * notehead) { - if(!notehead_l_) + if(!notehead_l_) { /* there should only be a single notehead, so silently ignore any extras */ notehead_l_=notehead; + } } void @@ -211,60 +289,72 @@ Voice_alist_entry::add_lyric(Score_element * lyric) else longest_lyric_l_ = shortest_lyric_l_ = lyric; } - + + void +Voice_alist_entry::set_melisma() +{ + melisma_b_ = true; +} + bool Voice_alist_entry::set_lyric_align(const char *punc, Score_element *default_notehead_l) { - if(lyric_list_.size()<2) { - /* Only for multi-stanza songs ... if we've only a single lyric (or none at all) we - do nothing. - */ - clear(); + if(lyric_list_.size()==0) { + // No lyrics: nothing to do. return true; } Score_element * lyric; alignment_i_ = appropriate_alignment(punc); + // If there was no notehead in the matching voice context, use the first + // notehead caught from any voice context (any port in a storm). + if(!notehead_l_) { + notehead_l_ = default_notehead_l; + } + Real translation = amount_to_translate(); for(int l = 0; l < lyric_list_.size(); l++) { /** set the x alignment of each lyric */ lyric = lyric_list_[l]; lyric->set_elt_property("self-alignment-X", gh_int2scm(alignment_i_)); - // centre on notehead ... if we have one. If there was no notehead in the matching - // voice context, use the first notehead caught from any voice context (any port in a storm). - if(notehead_l_ || default_notehead_l) { + // centre on notehead ... if we have one. + if(notehead_l_) { /* set the parent of each lyric to the notehead, set the offset callback of each lyric to centered_on_parent, */ - Score_element * parent_nh = notehead_l_ ? notehead_l_ : default_notehead_l; - lyric->set_parent(parent_nh, X_AXIS); + lyric->set_parent(notehead_l_, X_AXIS); lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS); - /* reference is on the right of the notehead; move it left half way */ - lyric->translate_axis (-(parent_nh->extent(X_AXIS)).center(), X_AXIS); - - if(alignment_i_ != CENTER) { - // right or left align ... - /* If length of longest lyric < 2 * length of shortest lyric, - - centre longest lyric on notehead - Otherwise - - move so shortest lyric just reaches notehead centre - */ - // FIXME: do we really know the lyric extent here? Some font sizing comes later? - Real translate; - if((longest_lyric_l_->extent(X_AXIS)).length() < - (shortest_lyric_l_->extent(X_AXIS)).length() * 2 ) - translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2; - else - translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length(); - lyric->translate_axis (translate, X_AXIS); - } + /* reference is on the right of the notehead; move it left half way, then centralise */ + lyric->translate_axis (translation-(notehead_l_->extent(X_AXIS)).center(), X_AXIS); } } - return (notehead_l_ || default_notehead_l); + return (notehead_l_); +} + +Real +Voice_alist_entry::amount_to_translate() +{ + Real translate = 0.0; + if(alignment_i_ != CENTER) { + // right or left align ... + /* If length of longest lyric < 2 * length of shortest lyric, + - centre longest lyric on notehead + Otherwise + - move so shortest lyric just reaches notehead centre + */ + // FIXME: do we really know the lyric extent here? Some font sizing comes later? + if((longest_lyric_l_->extent(X_AXIS)).length() < + (shortest_lyric_l_->extent(X_AXIS)).length() * 2 ) + translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2; + else + translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length(); + } + return translate; } + /** determine what alignment we want. Rules: if first_in_phrase_b_ is set, then alignment is LEFT. otherwise if each syllable ends in punctuation, then alignment is RIGHT @@ -317,6 +407,32 @@ Voice_alist_entry::appropriate_alignment(const char *punc) return CENTER; } +/** We don't know about the melisma until after the initial alignment work is done, so go + back and fix the alignment when we DO know. +*/ +void +Voice_alist_entry::adjust_melisma_align() +{ + if(notehead_l_) { + // undo what we did before ... + Real translation = -amount_to_translate(); + // melisma aligning: + switch (alignment_i_) { + // case LEFT: // that's all + case CENTER: // move right so smallest lyric is left-aligned on notehead + translation += (shortest_lyric_l_->extent(X_AXIS)).length()/2; + break; + case RIGHT: // move right so smallest lyric is left-aligned on notehead + translation += (shortest_lyric_l_->extent(X_AXIS)).length(); + break; + } + for(int l = 0; l < lyric_list_.size(); l++) { + lyric_list_[l]->translate_axis (translation, X_AXIS); + } + } +} + + bool Voice_alist_entry::is_empty() { diff --git a/lily/melisma-engraver.cc b/lily/melisma-engraver.cc index f3b96c7fcf..e5f7ada603 100644 --- a/lily/melisma-engraver.cc +++ b/lily/melisma-engraver.cc @@ -9,6 +9,7 @@ #include "engraver.hh" #include "musical-request.hh" +#include "score-element.hh" /** Signal existence of melismas. @@ -30,9 +31,18 @@ Melisma_engraver::do_try_music (Music *m ) SCM plain (get_property ("melismaBusy")); SCM slur (get_property ("slurMelismaBusy")); SCM tie (get_property ("tieMelismaBusy")); - return (to_boolean (plain)) - || (to_boolean (slur)) - || (to_boolean (tie)); + SCM beam (get_property ("beamMelismaBusy")); + + if( (to_boolean (plain)) + || (to_boolean (slur)) + || (to_boolean (tie)) + || (to_boolean (beam))) { + + Score_element * melisma_p = new Score_element (get_property ("basicMelismaProperties")); + announce_element (melisma_p, m); + + return true; + } } return false; } diff --git a/ly/engraver.ly b/ly/engraver.ly index 0ce4a5f879..9167c65804 100644 --- a/ly/engraver.ly +++ b/ly/engraver.ly @@ -733,6 +733,9 @@ ScoreContext = \translator { (break-align-symbol . Clef_item) (visibility-lambda . ,begin-of-line-visible) ) + basicMelismaProperties = #`( + (interfaces . (melisma-interface)) + ) \accepts "Staff"; \accepts "StaffGroup"; diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm index 2d411125e3..4ad037ff7d 100644 --- a/make/out/lilypond.lsm +++ b/make/out/lilypond.lsm @@ -1,15 +1,15 @@ Begin3 Title: LilyPond -Version: 1.3.75 -Entered-date: 25JUL00 +Version: 1.3.76 +Entered-date: 03AUG00 Description: Keywords: music notation typesetting midi fonts engraving Author: hanwen@cs.uu.nl (Han-Wen Nienhuys) janneke@gnu.org (Jan Nieuwenhuizen) Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys) Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert - 1000k lilypond-1.3.75.tar.gz + 1000k lilypond-1.3.76.tar.gz Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/ - 1000k lilypond-1.3.75.tar.gz + 1000k lilypond-1.3.76.tar.gz Copying-policy: GPL End diff --git a/make/out/lilypond.spec b/make/out/lilypond.spec index 647dfb5cc4..5ec5d04954 100644 --- a/make/out/lilypond.spec +++ b/make/out/lilypond.spec @@ -1,9 +1,9 @@ Name: lilypond -Version: 1.3.75 +Version: 1.3.76 Release: 1 Copyright: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.75.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.76.tar.gz Summary: A program for printing sheet music. URL: http://www.cs.uu.nl/~hanwen/lilypond # Icon: lilypond-icon.gif diff --git a/scm/slur.scm b/scm/slur.scm index 8eaafee36a..dadeb3056c 100644 --- a/scm/slur.scm +++ b/scm/slur.scm @@ -25,6 +25,9 @@ (define slur-extremity-rules (list + + ;; (cons (lambda (slur dir) (begin (display "before head") (newline))#f) #f) + (cons (lambda (slur dir) ;; urg, code dup (let* ((note-columns (ly-get-elt-property slur 'note-columns)) @@ -34,6 +37,8 @@ (not (= (ly-get-elt-property slur 'direction) (ly-get-elt-property stem 'direction)))))) 'head) + ;; (cons (lambda (slur dir) (begin (display "before stem") (newline))#f) #f) + (cons (lambda (slur dir) ;; if attached-to-stem (and (attached-to-stem slur dir) @@ -52,7 +57,9 @@ #f)))))) 'stem) + ;;(cons (lambda (slur dir) (begin (display "before loose-end") (newline))#f) #f) (cons (lambda (slur dir) (not (attached-to-stem slur dir))) 'loose-end) + ;; (cons (lambda (slur dir) (begin (display "after loose-end") (newline))#f) #f) ;; default case, attach to head (cons (lambda (x y) #t) 'head) diff --git a/scripts/mudela-book.py b/scripts/mudela-book.py index ca4b70f8ad..d82d949dfe 100644 --- a/scripts/mudela-book.py +++ b/scripts/mudela-book.py @@ -695,7 +695,12 @@ def compile_all_files (chunks): system ('lilypond %s %s' % (lilyopts, texfiles)) for e in eps: - cmd = r"""tex '\nonstopmode \input %s'; dvips -E -o %s %s""" % \ + if os.environ.has_key('OS') and \ + os.environ['OS'] == 'Windows_95': + cmd = r"""ash -c 'tex " \nonstopmode \input %s " ; dvips -E -o %s %s ' """ % \ + (e, e + '.eps', e) + else: + cmd = r"""tex '\nonstopmode \input %s' ; dvips -E -o %s %s""" % \ (e, e + '.eps', e) system (cmd) diff --git a/stepmake/stepmake/metapost-rules.make b/stepmake/stepmake/metapost-rules.make index 34bd4f4b03..6e135ede15 100644 --- a/stepmake/stepmake/metapost-rules.make +++ b/stepmake/stepmake/metapost-rules.make @@ -4,7 +4,7 @@ $(outdir)/%.0: %.mf $(outdir)/mfplain.mem -$(METAPOST) "&$(outdir)/mfplain \mode=lowres; \mag=1.0; nonstopmode; input $<" -mfplain.mem: $(MFPLAIN_MP) +$(outdir)/mfplain.mem: $(MFPLAIN_MP) $(INIMETAPOST) $(INIMETAPOST_FLAGS) $(MFPLAIN_MP) dump mv mfplain.* $(outdir) -- 2.39.5