Both are Grobs, but ties are Spanners and semi-ties are Items.
vector<Item *> notes_;
vector<Item *> prev_notes_;
// Must remember notes for explicit ties.
- vector<Grob *> ties_;
+ vector<Spanner *> ties_;
vector<Stream_event *> note_events_;
Spanner *tie_column_;
Moment note_end_mom_;
void
Completion_heads_engraver::make_tie (Grob *left, Grob *right)
{
- Grob *p = make_spanner ("Tie", SCM_EOL);
+ Spanner *p = make_spanner ("Tie", SCM_EOL);
Tie::set_head (p, LEFT, left);
Tie::set_head (p, RIGHT, right);
announce_end_grob (p, SCM_EOL);
DECLARE_SCHEME_CALLBACK (calc_control_points, (SCM));
static bool less (Grob *const &s1,
Grob *const &s2);
- static int get_position (Grob *);
+ static int get_column_rank (Item *);
+ static int get_position (Item *);
+ static Item *head (Item *);
+ // return the head if it is present on the given side
+ static Item *head (Item *, Direction d);
};
#endif /* SEMI_TIE_HH */
{
public:
DECLARE_GROB_INTERFACE ();
- static void add_tie (Grob *me, Grob *);
+ static void add_tie (Grob *me, Spanner *);
DECLARE_SCHEME_CALLBACK (calc_positioning_done, (SCM));
DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM));
static void set_directions (Grob *me);
class Tie
{
public:
- static void set_head (Grob *, Direction, Grob *head);
+ static void set_head (Spanner *, Direction, Grob *head);
DECLARE_GROB_INTERFACE ();
- static Grob *head (Grob *, Direction);
- static int get_column_rank (Grob *, Direction);
- static int get_position (Grob *);
+ static Item *head (Spanner *, Direction);
+ static int get_column_rank (Spanner *, Direction);
+ static int get_position (Spanner *);
+ static int get_position_generic (Grob *);
static Direction get_default_dir (Grob *);
static SCM get_control_points (Grob *, Grob *,
Tie_configuration const &,
Tie_details const &);
- static SCM get_default_control_points (Grob *);
+ static SCM get_default_control_points (Spanner *);
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM));
DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
#include "semi-tie.hh"
#include "directional-element-interface.hh"
#include "grob.hh"
+#include "paper-column.hh"
#include "tie.hh"
#include "warn.hh"
#include "staff-symbol-referencer.hh"
}
int
-Semi_tie::get_position (Grob *me)
+Semi_tie::get_column_rank (Item *me)
{
- Grob *h = unsmob<Grob> (me->get_object ("note-head"));
- return (int) rint (Staff_symbol_referencer::get_position (h));
+ return Paper_column::get_rank (me->get_column ());
+}
+
+int
+Semi_tie::get_position (Item *me)
+{
+ return (int) rint (Staff_symbol_referencer::get_position (head (me)));
}
bool
Semi_tie::less (Grob *const &s1,
Grob *const &s2)
{
- return get_position (s1) < get_position (s2);
+ return Tie::get_position_generic (s1) < Tie::get_position_generic (s2);
}
+Item *
+Semi_tie::head (Item *me)
+{
+ return unsmob<Item> (me->get_object ("note-head"));
+}
+
+Item *
+Semi_tie::head (Item *me, Direction d)
+{
+ SCM head_dir = me->get_property ("head-direction");
+ return (is_direction (head_dir) && (to_dir (head_dir) == d)) ? head (me) : 0;
+}
using namespace std;
void
-Tie_column::add_tie (Grob *tc, Grob *tie)
+Tie_column::add_tie (Grob *tc, Spanner *tie)
{
Spanner *me = dynamic_cast<Spanner *> (tc);
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);
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:
: 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_
}
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);
#include "misc.hh"
#include "note-head.hh"
#include "rhythmic-head.hh"
+#include "semi-tie.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
for (vsize i = 0; i < ties.size (); i++)
{
- Item *it = dynamic_cast<Spanner *> (ties[i])->get_bound (d);
+ Spanner *tie = dynamic_cast<Spanner *> (ties[i]);
+ Item *it = tie->get_bound (d);
if (it->break_status_dir ())
it = it->get_column ();
for (vsize i = 0; i < ties.size (); i++)
{
+ Spanner *tie = dynamic_cast<Spanner *> (ties[i]);
Tie_specification spec;
- spec.from_grob (ties[i]);
+ spec.from_grob (tie);
for (LEFT_and_RIGHT (d))
{
- spec.note_head_drul_[d] = Tie::head (ties[i], d);
- spec.column_ranks_[d] = Tie::get_column_rank (ties[i], d);
+ spec.note_head_drul_[d] = Tie::head (tie, d);
+ spec.column_ranks_[d] = Tie::get_column_rank (tie, d);
}
specifications_.push_back (spec);
}
int column_rank = -1;
for (vsize i = 0; i < semi_ties.size (); i++)
{
+ Item *semi_tie = dynamic_cast<Item *> (semi_ties[i]);
Tie_specification spec;
- Item *head = unsmob<Item> (semi_ties[i]->get_object ("note-head"));
+ Item *head = Semi_tie::head (semi_tie);
if (!head)
programming_error ("LV tie without head?!");
spec.position_ = int (Staff_symbol_referencer::get_position (head));
}
- spec.from_grob (semi_ties[i]);
+ spec.from_grob (semi_tie);
spec.note_head_drul_[head_dir] = head;
- column_rank = Tie::get_column_rank (semi_ties[i], head_dir);
+ column_rank = Semi_tie::get_column_rank (semi_tie);
spec.column_ranks_ = Drul_array<int> (column_rank, column_rank);
heads.push_back (head);
specifications_.push_back (spec);
has_manual_dir_ = true;
}
- position_ = Tie::get_position (tie);
+ position_ = Tie::get_position_generic (tie);
SCM pos_scm = tie->get_property ("staff-position");
if (scm_is_number (pos_scm))
{
#include "paper-column.hh"
#include "pointer-group-interface.hh"
#include "rhythmic-head.hh"
+#include "semi-tie.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
bool
Tie::less (Grob *const &s1, Grob *const &s2)
{
- return Tie::get_position (s1) < Tie::get_position (s2);
+ return get_position_generic (s1) < get_position_generic (s2);
}
void
-Tie::set_head (Grob *me, Direction d, Grob *h)
+Tie::set_head (Spanner *me, Direction d, Grob *h)
{
- dynamic_cast<Spanner *> (me)->set_bound (d, h);
+ me->set_bound (d, h);
}
-Grob *
-Tie::head (Grob *me, Direction d)
+Item *
+Tie::head (Spanner *me, Direction d)
{
- if (is_direction (me->get_property ("head-direction")))
- {
- Direction hd = to_dir (me->get_property ("head-direction"));
-
- return (hd == d)
- ? unsmob<Grob> (me->get_object ("note-head"))
- : 0;
- }
-
- Item *it = dynamic_cast<Spanner *> (me)->get_bound (d);
- if (Note_head::has_interface (it))
- return it;
- else
- return 0;
+ Item *it = me->get_bound (d);
+ return Note_head::has_interface (it) ? it : 0;
}
int
-Tie::get_column_rank (Grob *me, Direction d)
+Tie::get_column_rank (Spanner *me, Direction d)
{
- Grob *col = 0;
- Spanner *span = dynamic_cast<Spanner *> (me);
- if (!span)
- col = dynamic_cast<Item *> (me)->get_column ();
- else
- {
- Grob *h = head (me, d);
- if (!h)
- h = span->get_bound (d);
-
- col = dynamic_cast<Item *> (h)->get_column ();
- }
- return Paper_column::get_rank (col);
+ return Paper_column::get_rank (me->get_bound (d)->get_column ());
}
int
-Tie::get_position (Grob *me)
+Tie::get_position (Spanner *me)
{
for (LEFT_and_RIGHT (d))
{
return 0;
}
+int
+Tie::get_position_generic (Grob *me) // TODO: do away with this
+{
+ Spanner *spanner = dynamic_cast<Spanner *> (me);
+ if (spanner)
+ return get_position (spanner);
+
+ Item *item = dynamic_cast<Item *> (me);
+ if (item)
+ return Semi_tie::get_position (item);
+
+ programming_error ("grob is neither a tie nor a semi-tie");
+ return 0;
+}
+
/*
Default: Put the tie oppositie of the stem [Wanske p231]
Drul_array<Grob *> stems;
for (LEFT_and_RIGHT (d))
{
- Grob *one_head = head (me, d);
- if (!one_head && dynamic_cast<Spanner *> (me))
- one_head = Tie::head (dynamic_cast<Spanner *> (me)->broken_neighbor (d), d);
+ Grob *one_head = 0;
+ if (Spanner *spanner = dynamic_cast<Spanner *> (me))
+ {
+ one_head = head (spanner, d);
+ if (!one_head)
+ one_head = head (spanner->broken_neighbor (d), d);
+ }
+ else if (Item *item = dynamic_cast<Item *> (me))
+ one_head = Semi_tie::head (item);
Grob *stem = one_head ? Rhythmic_head::get_stem (one_head) : 0;
- if (stem)
- stem = Stem::is_invisible (stem) ? 0 : stem;
-
- stems[d] = stem;
+ stems[d] = (stem && !Stem::is_invisible (stem)) ? stem : 0;
}
if (stems[LEFT] && stems[RIGHT])
if (get_grob_direction (stems[LEFT]) == UP
&& get_grob_direction (stems[RIGHT]) == UP)
return DOWN;
+
+ // And why not return UP if both stems are DOWN?
+
+ // And when stems conflict, why fall directly through to using
+ // neutral-direction without considering get_position (me)?
}
- else if (stems[LEFT] || stems[RIGHT])
- {
- Grob *s = stems[LEFT] ? stems[LEFT] : stems[RIGHT];
- return -get_grob_direction (s);
- }
- else if (int p = get_position (me))
+ else if (stems[LEFT])
+ return -get_grob_direction (stems[LEFT]);
+ else if (stems[RIGHT])
+ return -get_grob_direction (stems[RIGHT]);
+ else if (int p = get_position_generic (me))
return Direction (sign (p));
return to_dir (me->get_property ("neutral-direction"));
}
SCM
-Tie::get_default_control_points (Grob *me_grob)
+Tie::get_default_control_points (Spanner *me)
{
- Spanner *me = dynamic_cast<Spanner *> (me_grob);
Grob *common = me;
common = me->get_bound (LEFT)->common_refpoint (common, X_AXIS);
common = me->get_bound (RIGHT)->common_refpoint (common, X_AXIS);
SCM
Tie::calc_control_points (SCM smob)
{
- Grob *me = unsmob<Grob> (smob);
+ Spanner *me = LY_ASSERT_SMOB(Spanner, smob, 1);
Grob *yparent = me->get_parent (Y_AXIS);
if ((Tie_column::has_interface (yparent)