]> git.donarmstrong.com Git - lilypond.git/commitdiff
PartCombine: part-combine texts on first real note rather than rests
authorReinhold Kainhofer <reinhold@kainhofer.com>
Wed, 24 Nov 2010 23:40:17 +0000 (00:40 +0100)
committerReinhold Kainhofer <reinhold@kainhofer.com>
Fri, 26 Nov 2010 15:22:48 +0000 (16:22 +0100)
-) 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.

input/regression/part-combine-text-wait.ly [new file with mode: 0644]
lily/part-combine-engraver.cc
ly/engraver-init.ly
scm/define-context-properties.scm

diff --git a/input/regression/part-combine-text-wait.ly b/input/regression/part-combine-text-wait.ly
new file mode 100644 (file)
index 0000000..7326066
--- /dev/null
@@ -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
+}
index bbc0d059e5a7ccd432cbdc78879d0f208f12fc95..59a818952ce412f989fa5504e0b884825c584875 100644 (file)
@@ -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 ",
index 515c1cd3bb887446b347956a3177547313102e65..f2ca7c3e464757b010b22b5aa893aabcfbca46f9 100644 (file)
@@ -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
index 4a2a6736f2c7b4d7be560ca6225507fcb2df6e29..8a22e2d36aba5e38cf7feab807d8487a77f9e96e 100644 (file)
@@ -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