/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 1998--2014 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 1998--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#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"
Stream_event *event_;
vector<Grob *> now_heads_;
vector<Head_event_tuple> heads_to_tie_;
- vector<Grob *> ties_;
+ vector<Spanner *> ties_;
Spanner *tie_column_;
+ bool tie_notehead (Grob *h, bool enharmonic);
protected:
void process_acknowledged ();
DECLARE_ACKNOWLEDGER (note_head);
DECLARE_TRANSLATOR_LISTENER (tie);
void process_music ();
- void typeset_tie (Grob *);
+ void typeset_tie (Spanner *);
void report_unterminated_tie (Head_event_tuple const &);
bool has_autosplit_end (Stream_event *event);
public:
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 = heads_to_tie_.size (); i--;)
+ for (vsize i = 0; i < heads_to_tie_.size (); i++)
{
Grob *th = heads_to_tie_[i].head_;
- Stream_event *right_ev = unsmob_stream_event (h->get_property ("cause"));
- Stream_event *left_ev = unsmob_stream_event (th->get_property ("cause"));
+ Stream_event *right_ev = unsmob<Stream_event> (h->get_property ("cause"));
+ Stream_event *left_ev = unsmob<Stream_event> (th->get_property ("cause"));
/*
maybe should check positions too.
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
+ ? (unsmob<Pitch> (p1) && unsmob<Pitch> (p2) &&
+ unsmob<Pitch> (p1)->tone_pitch () == unsmob<Pitch> (p2)->tone_pitch ())
+ : ly_is_equal (p1, p2))
&& (!Tie_engraver::has_autosplit_end (left_ev)))
{
- Grob *p = heads_to_tie_[i].tie_;
+ Spanner *p = heads_to_tie_[i].tie_;
Moment end = heads_to_tie_[i].end_moment_;
Stream_event *cause = heads_to_tie_[i].tie_event_
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!)
if (heads_to_tie_[j].end_moment_ == end)
heads_to_tie_[j].tie_from_chord_created = true;
}
+ 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 ());
if (tie_column_)
- for (vsize i = ties_.size (); i--;)
+ for (vsize i = 0; i < ties_.size (); i++)
Tie_column::add_tie (tie_column_, ties_[i]);
}
{
Grob *head = now_heads_[i];
Stream_event *left_ev
- = unsmob_stream_event (head->get_property ("cause"));
+ = unsmob<Stream_event> (head->get_property ("cause"));
if (!left_ev)
{
!tie_event && !tie_stream_event && scm_is_pair (s);
s = scm_cdr (s))
{
- Stream_event *ev = unsmob_stream_event (scm_car (s));
+ Stream_event *ev = unsmob<Stream_event> (scm_car (s));
if (!ev)
continue;
}
void
-Tie_engraver::typeset_tie (Grob *her)
+Tie_engraver::typeset_tie (Spanner *her)
{
- if (! (Tie::head (her, LEFT) && Tie::head (her, RIGHT)))
- warning (_ ("lonely tie"));
+ Grob *left_head = Tie::head (her, LEFT);
+ Grob *right_head = Tie::head (her, RIGHT);
- Drul_array<Grob *> new_head_drul;
- new_head_drul[LEFT] = Tie::head (her, LEFT);
- new_head_drul[RIGHT] = Tie::head (her, RIGHT);
- for (LEFT_and_RIGHT (d))
+ if (!left_head || !right_head)
{
- if (!Tie::head (her, d))
- new_head_drul[d] = Tie::head (her, (Direction) - d);
+ warning (_ ("lonely tie"));
+ if (!left_head)
+ left_head = right_head;
+ else
+ right_head = left_head;
}
- Spanner *sp = dynamic_cast<Spanner *> (her);
- sp->set_bound (LEFT, new_head_drul[LEFT]);
- sp->set_bound (RIGHT, new_head_drul[RIGHT]);
+ her->set_bound (LEFT, left_head);
+ her->set_bound (RIGHT, right_head);
}
ADD_ACKNOWLEDGER (Tie_engraver, note_head);