]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4478: Disentangle some Tie and Semi_tie code
authorDan Eble <nine.fierce.ballads@gmail.com>
Fri, 3 Jul 2015 14:26:33 +0000 (10:26 -0400)
committerDan Eble <nine.fierce.ballads@gmail.com>
Wed, 8 Jul 2015 02:56:20 +0000 (22:56 -0400)
Both are Grobs, but ties are Spanners and semi-ties are Items.

lily/completion-note-heads-engraver.cc
lily/include/semi-tie.hh
lily/include/tie-column.hh
lily/include/tie.hh
lily/semi-tie.cc
lily/tie-column.cc
lily/tie-engraver.cc
lily/tie-formatting-problem.cc
lily/tie-specification.cc
lily/tie.cc

index f590d2a40f014fabadebbae1afd7b818740c62e6..c88e4cccc1e8f6f391937e9a87cca340a1ab6a06 100644 (file)
@@ -59,7 +59,7 @@ class Completion_heads_engraver : public Engraver
   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_;
@@ -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);
index 9fe673a71754a47914a88e9a4fc1a6c3cbee9968..6eb6472e712c439bdf97a41a07f906feb9f38fff 100644 (file)
@@ -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 */
index 8ec9cad18b0230c2c1cfce2075655ea06df712ff..0485cd0bcf3c96607b23153ca394b2d0c939642f 100644 (file)
@@ -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);
index 189bb7757971c0ba09c665c021f91da95fe72a8e..7b74d159c85d046913685f41746ccd194dcb4441 100644 (file)
 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));
index 4e997aa78f4a4235fd69d350ec13a7b946f72842..1cc82c3b08839a397198010384524114d801345d 100644 (file)
@@ -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<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;
+}
index 6241a4c246799ef93ba50cf7c5b722c3882a07a1..8a0ef24139a5b8481e84e4277de5ff8a105cc36e 100644 (file)
@@ -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<Spanner *> (tc);
 
index ef03f87bd632626ae6a740ac6bf456464f0d1ed7..56fb4a337ddce22c9653c16d74635e25501e277a 100644 (file)
@@ -75,7 +75,7 @@ class Tie_engraver : public Engraver
   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);
@@ -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<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);
index 83e5d25464a2ca4c57e05a1da121fb0a130bc471..ad08638ebb000d81b22ba4a050c7f0aa0e2a0636 100644 (file)
@@ -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<Grob *> const &ties)
 
       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 ();
 
@@ -354,13 +356,14 @@ Tie_formatting_problem::from_ties (vector<Grob *> const &ties)
 
   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);
     }
@@ -379,8 +382,9 @@ Tie_formatting_problem::from_semi_ties (vector<Grob *> const &semi_ties, Directi
   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?!");
@@ -390,10 +394,10 @@ Tie_formatting_problem::from_semi_ties (vector<Grob *> 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<int> (column_rank, column_rank);
       heads.push_back (head);
       specifications_.push_back (spec);
index 0ccf2c5beb3298e44e0f1d5e3e0814ed8ee029b6..9beb9859136c17d392f1cd6ff2285f4422fef434 100644 (file)
@@ -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))
     {
index 631ec18428be57d66b5fc0f6df9120f780bd555c..47c5a1c9cfb9809b1d58b6f0186a069dff9bcc9d 100644 (file)
@@ -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"
 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))
     {
@@ -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<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]
 
@@ -125,15 +117,18 @@ Tie::get_default_dir (Grob *me)
   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])
@@ -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<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);
@@ -218,7 +216,7 @@ MAKE_SCHEME_CALLBACK (Tie, calc_control_points, 1);
 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)