From: Reinhold Kainhofer Date: Wed, 24 Nov 2010 23:40:17 +0000 (+0100) Subject: PartCombine: part-combine texts on first real note rather than rests X-Git-Tag: release/2.13.41-1~3^2~1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=f0f0f0648b63a1ce156cf9634f043a046384a182;p=lilypond.git PartCombine: part-combine texts on first real note rather than rests -) If the context property partCombineTextsOnNote is set, the part-combine texts are not printed immediately if there is a rest or skip, but on the next following note. If the voice contains a note, they are printed immediately. This is needed if one voice has a full measure rest and the other e.g. r2 r4 c4. -) The event triggering the part-combine text is cached in that case and the Part_combine_engraver now also listens to note events. The texts are then created at the first moment when a note is encountered. --- diff --git a/input/regression/part-combine-text-wait.ly b/input/regression/part-combine-text-wait.ly new file mode 100644 index 0000000000..73260661a1 --- /dev/null +++ b/input/regression/part-combine-text-wait.ly @@ -0,0 +1,26 @@ +\version "2.13.41" + + +\header { + texidoc ="Wait for the next real note for part-combine texts (i.e. don't +print part-combine texts on rests). This is needed because the part-combiner +needs an override if one voice has a full-bar rest while the other has some +rests and then a solo." +} + +\layout { ragged-right = ##t } + +mI = \relative c'' { + \set Score.partCombineTextsOnNote = ##t + g4 \partcombineSoloI r4 c2 | + \partcombineSoloII R1*2 | +} +mII = \relative c' { + c4 r2. | + r2 r4 c4 | + R1 | +} + +\score { + \new Staff \partcombine \mI \mII +} diff --git a/lily/part-combine-engraver.cc b/lily/part-combine-engraver.cc index bbc0d059e5..59a818952c 100644 --- a/lily/part-combine-engraver.cc +++ b/lily/part-combine-engraver.cc @@ -38,46 +38,74 @@ protected: DECLARE_ACKNOWLEDGER (stem); DECLARE_TRANSLATOR_LISTENER (part_combine); + DECLARE_TRANSLATOR_LISTENER (note); void process_music (); void stop_translation_timestep (); + void create_item (Stream_event *ev); + private: Item *text_; - Stream_event *event_; + Stream_event *new_event_; // Event happened at this moment + bool note_found_; + // Event possibly from an earlier moment waiting to create a text: + Stream_event *waiting_event_; }; IMPLEMENT_TRANSLATOR_LISTENER (Part_combine_engraver, part_combine); void Part_combine_engraver::listen_part_combine (Stream_event *ev) { - ASSIGN_EVENT_ONCE (event_, ev); + ASSIGN_EVENT_ONCE (new_event_, ev); + // If two events occur at the same moment, discard the second as the + // warning indicates: + waiting_event_ = new_event_; +} + +IMPLEMENT_TRANSLATOR_LISTENER (Part_combine_engraver, note); +void +Part_combine_engraver::listen_note (Stream_event *) +{ + note_found_ = true; } Part_combine_engraver::Part_combine_engraver () { text_ = 0; - event_ = 0; + new_event_ = 0; + waiting_event_ = 0; + note_found_ = false; +} + +void +Part_combine_engraver::create_item (Stream_event *ev) +{ + SCM what = ev->get_property ("class"); + SCM text = SCM_EOL; + if (what == ly_symbol2scm ("solo-one-event")) + text = get_property ("soloText"); + else if (what == ly_symbol2scm ("solo-two-event")) + text = get_property ("soloIIText"); + else if (what == ly_symbol2scm ("unisono-event")) + text = get_property ("aDueText"); + + if (Text_interface::is_markup (text)) + { + text_ = make_item ("CombineTextScript", ev->self_scm ()); + text_->set_property ("text", text); + } } void Part_combine_engraver::process_music () { - if (event_ + if (waiting_event_ && to_boolean (get_property ("printPartCombineTexts"))) { - SCM what = event_->get_property ("class"); - SCM text = SCM_EOL; - if (what == ly_symbol2scm ("solo-one-event")) - text = get_property ("soloText"); - else if (what == ly_symbol2scm ("solo-two-event")) - text = get_property ("soloIIText"); - else if (what == ly_symbol2scm ("unisono-event")) - text = get_property ("aDueText"); - - if (Text_interface::is_markup (text)) - { - text_ = make_item ("CombineTextScript", event_->self_scm ()); - text_->set_property ("text", text); - } + if (note_found_ || !to_boolean (get_property ("partCombineTextsOnNote"))) + { + create_item (waiting_event_); + waiting_event_ = 0; + } } } @@ -105,7 +133,8 @@ void Part_combine_engraver::stop_translation_timestep () { text_ = 0; - event_ = 0; + new_event_ = 0; + note_found_ = false; } ADD_ACKNOWLEDGER (Part_combine_engraver, note_head); @@ -120,6 +149,7 @@ ADD_TRANSLATOR (Part_combine_engraver, /* read */ "printPartCombineTexts " + "partCombineTextsOnNote " "soloText " "soloIIText " "aDueText ", diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 515c1cd3bb..f2ca7c3e46 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -531,6 +531,7 @@ automatically when an output definition (a @code{\score} or soloIIText = #"Solo II" aDueText = #"a2" printPartCombineTexts = ##t + partCombineTextsOnNote = ##t systemStartDelimiter =#'SystemStartBar drumStyleTable = #drums-style diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 4a2a6736f2..8a22e2d36a 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -361,6 +361,8 @@ Changing this creates a new text spanner.") translator during music interpretation.") + (partCombineTextsOnNote ,boolean? "Print part-combine texts only on +the next note rather than immediately on rests or skips.") (pedalSostenutoStrings ,list? "See @code{pedalSustainStrings}.") (pedalSostenutoStyle ,symbol? "See @code{pedalSustainStyle}.") (pedalSustainStrings ,list? "A list of strings to print for