summaryrefslogtreecommitdiff
path: root/lily/tie-engraver.cc
diff options
context:
space:
mode:
authorKarin Hoethker <karin.hoethker@googlemail.com>2011-05-25 13:38:29 +0200
committerGraham Percival <graham@percival-music.ca>2011-06-15 13:38:40 +0100
commit258dd9a854b627b533ab709a137b23c539857838 (patch)
treed0e1eb6768a5f00e58b0dd1849746894e1f1582e /lily/tie-engraver.cc
parentacf493b9f41e07d61ef79a7a354d4bf77fb1690d (diff)
Remove duplicate ties for chords autosplit (1630)
Diffstat (limited to 'lily/tie-engraver.cc')
-rw-r--r--lily/tie-engraver.cc50
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 ();
}