]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/tie-engraver.cc
Merge branch 'master' into lilypond/translation
[lilypond.git] / lily / tie-engraver.cc
index b13e68050c97f0d2a162a27d6650837f0fd6b6cf..edaba06c7c0720e1dcc35321acf9010cee298226 100644 (file)
@@ -82,6 +82,7 @@ protected:
   void process_music ();
   void typeset_tie (Grob *);
   void report_unterminated_tie (Head_event_tuple const &);
+  bool has_autosplit_end (Stream_event *event);
 public:
   TRANSLATOR_DECLARATIONS (Tie_engraver);
 };
@@ -116,6 +117,18 @@ void Tie_engraver::report_unterminated_tie (Head_event_tuple const &tie_start)
     tie_start.head_->warning (_("unterminated tie"));
 }
 
+/*
+  Determines whether the end of an event was created by
+  a split in Completion_heads_engraver or by user input.
+*/
+bool
+Tie_engraver::has_autosplit_end (Stream_event *event)
+{
+  if (event)
+    return to_boolean (event->get_property ("autosplit-end"));
+  return false;
+}
+
 void
 Tie_engraver::process_music ()
 {
@@ -146,8 +159,12 @@ Tie_engraver::acknowledge_note_head (Grob_info i)
       if (!right_ev || !left_ev)
        continue;
 
-      if (ly_is_equal (right_ev->get_property ("pitch"),
-                      left_ev->get_property ("pitch")))
+      /*
+        Make a tie only if pitches are equal or if event end was not generated by
+        Completion_heads_engraver.
+      */
+      if (ly_is_equal (right_ev->get_property ("pitch"), left_ev->get_property ("pitch"))
+         && (!Tie_engraver::has_autosplit_end (left_ev)))
        {
          Grob *p = new Spanner (heads_to_tie_[i].tie_definition_);
          Moment end = heads_to_tie_[i].end_moment_;
@@ -170,10 +187,12 @@ Tie_engraver::acknowledge_note_head (Grob_info i)
          ties_.push_back (p);
          heads_to_tie_.erase (heads_to_tie_.begin () + i);
 
-         // Prevent all other tied notes ending at the same moment (assume
-         // implicitly the notes have also started at the same moment!)
-         // from triggering an "unterminated tie" warning. Needed e.g. for
-         // <c e g>~ g
+         /*
+           Prevent all other tied notes ending at the same moment (assume
+           implicitly the notes have also started at the same moment!)
+           from triggering an "unterminated tie" warning. Needed e.g. for
+           <c e g>~ g
+         */
          for (vsize j = heads_to_tie_.size (); j--;)
            {
              if (heads_to_tie_[j].end_moment_ == end)
@@ -233,6 +252,12 @@ Tie_engraver::stop_translation_timestep ()
 
   vector<Head_event_tuple> new_heads_to_tie;
 
+  /*
+    Whether tie event has been processed and can be deleted or should
+    be kept for later portions of a split note.
+  */
+  bool event_processed = false;
+
   for (vsize i = 0; i < now_heads_.size (); i++)
     {
       Grob *head = now_heads_[i];
@@ -245,6 +270,9 @@ Tie_engraver::stop_translation_timestep ()
          continue;
        }
 
+      // We only want real notes to cause ties, not e.g. pitched trills
+      if (!left_ev->in_event_class ("note-event"))
+          continue;
 
       SCM left_articulations = left_ev->get_property ("articulations");
 
@@ -262,8 +290,11 @@ Tie_engraver::stop_translation_timestep ()
            tie_event = ev;
        }
 
-      if (left_ev && (tie_event || tie_stream_event))
+      if (left_ev && (tie_event || tie_stream_event)
+         && (!Tie_engraver::has_autosplit_end (left_ev)))
        {
+         event_processed = true;
+
          Head_event_tuple event_tup;
 
          SCM start_definition
@@ -301,7 +332,13 @@ Tie_engraver::stop_translation_timestep ()
   for (vsize i = 0; i < new_heads_to_tie.size (); i++)
     heads_to_tie_.push_back (new_heads_to_tie[i]);
 
-  event_ = 0;
+  /*
+    Discard event only if it has been processed with at least one
+    appropriate note.
+  */
+  if (event_processed)
+    event_ = 0;
+
   now_heads_.clear ();
 }