for (vsize j = ties_.size (); j--;)
{
Grob *r = Tie::head (ties_[j], RIGHT);
+ Grob *l = Tie::head (ties_[j], LEFT);
+ if (l && r)
+ {
+ // Don't mark accidentals as "tied" when the pitch is not
+ // actually the same. This is relevant for enharmonic ties.
+ Stream_event *le = Stream_event::unsmob (l->get_property ("cause"));
+ Stream_event *re = Stream_event::unsmob (r->get_property ("cause"));
+ if (le && re
+ && !ly_is_equal (le->get_property ("pitch"), re->get_property ("pitch")))
+ continue;
+ }
+
for (vsize i = accidentals_.size (); i--;)
if (accidentals_[i].head_ == r)
{
#include "international.hh"
#include "item.hh"
#include "note-head.hh"
+#include "pitch.hh"
#include "protected-scm.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
vector<Grob *> ties_;
Spanner *tie_column_;
+ bool tie_notehead (Grob *h, bool enharmonic);
protected:
void process_acknowledged ();
context ()->set_property ("tieMelismaBusy", SCM_BOOL_T);
}
-void
-Tie_engraver::acknowledge_note_head (Grob_info i)
+bool
+Tie_engraver::tie_notehead (Grob *h, bool enharmonic)
{
- Grob *h = i.grob ();
+ bool found = false;
- now_heads_.push_back (h);
for (vsize i = 0; i < heads_to_tie_.size (); i++)
{
Grob *th = heads_to_tie_[i].head_;
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"))
+ SCM p1 = left_ev->get_property ("pitch");
+ SCM p2 = right_ev->get_property ("pitch");
+ if ((enharmonic
+ ? (Pitch::is_smob (p1) && Pitch::is_smob (p2) &&
+ Pitch::unsmob (p1)->tone_pitch () == Pitch::unsmob (p2)->tone_pitch ())
+ : ly_is_equal (p1, p2))
&& (!Tie_engraver::has_autosplit_end (left_ev)))
{
Grob *p = heads_to_tie_[i].tie_;
ties_.push_back (p);
heads_to_tie_.erase (heads_to_tie_.begin () + i);
+ found = true;
/*
Prevent all other tied notes ending at the same moment (assume
implicitly the notes have also started at the same moment!)
break;
}
}
+ return found;
+}
+
+void
+Tie_engraver::acknowledge_note_head (Grob_info i)
+{
+ Grob *h = i.grob ();
+
+ now_heads_.push_back (h);
+
+ if (!tie_notehead (h, false))
+ tie_notehead (h, true);
if (ties_.size () && ! tie_column_)
tie_column_ = make_spanner ("TieColumn", ties_[0]->self_scm ());
it = heads_to_tie_.erase (it);
}
}
+ if (found)
+ return;
+ for (it = heads_to_tie_.begin ();
+ !found && (it != heads_to_tie_.end ());
+ it++)
+ {
+ Audio_element_info et = (*it).head_;
+ Audio_note *th = dynamic_cast<Audio_note *> (et.elem_);
+ Stream_event *left_mus = et.event_;
+
+ if (!(th && right_mus && left_mus))
+ continue;
+
+ SCM p1 = left_mus->get_property ("pitch");
+ SCM p2 = right_mus->get_property ("pitch");
+ if (Pitch::is_smob (p1) && Pitch::is_smob (p2)
+ && Pitch::unsmob (p1)->tone_pitch () == Pitch::unsmob (p2)->tone_pitch ())
+ {
+ found = true;
+ // (*it).moment_ already stores the end of the tied note!
+ Moment skip = now_mom () - (*it).end_moment_;
+ an->tie_to (th, skip);
+ it = heads_to_tie_.erase (it);
+ }
+ }
}
}