From: Glen Prideaux Date: Sun, 6 Aug 2000 22:19:35 +0000 (+0200) Subject: patch::: 1.3.76.gp1 X-Git-Tag: release/1.3.77~3 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=7b4fd379bc68c234e217e7e17dac7b40cfcf7a57;p=lilypond.git patch::: 1.3.76.gp1 1.3.76.gp1 ========== * Lyric_phrasing_engraver now catches lyric extenders and correctly terminates them under the last note of a melisma. * Lyric word spacing code changed to fix hyphen alignment. * Other minor tidying up of Lyric_phrasing_engraver and related code. --- Generated by (address unknown), From = lilypond-1.3.76, To = lilypond-1.3.76.gp1 usage cd lilypond-source-dir; patch -E -p1 < lilypond-1.3.76.gp1.diff Patches do not contain automatically generated files or (urg) empty directories, i.e., you should rerun autoconf, configure --- diff --git a/CHANGES b/CHANGES index 1a35d304ec..47a194e261 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,18 @@ -1.3.76 +--- ../lilypond-1.3.76/CHANGES Fri Aug 4 02:29:02 2000 +++ b/CHANGES Mon Aug 7 00:19:35 2000 +@@ -1,3 +1,12 @@ +1.3.76.gp1 +========== +* Lyric_phrasing_engraver now catches lyric extenders and correctly + terminates them under the last note of a melisma. + +* Lyric word spacing code changed to fix hyphen alignment. + +* Other minor tidying up of Lyric_phrasing_engraver and related code. + + 1.3.76 + ====== + 1.3.76 ====== * Lyric_phrasing_engraver now adjusts for melisma. (Glenn Prideaux). diff --git a/VERSION b/VERSION index 2646ad5419..ea1210f086 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=76 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=gp1 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/star-spangled-banner.ly b/input/star-spangled-banner.ly index 1bb791a165..f847471cbf 100644 --- a/input/star-spangled-banner.ly +++ b/input/star-spangled-banner.ly @@ -106,23 +106,24 @@ text = \lyrics { Oh __ \repeat "fold" 2 { } \alternative { { - say, can you | see, by the dawn's ear- ly light - What so proud- ly we hailed, - At the twi- light's last gleam- ing. + say, can you | see, by the dawn's ear -- ly light + What so proud -- ly we hailed, + At the twi -- light's last gleam -- ing. % Ah, it seems that this context stops to exist just before % the :| barline is set, and doesn't see its width? % Ugly fix: Whose broad \bar "|."; } + \context LyricVoice = "one-2" { - stripes and bright stars, through the per- il- ous fight, - O'er the ram- parts we watched, were so gal- lant- ly + stripes and bright stars, through the per -- il -- ous fight, + O'er the ram -- parts we watched, were so gal -- lant -- ly " " " " " " " "% UGH UGH UGH - stream- ing + stream -- ing - And the rock- ets' red glare, the bombs burst- ing in air, + And the rock -- ets' red glare, the bombs burst -- ing in air, gave proof through the night that our flag was still there, - Oh say, does that star- span- gled ban- ner yet wave, __ + Oh say, does that star -- span -- gled ban -- ner yet wave, __ O'er the land __ of the free and the home of the brave. } } @@ -147,7 +148,7 @@ text = \lyrics { \$staff1_voice_2 } > - \context LyricVoice \text + \context LyricVoice = "one-1" \text \context Staff=lower < \global \clef bass; @@ -170,10 +171,11 @@ text = \lyrics { \GrandStaffContext \accepts "Lyrics"; } - \translator { - \LyricsContext - \consists "Span_bar_engraver"; - } +% We have a Span_bar_engraver in GrandStaff; we only get grief if we add it here too. +% \translator { +% \LyricsContext +% \consists "Span_bar_engraver"; +% } \translator { \LyricsVoiceContext \consists "Bar_engraver"; diff --git a/input/test/lyric-phrasing.ly b/input/test/lyric-phrasing.ly index 2edfa2dbeb..cdd198c6fc 100644 --- a/input/test/lyric-phrasing.ly +++ b/input/test/lyric-phrasing.ly @@ -38,11 +38,6 @@ textIII = \lyrics { la -- da __ doo dah; dargh la dargh loo. } > \paper { - \translator { - \ScoreContext - \consists "Lyric_phrasing_engraver"; - automaticPhrasing = ##t; - } } } \ No newline at end of file diff --git a/input/test/lyric-phrasing.ly.orig b/input/test/lyric-phrasing.ly.orig new file mode 100644 index 0000000000..2edfa2dbeb --- /dev/null +++ b/input/test/lyric-phrasing.ly.orig @@ -0,0 +1,48 @@ +\header{ +filename = "twinkle-pop.ly"; +%title = "Ah, vous dirais-je, maman "; +description = "twinkle twinkle in pop-song-settings"; +composer = "traditional"; +enteredby = "HWN, chords by Johan Vromans"; +copyright = "public domain"; +} + +\version "1.3.59"; + +m =\notes \relative c'' { + \property Staff.automaticMelismata = ##t + \autoBeamOff + g4 r8 \times 2/3 { g'8( f )e } r8 \grace { [d16 c b] } e4 + \emptyText + d8.^"melisma" \melisma c16 + \melismaEnd + b c d e } + +textI = \lyrics { la4 __ la -- la I, la dargh la dargh. } +textII = \lyrics { dar -- dargh __ dargh dargh; dargh la dargh loo. } +textIII = \lyrics { la -- da __ doo dah; dargh la dargh loo. } + +\score { + + \notes < \context Staff = SA \context Voice = VA { s1 } + \context LyricVoice = "VA-1" { s1 } + \context LyricVoice = "VA-2" { s1 } + + \addlyrics + \context Staff = SA \m + < \context LyricVoice = "VA-1" \textI + \context LyricVoice = "VA-2" \textII + \context LyricVoice = "VA-3" \textIII + > + + > + + \paper { + \translator { + \ScoreContext + \consists "Lyric_phrasing_engraver"; + automaticPhrasing = ##t; + } + } + +} \ No newline at end of file diff --git a/lily/hyphen-spanner.cc b/lily/hyphen-spanner.cc index f21eda6045..50259cc314 100644 --- a/lily/hyphen-spanner.cc +++ b/lily/hyphen-spanner.cc @@ -49,9 +49,14 @@ Hyphen_spanner::brew_molecule (SCM smob) Real th = gh_scm2double (sp->get_elt_property ("thickness")) * lt ; Real h = gh_scm2double (sp->get_elt_property ("height")) * ss; Real l = gh_scm2double (sp->get_elt_property ("minimum-length")) * ss; + // The hyphen can exist in the word space of the left lyric ... + SCM space = sp->get_bound (LEFT)->get_elt_property ("word-space"); + if (gh_number_p (space)) + { + bounds[LEFT] -= gh_scm2double (space)*ss; + } Real w = bounds.length (); - /* First try: just make the hyphen take 1/3 of the available space - for length, use a geometric mean of the available space and some minimum + /* for length, use a geometric mean of the available space and some minimum */ if(l < w) l = sqrt(l*w); diff --git a/lily/include/lyric-phrasing-engraver.hh b/lily/include/lyric-phrasing-engraver.hh index 75ac186e62..44263b4ca4 100644 --- a/lily/include/lyric-phrasing-engraver.hh +++ b/lily/include/lyric-phrasing-engraver.hh @@ -71,6 +71,7 @@ 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); + void record_extender(const String &context_id, Score_element * extender); Voice_alist_entry * lookup_context_id(const String &context_id); public: @@ -91,6 +92,7 @@ class Voice_alist_entry bool first_in_phrase_b_; Score_element * notehead_l_; Link_array lyric_list_; +// Link_array extender_list_; Score_element * longest_lyric_l_; Score_element * shortest_lyric_l_; int alignment_i_; @@ -100,6 +102,9 @@ public: void set_first_in_phrase(bool f); void set_notehead(Score_element * notehead); void add_lyric(Score_element * lyric); + void add_extender(Score_element * extender); +// void terminate_extenders(); +// void clear_extenders(); void set_melisma(); bool get_melisma() { return melisma_b_; } int lyric_count() { return lyric_list_.size(); } diff --git a/lily/lyric-engraver.cc b/lily/lyric-engraver.cc index 3108ca01a4..e31edb6950 100644 --- a/lily/lyric-engraver.cc +++ b/lily/lyric-engraver.cc @@ -44,7 +44,8 @@ Lyric_engraver::do_process_music() text_p_= new Item (get_property ("basicLyricTextProperties")); text_p_->set_elt_property ("text", - ly_str02scm ((req_l_->text_str_ + " ").ch_C ())); +// ly_str02scm ((req_l_->text_str_ + " ").ch_C ())); + ly_str02scm ((req_l_->text_str_).ch_C ())); text_p_->add_offset_callback (&Side_position::aligned_on_self,X_AXIS); /* diff --git a/lily/lyric-extender.cc b/lily/lyric-extender.cc index f5209e36aa..43230acfc6 100644 --- a/lily/lyric-extender.cc +++ b/lily/lyric-extender.cc @@ -24,7 +24,18 @@ Lyric_extender::brew_molecule (SCM smob) Real leftext = sp->get_bound (LEFT)->extent (X_AXIS).length (); Real ss = sp->paper_l ()->get_var ("staffspace"); - Real w = sp->spanner_length () - leftext - ss/2; + Real righttrim = 0.5; // default to half a staffspace gap on the right + SCM righttrim_scm = sp->get_elt_property("right-trim-amount"); + if (gh_number_p (righttrim_scm)) { + righttrim = gh_scm2double (righttrim_scm); + } + // The extender can exist in the word space of the left lyric ... + SCM space = sp->get_bound (LEFT)->get_elt_property ("word-space"); + if (gh_number_p (space)) + { + leftext -= gh_scm2double (space)*ss; + } + Real w = sp->spanner_length () - leftext - righttrim*ss; Real h = sp->paper_l ()->get_var ("extender_height"); Molecule mol (sp->lookup_l ()->filledbox ( Box (Interval (0,w), Interval (0,h)))); diff --git a/lily/lyric-phrasing-engraver.cc b/lily/lyric-phrasing-engraver.cc index af66efdcfa..f8e74fce9d 100644 --- a/lily/lyric-phrasing-engraver.cc +++ b/lily/lyric-phrasing-engraver.cc @@ -11,6 +11,8 @@ #include "note-head.hh" #include "translator-group.hh" #include "side-position-interface.hh" +#include "spanner.hh" +#include "paper-def.hh" String get_context_id(Translator_group * ancestor, const char * type); String trim_suffix(String &id); @@ -98,6 +100,24 @@ Lyric_phrasing_engraver::record_lyric(const String &context_id, Score_element * v->add_lyric(lyric); } +void +Lyric_phrasing_engraver::record_extender(const String &context_id, Score_element * extender) +{ + SCM key = ly_str02scm(context_id.ch_C()); + if( ! gh_null_p(voice_alist_) ) { + SCM s = scm_assoc(key, voice_alist_); + if(! (gh_boolean_p(s) && !to_boolean(s))) { + /* match found */ + // ( key . ( (alist_entry . old_entry) . previous_entry) ) + SCM previous_scm = gh_cddr(s); + if(previous_scm != SCM_EOL) { + Voice_alist_entry * v = unsmob_voice_entry(previous_scm); + v->add_extender(extender); + } + } + } +} + void Lyric_phrasing_engraver::record_melisma(const String &context_id) { @@ -144,6 +164,24 @@ Lyric_phrasing_engraver::acknowledge_element(Score_element_info i) record_melisma(voice_context_id); return; } + /* How about catching any extender items and then if we have a melisma, + set the RIGHT item of the extender spanner to the melismatic note in + the corresponding context (if any). + This has the effect of finishing the extender under the last note + of the melisma, instead of extending it to the next lyric. + + Problem: the extender request is thrown at the same moment as the next lyric, + by which time we have already passed the last note of the melisma. + However, the Lyric_phrasing_engraver remembers the last note, so just + attach it to that, provided it was melismatic. If it was not melismatic, + then ignore it and let the Extender_engraver take care of it (i.e. finish at next + lyric). + */ + if(h->has_interface (ly_symbol2scm ("lyric-extender-interface"))) { + String voice_context_id = get_context_id(i.origin_trans_l_->daddy_trans_l_, "LyricVoice"); + record_extender(trim_suffix(voice_context_id), h); + return; + } } String @@ -183,19 +221,21 @@ void Lyric_phrasing_engraver::process_acknowledged () 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(); + if(!to_boolean(gh_cdar(v_entry))) { // not an old entry left over from a prior note ... + 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(); + } } } } @@ -290,7 +330,25 @@ Voice_alist_entry::add_lyric(Score_element * lyric) longest_lyric_l_ = shortest_lyric_l_ = lyric; } - void +void +Voice_alist_entry::add_extender(Score_element * extender) +{ + if(notehead_l_ && melisma_b_) { + dynamic_cast(extender)->set_bound (RIGHT, notehead_l_); + // should the extender finish at the right of the last note of the melisma, or the left? + // Comments in lyric-extender.hh say left, but right looks better to me. GP. + + // Left: +// extender->set_elt_property("right-trim-amount", gh_double2scm(0.0)); + + // Right: + Real ss = extender->paper_l ()->get_var ("staffspace"); + extender->set_elt_property("right-trim-amount", + gh_double2scm(-notehead_l_->extent(X_AXIS).length()/ss)); + } +} + +void Voice_alist_entry::set_melisma() { melisma_b_ = true; @@ -375,9 +433,8 @@ Voice_alist_entry::appropriate_alignment(const char *punc) SCM lyric_scm = lyric->get_elt_property("text"); String lyric_str = gh_string_p(lyric_scm)?ly_scm2string(lyric_scm):""; char lastchar; - if(lyric_str.length_i()>1) { - lastchar = lyric_str[lyric_str.length_i()-2]; - /* We look at the second last character, because lily always appends a space. */ + if(lyric_str.length_i()>0) { + lastchar = lyric_str[lyric_str.length_i()-1]; /* If it doesn't end in punctuation then it ain't an end of phrase */ if(! strchr(punc, lastchar)) { /* Special case: trailing space. Here examine the previous character and reverse the @@ -390,8 +447,8 @@ Voice_alist_entry::appropriate_alignment(const char *punc) FIXME: The extra space throws alignment out a bit. */ if(lastchar == ' ') { - if(lyric_str.length_i()>2) { - lastchar = lyric_str[lyric_str.length_i()-3]; + if(lyric_str.length_i()>1) { + lastchar = lyric_str[lyric_str.length_i()-2]; if(strchr(punc, lastchar)) end_phrase=false; } diff --git a/ly/engraver.ly b/ly/engraver.ly index 9167c65804..790704c229 100644 --- a/ly/engraver.ly +++ b/ly/engraver.ly @@ -539,11 +539,14 @@ ScoreContext = \translator { ) basicLyricExtenderProperties = #`( (molecule-callback . ,Lyric_extender::brew_molecule) + (right-trim-amount . 0.5) + (interfaces . (lyric-extender-interface)) ) basicLyricTextProperties = #`( (molecule-callback . ,Text_item::brew_molecule) (self-alignment-X . 0) (non-rhythmic . #t) + (word-space . 0.6) (interfaces . (lyric-syllable-interface text-item-interface)) ) basicMarkProperties = #`( @@ -552,6 +555,9 @@ ScoreContext = \translator { (interfaces . (mark-interface)) (visibility-lambda . ,end-of-line-invisible) ) + basicMelismaProperties = #`( + (interfaces . (melisma-interface)) + ) basicMultiMeasureRestProperties = #`( (spacing-procedure . ,Multi_measure_rest::set_spacing_rods) (molecule-callback . ,Multi_measure_rest::brew_molecule) @@ -637,12 +643,32 @@ ScoreContext = \translator { (thick-thickness . 6.0) (interfaces . (bar-interface span-bar-interface)) ) + basicStanzaNumberProperties = #`( + (breakable . #t) + (molecule-callback . ,Text_item::brew_molecule) + (break-align-symbol . Clef_item) + (visibility-lambda . ,begin-of-line-visible) + ) + basicStemProperties = #`( + (before-line-breaking-callback . ,Stem::before_line_breaking) + (molecule-callback . ,Stem::brew_molecule) + + ; if stem is on middle line, choose this direction. + (default-neutral-direction . 1) + (interfaces . (stem-interface)) + ) basicSustainPedalProperties = #`( (no-spacing-rods . #t) (molecule-callback . ,Sustain_pedal::brew_molecule) (self-alignment-X . 0) (interface . (sustain-pedal-interface)) ) + staffSymbolBasicProperties = #`( + (molecule-callback . ,Staff_symbol::brew_molecule) + (staff-space . 1.0) + (line-count . 5 ) + (interfaces . (staff-symbol-interface )) + ) basicSystemStartDelimiterProperties = #`( (molecule-callback . ,System_start_delimiter::brew_molecule) (after-line-breaking-callback . ,System_start_delimiter::after_line_breaking) @@ -655,20 +681,6 @@ ScoreContext = \translator { (bracket-thick . 0.25) (bracket-width . 2.0) ) - basicStemProperties = #`( - (before-line-breaking-callback . ,Stem::before_line_breaking) - (molecule-callback . ,Stem::brew_molecule) - - ; if stem is on middle line, choose this direction. - (default-neutral-direction . 1) - (interfaces . (stem-interface)) - ) - staffSymbolBasicProperties = #`( - (molecule-callback . ,Staff_symbol::brew_molecule) - (staff-space . 1.0) - (line-count . 5 ) - (interfaces . (staff-symbol-interface )) - ) basicTextScriptProperties = #`( (molecule-callback . ,Text_item::brew_molecule) (no-spacing-rods . #t) @@ -727,15 +739,6 @@ ScoreContext = \translator { (molecule-callback . ,Volta_spanner::brew_molecule) (interfaces . (volta-spanner-interface)) ) - basicStanzaNumberProperties = #`( - (breakable . #t) - (molecule-callback . ,Text_item::brew_molecule) - (break-align-symbol . Clef_item) - (visibility-lambda . ,begin-of-line-visible) - ) - basicMelismaProperties = #`( - (interfaces . (melisma-interface)) - ) \accepts "Staff"; \accepts "StaffGroup";