diff options
author | Karin Hoethker <karin.hoethker@googlemail.com> | 2011-05-25 13:38:29 +0200 |
---|---|---|
committer | Graham Percival <graham@percival-music.ca> | 2011-06-15 13:38:40 +0100 |
commit | 258dd9a854b627b533ab709a137b23c539857838 (patch) | |
tree | d0e1eb6768a5f00e58b0dd1849746894e1f1582e /lily/tie-engraver.cc | |
parent | acf493b9f41e07d61ef79a7a354d4bf77fb1690d (diff) |
Remove duplicate ties for chords autosplit (1630)
Diffstat (limited to 'lily/tie-engraver.cc')
-rw-r--r-- | lily/tie-engraver.cc | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index b13e68050c..d7fb39db74 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -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]; @@ -262,8 +287,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 +329,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 (); } |