From: Dan Eble Date: Fri, 3 Jul 2015 14:26:33 +0000 (-0400) Subject: Issue 4478: Disentangle some Tie and Semi_tie code X-Git-Tag: release/2.19.23-1~17 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=0694f44d61203d9e8d26cd9bc83b46f2addb2c7f;p=lilypond.git Issue 4478: Disentangle some Tie and Semi_tie code Both are Grobs, but ties are Spanners and semi-ties are Items. --- diff --git a/lily/completion-note-heads-engraver.cc b/lily/completion-note-heads-engraver.cc index f590d2a40f..c88e4cccc1 100644 --- a/lily/completion-note-heads-engraver.cc +++ b/lily/completion-note-heads-engraver.cc @@ -59,7 +59,7 @@ class Completion_heads_engraver : public Engraver vector notes_; vector prev_notes_; // Must remember notes for explicit ties. - vector ties_; + vector ties_; vector note_events_; Spanner *tie_column_; Moment note_end_mom_; @@ -271,7 +271,7 @@ Completion_heads_engraver::process_music () 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); diff --git a/lily/include/semi-tie.hh b/lily/include/semi-tie.hh index 9fe673a717..6eb6472e71 100644 --- a/lily/include/semi-tie.hh +++ b/lily/include/semi-tie.hh @@ -31,7 +31,11 @@ struct Semi_tie 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 */ diff --git a/lily/include/tie-column.hh b/lily/include/tie-column.hh index 8ec9cad18b..0485cd0bcf 100644 --- a/lily/include/tie-column.hh +++ b/lily/include/tie-column.hh @@ -27,7 +27,7 @@ class Tie_column { 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); diff --git a/lily/include/tie.hh b/lily/include/tie.hh index 189bb77579..7b74d159c8 100644 --- a/lily/include/tie.hh +++ b/lily/include/tie.hh @@ -27,16 +27,17 @@ 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)); diff --git a/lily/semi-tie.cc b/lily/semi-tie.cc index 4e997aa78f..1cc82c3b08 100644 --- a/lily/semi-tie.cc +++ b/lily/semi-tie.cc @@ -22,6 +22,7 @@ #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" @@ -71,16 +72,33 @@ Semi_tie::calc_control_points (SCM smob) } int -Semi_tie::get_position (Grob *me) +Semi_tie::get_column_rank (Item *me) { - Grob *h = unsmob (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 (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; +} diff --git a/lily/tie-column.cc b/lily/tie-column.cc index 6241a4c246..8a0ef24139 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -35,7 +35,7 @@ using namespace std; void -Tie_column::add_tie (Grob *tc, Grob *tie) +Tie_column::add_tie (Grob *tc, Spanner *tie) { Spanner *me = dynamic_cast (tc); diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index ef03f87bd6..56fb4a337d 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -75,7 +75,7 @@ class Tie_engraver : public Engraver Stream_event *event_; vector now_heads_; vector heads_to_tie_; - vector ties_; + vector ties_; Spanner *tie_column_; bool tie_notehead (Grob *h, bool enharmonic); @@ -87,7 +87,7 @@ protected: 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: @@ -176,7 +176,7 @@ Tie_engraver::tie_notehead (Grob *h, bool enharmonic) : 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_ @@ -367,23 +367,22 @@ Tie_engraver::stop_translation_timestep () } 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 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 (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); diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc index 83e5d25464..ad08638ebb 100644 --- a/lily/tie-formatting-problem.cc +++ b/lily/tie-formatting-problem.cc @@ -29,6 +29,7 @@ #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" @@ -342,7 +343,8 @@ Tie_formatting_problem::from_ties (vector const &ties) for (vsize i = 0; i < ties.size (); i++) { - Item *it = dynamic_cast (ties[i])->get_bound (d); + Spanner *tie = dynamic_cast (ties[i]); + Item *it = tie->get_bound (d); if (it->break_status_dir ()) it = it->get_column (); @@ -354,13 +356,14 @@ Tie_formatting_problem::from_ties (vector const &ties) for (vsize i = 0; i < ties.size (); i++) { + Spanner *tie = dynamic_cast (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); } @@ -379,8 +382,9 @@ Tie_formatting_problem::from_semi_ties (vector const &semi_ties, Directi int column_rank = -1; for (vsize i = 0; i < semi_ties.size (); i++) { + Item *semi_tie = dynamic_cast (semi_ties[i]); Tie_specification spec; - Item *head = unsmob (semi_ties[i]->get_object ("note-head")); + Item *head = Semi_tie::head (semi_tie); if (!head) programming_error ("LV tie without head?!"); @@ -390,10 +394,10 @@ Tie_formatting_problem::from_semi_ties (vector const &semi_ties, Directi 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 (column_rank, column_rank); heads.push_back (head); specifications_.push_back (spec); diff --git a/lily/tie-specification.cc b/lily/tie-specification.cc index 0ccf2c5beb..9beb985913 100644 --- a/lily/tie-specification.cc +++ b/lily/tie-specification.cc @@ -29,7 +29,7 @@ Tie_specification::from_grob (Grob *tie) 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)) { diff --git a/lily/tie.cc b/lily/tie.cc index 631ec18428..47c5a1c9cf 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -30,6 +30,7 @@ #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" @@ -43,54 +44,30 @@ 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 (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 (me->get_object ("note-head")) - : 0; - } - - Item *it = dynamic_cast (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 (me); - if (!span) - col = dynamic_cast (me)->get_column (); - else - { - Grob *h = head (me, d); - if (!h) - h = span->get_bound (d); - - col = dynamic_cast (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)) { @@ -109,6 +86,21 @@ Tie::get_position (Grob *me) return 0; } +int +Tie::get_position_generic (Grob *me) // TODO: do away with this +{ + Spanner *spanner = dynamic_cast (me); + if (spanner) + return get_position (spanner); + + Item *item = dynamic_cast (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] @@ -125,15 +117,18 @@ Tie::get_default_dir (Grob *me) Drul_array stems; for (LEFT_and_RIGHT (d)) { - Grob *one_head = head (me, d); - if (!one_head && dynamic_cast (me)) - one_head = Tie::head (dynamic_cast (me)->broken_neighbor (d), d); + Grob *one_head = 0; + if (Spanner *spanner = dynamic_cast (me)) + { + one_head = head (spanner, d); + if (!one_head) + one_head = head (spanner->broken_neighbor (d), d); + } + else if (Item *item = dynamic_cast (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]) @@ -141,13 +136,17 @@ Tie::get_default_dir (Grob *me) 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")); @@ -175,9 +174,8 @@ Tie::calc_direction (SCM smob) } SCM -Tie::get_default_control_points (Grob *me_grob) +Tie::get_default_control_points (Spanner *me) { - Spanner *me = dynamic_cast (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); @@ -218,7 +216,7 @@ MAKE_SCHEME_CALLBACK (Tie, calc_control_points, 1); SCM Tie::calc_control_points (SCM smob) { - Grob *me = unsmob (smob); + Spanner *me = LY_ASSERT_SMOB(Spanner, smob, 1); Grob *yparent = me->get_parent (Y_AXIS); if ((Tie_column::has_interface (yparent)