]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/tie-column.cc (set_directions): set directions only once.
authorhanwen <hanwen>
Mon, 22 Aug 2005 00:58:02 +0000 (00:58 +0000)
committerhanwen <hanwen>
Mon, 22 Aug 2005 00:58:02 +0000 (00:58 +0000)
(add_configuration): new function.

* lily/tie.cc (set_control_points): new function

* lily/tie-column.cc (new_directions): new function.

* ly/music-functions-init.ly: set 'pitch property
iso. trill-pitch. This makes \relative work with \pitchedTrill

* lily/tie.cc (get_configuration): new function. Don't generate
control points, rather, generate configuration.
remove head-pair property.

* lily/include/tie.hh (struct Tie_configuration): new struct.

14 files changed:
ChangeLog
Documentation/user/advanced-notation.itely
input/regression/trill-spanner-pitched.ly
lily/completion-note-heads-engraver.cc
lily/include/break-algorithm.hh
lily/include/tie-column.hh
lily/include/tie.hh
lily/pitched-trill-engraver.cc
lily/tie-column.cc
lily/tie-engraver.cc
lily/tie.cc
ly/music-functions-init.ly
scm/define-grob-properties.scm
scm/define-grobs.scm

index 0e54d92c498b9a569ee0fa06f9903c55f1bed6fd..d02ec693c12c9fe8fb10ac75beea5ada7c736a46 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2005-08-22  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+
+       * lily/tie-column.cc (set_directions): set directions only once.
+       (add_configuration): new function.
+
+       * lily/tie.cc (set_control_points): new function
+
+       * lily/tie-column.cc (new_directions): new function.
+
+       * ly/music-functions-init.ly: set 'pitch property
+       iso. trill-pitch. This makes \relative work with \pitchedTrill
+
+       * lily/tie.cc (get_configuration): new function. Don't generate
+       control points, rather, generate configuration.
+       remove head-pair property.
+
+       * lily/include/tie.hh (struct Tie_configuration): new struct.
+
 2005-08-22  Heikki Junes  <hjunes@cc.hut.fi>
 
        * Documentation/topdocs/NEWS.tely: clarify.
index 478ecf79c69fd4ced5d32e57f5e8e9f9d76079c2..60f9a3beaeb27508fb6f25f97f114f9debd11f81 100644 (file)
@@ -1799,11 +1799,6 @@ typeset with the command @code{pitchedTrill},
 The first argument is the main note. The absolute pitch of the second
 is printed as a stemless note head in parentheses.
 
-@refbugs
-
-Relative octave mode ignores the octave of the second argument of
-@code{\pitchedTrill}.
-
 @node Feathered beams
 @subsection Feathered beams
 
index 38d2393f285afc5bf80238eae30d28953d25f123..6e13f9b8b9e7729ef1e677bf2dfb0d6de366d6c1 100644 (file)
@@ -13,5 +13,5 @@
 }
 
 \relative {
-  \pitchedTrill c4.\startTrillSpan fis f\stopTrillSpan
+  \pitchedTrill c4.\startTrillSpan es f\stopTrillSpan
 }
index b594e5be61b128ec17d139c773201eb804fd9341..ede37181b9b84485566242f8c8966689053604ce 100644 (file)
@@ -247,8 +247,6 @@ Completion_heads_engraver::process_music ()
       for (int i = 0; i < notes_.size (); i++)
        {
          Grob *p = make_spanner ("Tie", SCM_EOL);
-         Tie::set_interface (p); // cannot remove yet!
-
          Tie::set_head (p, LEFT, prev_notes_[i]);
          Tie::set_head (p, RIGHT, notes_[i]);
 
index 025c56406e09da577d00c211654b863d23d525bf..0fe95a26ffe3e0d22a27ee329c2364c746e08af8 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  break-algorithm.hh -- declare  Break_algorithm
+  break-algorithm.hh -- declare Break_algorithm
 
   source file of the GNU LilyPond music typesetter
 
@@ -28,9 +28,10 @@ protected:
   void solve_line (Column_x_positions *) const;
   bool feasible (Link_array<Grob> const &) const;
 
-  Simple_spacer_wrapper *generate_spacing_problem (Link_array<Grob> const &, Interval) const;
-
+  Simple_spacer_wrapper *generate_spacing_problem (Link_array<Grob> const &,
+                                                  Interval) const;
   virtual Array<Column_x_positions> do_solve () const = 0;
+
 public:
   virtual ~Break_algorithm ();
   Simple_spacer *(*get_line_spacer) ();
index 17797e9d963c38a592fdcb91b1cce47a1187d1a6..3ecc0120761c506aeebdd160709d2ea471960b40 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
   tie-column.hh -- declare Tie_column
 
@@ -22,6 +21,7 @@ public:
   DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM));
   static void set_directions (Grob *me);
   static void werner_directions (Grob *me);
+  static void new_directions (Grob *me);
 };
 
 #endif /* TIE_COLUMN_HH */
index bb6066a53933e58b4d1cec0bdb2279aac5aae8dc..efaa3f2949b21c3628cf31afa28ae78e65e26e0f 100644 (file)
@@ -18,33 +18,33 @@ struct Tie_configuration
   int position_;
   Direction dir_;
   Interval attachment_x_;
-  Real edge_y_;
+  Real delta_y_;
   
-  Tie_configuration ()
-  {
-    dir_ = CENTER;
-    position_ = 0;
-  }
+  Tie_configuration ();
   
   static int compare (Tie_configuration const &a,
                      Tie_configuration const &b);
 };
+INSTANTIATE_COMPARE (Tie_configuration, Tie_configuration::compare);
 
 class Tie
 {
 public:
   static void set_head (Grob *, Direction, Grob *head);
-  static void set_interface (Grob *);
   static bool has_interface (Grob *);
   static void set_direction (Grob *);
   static Grob *head (Grob *, Direction);
   static int get_column_rank (Grob *, Direction);
   static Real get_position (Grob *);
   static Direction get_default_dir (Grob *);
-  static SCM get_control_points (SCM);
-  static SCM get_configuration (SCM);
+  static void get_configuration (Grob *, Grob **, Tie_configuration *);
+  static void set_control_points (Grob *, Grob **,Tie_configuration const&);
+  static void set_default_control_points (Grob *);
   DECLARE_SCHEME_CALLBACK (print, (SCM));
   DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM));
+  static int compare (Grob *const &s1,
+                     Grob *const &s2);
+  
 };
 
 
index ce2c5a3b91ae70fa868768c871edfd20fcc5ad1b..5066d79eddade04879b0a62d076cd6e0e755c18f 100644 (file)
@@ -28,7 +28,6 @@ protected:
   DECLARE_ACKNOWLEDGER (dots);
   DECLARE_ACKNOWLEDGER (text_spanner);
   void process_music ();
-  virtual bool try_music (Music *);
   void stop_translation_timestep ();
 
 private:
@@ -66,14 +65,14 @@ Pitched_trill_engraver::acknowledge_text_spanner (Grob_info info)
   if (mus
       && mus->is_mus_type ("trill-span-event")
       && to_dir (mus->get_property ("span-direction")) == START
-      && unsmob_pitch (mus->get_property ("trill-pitch")))
+      && unsmob_pitch (mus->get_property ("pitch")))
     make_trill (mus);
 }
 
 void
 Pitched_trill_engraver::make_trill (Music *mus)
 {
-  SCM scm_pitch = mus->get_property ("trill-pitch");
+  SCM scm_pitch = mus->get_property ("pitch");
   Pitch *p = unsmob_pitch (scm_pitch);
 
   SCM keysig = get_property ("localKeySignature");
@@ -137,19 +136,19 @@ Pitched_trill_engraver::process_music ()
 {
 }
 
-bool
-Pitched_trill_engraver::try_music (Music *)
-{
-  return false;
-}
 
 #include "translator.icc"
+
 ADD_ACKNOWLEDGER (Pitched_trill_engraver, note_head);
 ADD_ACKNOWLEDGER (Pitched_trill_engraver, dots);
 ADD_ACKNOWLEDGER (Pitched_trill_engraver, text_spanner);
+
 ADD_TRANSLATOR (Pitched_trill_engraver,
                /* doc */ "Print the bracketed notehead after a notehead with trill.",
-               /* create */ "TrillPitchHead TrillPitchAccidental TrillPitchGroup",
+               /* create */
+               "TrillPitchHead "
+               "TrillPitchAccidental "
+               "TrillPitchGroup",
                /* accept */ "",
                /* read */ "",
                /* write */ "");
index 31e1daf1f8f4570336d04c32a7dfcfc97219d053..351feb2cc66c2ac64ffaca27e6e367ba2556a50f 100644 (file)
@@ -6,6 +6,12 @@
   (c) 2000--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
 
+
+#include <math.h>
+#include <map>
+
+#include "staff-symbol-referencer.hh"
+#include "warn.hh"
 #include "tie-column.hh"
 #include "paper-column.hh"
 #include "spanner.hh"
 #include "directional-element-interface.hh"
 #include "rhythmic-head.hh"
 
-/*
-  tie dir depends on what Tie_column does.
-*/
-/*
-  TODO: this doesn't follow standard pattern. Regularize.
-*/
 void
 Tie_column::add_tie (Grob *me, Grob *tie)
 {
@@ -41,17 +41,20 @@ Tie_column::add_tie (Grob *me, Grob *tie)
 void
 Tie_column::set_directions (Grob *me)
 {
-  werner_directions (me);
+  if (!to_boolean (me->get_property ("positioning-done")))
+    {
+      me->set_property ("positioning-done", SCM_BOOL_T); 
+      new_directions (me);
+    }
 }
 
 int
-tie_compare (Grob *const &s1,
-            Grob *const &s2)
+Tie::compare (Grob *const &s1,
+             Grob *const &s2)
 {
   return sign (Tie::get_position (s1) - Tie::get_position (s2));
 }
 
-#if 0
 /*
   Werner:
 
@@ -75,7 +78,7 @@ Tie_column::werner_directions (Grob *me)
   if (!ties.size ())
     return;
 
-  ties.sort (tie_compare);
+  ties.sort (&Tie::compare);
 
   Direction d = get_grob_direction (me);
   if (d)
@@ -134,13 +137,12 @@ Tie_column::werner_directions (Grob *me)
 
   return;
 }
-#endif
 
 MAKE_SCHEME_CALLBACK (Tie_column, after_line_breaking, 1);
 SCM
 Tie_column::after_line_breaking (SCM smob)
 {
-  werner_directions (unsmob_grob (smob));
+  set_directions (unsmob_grob (smob));
   return SCM_UNSPECIFIED;
 }
 
@@ -169,6 +171,182 @@ Tie_column::before_line_breaking (SCM smob)
 
 ADD_INTERFACE (Tie_column, "tie-column-interface",
               "Object that sets directions of multiple ties in a tied chord",
-              "direction");
+              "direction "
+              "positioning-done "
+              );
+
+
+
+
+bool
+config_allowed (map<Tie_configuration, bool> const &allowed,
+               Tie_configuration conf)
+{
+  return allowed.find (conf) == allowed.end ();
+}
+
+void
+add_configuration (map<Tie_configuration, bool> *allowed,
+                  Grob *tie_column,
+                  Tie_configuration new_conf)
+{
+  bool on_line = Staff_symbol_referencer::on_staffline (tie_column, new_conf.position_);
+  
+  if (allowed->find (new_conf) != allowed->end ()
+      && !(*allowed)[new_conf])
+    {
+      programming_error ("Tie configuration not allowed");
+    }
+        
+
+  if (on_line)
+    {
+      Tie_configuration forbidden;
+
+      forbidden.dir_ = -new_conf.dir_ ;
+      forbidden.position_ = new_conf.position_;
+      (*allowed)[forbidden] = false;
+
+      forbidden.position_ += new_conf.dir_;
+      (*allowed)[forbidden] = false;
+      forbidden.position_ += new_conf.dir_;
+      (*allowed)[forbidden] = false;
+
+      forbidden.dir_ = new_conf.dir_;
+      forbidden.position_ = new_conf.position_ + new_conf.dir_;
+      (*allowed)[forbidden] = false;
+    }
+  else
+    {
+      Tie_configuration forbidden;
+      forbidden.dir_ = - new_conf.dir_;
+      forbidden.position_ = new_conf.position_;
+
+      
+      (*allowed)[forbidden] = false;
+      forbidden.position_ -= new_conf.dir_;
+      forbidden.dir_ = new_conf.dir_;
+      (*allowed)[forbidden] = false;
+
+      forbidden.position_ += 2* new_conf.dir_; 
+      (*allowed)[forbidden] = false;
+    }
+}
+
+
+void
+Tie_column::new_directions (Grob *me)
+{
+  extract_grob_set (me, "ties", ro_ties);
+  Link_array<Grob> ties (ro_ties);
+  if (!ties.size ())
+    return;
+
+  if (ties.size() == 1)
+    {
+      Tie::set_default_control_points (ties[0]);
+      return ;
+    }
+  
+  ties.sort (&Tie::compare);
+  Array<Tie_configuration> tie_configs;
+  for (int i = 0; i < ties.size (); i++)
+    {
+      Tie_configuration conf;
+      conf.dir_ = get_grob_direction (ties[i]);
+      conf.position_ = (int) rint (Tie::get_position (ties[i]));
+      tie_configs.push (conf);
+    }
+
+    
+  if (!tie_configs[0].dir_)
+    tie_configs[0].dir_ = DOWN;
+  if (!tie_configs.top().dir_)
+    tie_configs.top().dir_ = UP;
+
+
+  /*
+    Seconds
+   */
+  for (int i = 1; i < tie_configs.size(); i++)
+    {
+      if (fabs (tie_configs[i-1].position_ - tie_configs[i].position_) <= 1)
+       {
+         if (!tie_configs[i-1].dir_)
+           tie_configs[i-1].dir_ = DOWN;
+         if (!tie_configs[i].dir_)
+           tie_configs[i].dir_ = UP;
+       }
+    }
+
+  for (int i = 1; i < tie_configs.size() - 1; i++)
+    {
+      if (tie_configs[i].dir_)
+       continue;
+
+      tie_configs[i].dir_ = (Direction) sign (tie_configs[i].position_);
+    }
+
+  Grob *common[NO_AXES] = {
+    me, me
+  };
+  for (int i = 0; i < ties.size (); i++)
+    for (int a = X_AXIS; a < NO_AXES; a++)
+      {
+       Axis ax ((Axis) a);
+       
+       common[ax] = dynamic_cast<Spanner*> (ties[i])->get_bound (LEFT)->common_refpoint (common[a], ax); 
+       common[ax] = dynamic_cast<Spanner*> (ties[i])->get_bound (RIGHT)->common_refpoint (common[a], ax); 
+      }
+  
+  map<Tie_configuration, bool> allowed;
+
+  Tie::get_configuration (ties[0], common, &tie_configs.elem_ref (0));
+  Tie::get_configuration (ties.top (), common,
+                         &tie_configs.elem_ref (tie_configs.size()-1));
+
+  add_configuration (&allowed, me, tie_configs[0]);
+  add_configuration (&allowed, me, tie_configs.top());
+
+  for (int i = 1; i < ties.size(); i++)
+    {
+      Tie_configuration conf = tie_configs[i];
+      Tie::get_configuration (ties[i], common, &conf);
+      if (!config_allowed (allowed, conf))
+       {
+         conf = tie_configs[i];
+
+         Direction d = LEFT;
+         do
+           {
+             conf.attachment_x_[d] = d * 1e6; //  infty
+             for (int j = i - 1; j < i + 2; j++)
+               {
+                 if (j >= 0 && j < ties.size())
+                   {
+                     Spanner *t = dynamic_cast<Spanner*> (ties[j]);
+                     Interval ext
+                       = robust_relative_extent (t->get_bound (d),
+                                                 common[X_AXIS], X_AXIS);
+                     conf.attachment_x_[d]
+                       = d * min (d * conf.attachment_x_[d], d * ext[-d]);
+                   } 
+               }
+           }
+         while (flip (&d) != LEFT);
+         tie_configs[i] = conf;
+       }
+      else
+       tie_configs[i] = conf;
+
+      add_configuration (&allowed, me, conf);
+    }
+
+  for (int i = 0; i < ties.size(); i++)
+    {
+      Tie::set_control_points (ties[i], common, tie_configs[i]);
+      set_grob_direction (ties[i], tie_configs[i].dir_);
+    }
+}
 
 
index 33608058a6160403780f101f976e2aab31f33429..15239114030555c9f085dfe9602b6af82b13a2fb 100644 (file)
@@ -115,8 +115,6 @@ Tie_engraver::acknowledge_note_head (Grob_info i)
          Grob *p = new Spanner (heads_to_tie_[i].tie_definition_,
                                 context ()->get_grob_key ("Tie"));
          announce_grob (p, heads_to_tie_[i].event_->self_scm ());
-         Tie::set_interface (p); // cannot remove yet!
-
          Tie::set_head (p, LEFT, th);
          Tie::set_head (p, RIGHT, h);
 
@@ -191,15 +189,20 @@ Tie_engraver::typeset_tie (Grob *her)
     }
   while (flip (&d) != LEFT);
 
-  index_set_cell (her->get_property ("head-pair"), LEFT, new_head_drul[LEFT]->self_scm ());
-  index_set_cell (her->get_property ("head-pair"), RIGHT, new_head_drul[RIGHT]->self_scm ());
+  Spanner *sp = dynamic_cast<Spanner*> (her);
+  sp->set_bound (LEFT, new_head_drul[LEFT]);
+  sp->set_bound (RIGHT, new_head_drul[RIGHT]);
 }
 
 #include "translator.icc"
+
 ADD_ACKNOWLEDGER (Tie_engraver, note_head);
 ADD_TRANSLATOR (Tie_engraver,
                /* doc */ "Generate ties between noteheads of equal pitch.",
-               /* create */ "Tie TieColumn",
+               /* create */
+               "Tie "
+               "TieColumn",
+
                /* accept */ "tie-event",
                /* read */ "tieWaitForNote",
                /* write */ "tieMelismaBusy");
index 0a968718c181d0631cc1c52c78f2b7f1da6fc857..40a8facc16e302c7f296bbc4d722f5bc70498b4d 100644 (file)
 void
 Tie::set_head (Grob *me, Direction d, Grob *h)
 {
-  assert (!head (me, d));
-  index_set_cell (me->get_property ("head-pair"), d, h->self_scm ());
-
   dynamic_cast<Spanner *> (me)->set_bound (d, h);
   me->add_dependency (h);
 }
 
-void
-Tie::set_interface (Grob *me)
-{
-  me->set_property ("head-pair", scm_cons (SCM_EOL, SCM_EOL));
-}
-
 Grob *
 Tie::head (Grob *me, Direction d)
 {
-  SCM c = me->get_property ("head-pair");
-
-  if (scm_is_pair (c))
-    return unsmob_grob (index_get_cell (c, d));
+  Item *it = dynamic_cast<Spanner*> (me)->get_bound (d);
+  if (Note_head::has_interface (it))
+    return it;
   else
     return 0;
 }
@@ -125,78 +115,89 @@ Tie::set_direction (Grob *me)
 }
 
 
-SCM
-Tie::get_configuration (Grob *me_grob,
-                       Grob **common,
+void
+Tie::get_configuration (Grob *me_grob, Grob **common,
                        Tie_configuration *conf)
 {
   Spanner *me = dynamic_cast<Spanner*> (me_grob);
-  
   if (!head (me, LEFT) && !head (me, RIGHT))
     {
       programming_error ("tie without heads");
       me->suicide ();
-      return SCM_EOL;
+      return ;
     }
 
-  set_direction (me);
-  int tie_position = (int) Tie::get_position (me);
+  Direction dir = CENTER;
   
-  Direction dir = get_grob_direction (me);
-
-  Real staff_space = Staff_symbol_referencer::staff_space (me);
-  Real staff_position = tie_position;
+  int tie_position = (int) Tie::get_position (me);
+  int staff_position = conf->position_;
 
-  Direction d = LEFT;
-  Real gap = robust_scm2double (me->get_property ("x-gap"), 0.2);
-  do
+  if (conf->dir_)
+    {
+      dir = conf->dir_;
+    }
+  else
     {
-      attachments[d]
-       = robust_relative_extent (me->get_bound (d),
-                                 common[X_AXIS],
-                                 X_AXIS)[-d]
-       - gap * d;
+      dir = get_grob_direction (me);
+      if (!dir)
+       dir = get_default_dir (me);
     }
-  while (flip (&d) != LEFT);
+
+  Real staff_space = Staff_symbol_referencer::staff_space (me);
 
   bool in_between = true;
-  if (attachments.length () < 0.6 * staff_space)
+  Interval attachments = conf->attachment_x_;
+  if (attachments.is_empty())
     {
-      /*
-       Let short ties start over note heads, instead of between.
-       */
-      Drul_array<bool> allow (true, true);
-
       Direction d = LEFT;
-      do {
-       if (Note_head::has_interface (me->get_bound (d)))
-         {
-           Grob *stem = unsmob_grob (me->get_bound (d)->get_object ("stem"));
-           if (get_grob_direction (stem) == dir
-               && -d == dir)
-             allow[d] = false;
-         }
-      } while (flip (&d) != LEFT);
-
-      if (allow[LEFT] && allow[RIGHT])
+      Real gap = robust_scm2double (me->get_property ("x-gap"), 0.2);
+      do
        {
-         staff_position += dir;
-         do
+         attachments[d]
+           = robust_relative_extent (me->get_bound (d),
+                                     common[X_AXIS],
+                                     X_AXIS)[-d]
+           - gap * d;
+       }
+      while (flip (&d) != LEFT);
+  
+      if (attachments.length () < 0.6 * staff_space)
+       {
+         /*
+           Let short ties start over note heads, instead of between.
+         */
+         Drul_array<bool> allow (true, true);
+
+         Direction d = LEFT;
+         do {
+           if (Note_head::has_interface (me->get_bound (d)))
+             {
+               Grob *stem = unsmob_grob (me->get_bound (d)->get_object ("stem"));
+               if (get_grob_direction (stem) == dir
+                   && -d == dir)
+                 allow[d] = false;
+             }
+         } while (flip (&d) != LEFT);
+
+         if (allow[LEFT] && allow[RIGHT])
            {
-             if (Note_head::has_interface (me->get_bound (d)))
+             staff_position += dir;
+             do
                {
-                 Interval extent
-                   = robust_relative_extent (me->get_bound (d),
-                                             common[X_AXIS], X_AXIS);
-
-                 attachments[d] = extent.linear_combination (- 0.5 * d);
-                 in_between = false;
+                 if (Note_head::has_interface (me->get_bound (d)))
+                   {
+                     Interval extent
+                       = robust_relative_extent (me->get_bound (d),
+                                                 common[X_AXIS], X_AXIS);
+
+                     attachments[d] = extent.linear_combination (- 0.5 * d);
+                     in_between = false;
+                   }
                }
+             while (flip (&d) != LEFT);
            }
-         while (flip (&d) != LEFT);
        }
     }
-
   SCM details = me->get_property ("details");
 
   SCM limit
@@ -213,7 +214,7 @@ Tie::get_configuration (Grob *me_grob,
   Offset middle = b.curve_point (0.5);
   Offset edge = b.curve_point (0.0);
 
-  staff_position = rint (staff_position);
+  staff_position = int (rint (staff_position));
   
   Real dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]);
   bool in_space = !(Staff_symbol_referencer::on_staffline (me, (int) staff_position));
@@ -248,17 +249,6 @@ Tie::get_configuration (Grob *me_grob,
        }
     }
 
-  /*
-    Putting larger in-space ties next to the notes forces
-    the edges to be opposite (Y-wise) to the tie direction.
-   */
-  if (staff_position == tie_position
-      && in_space
-      && dy > 0.3 * staff_space)
-    {
-      staff_position += 2 * dir; 
-    }
-
   if (in_space != fits_in_space)
     {
       if (in_space)
@@ -272,6 +262,18 @@ Tie::get_configuration (Grob *me_grob,
        }
     }
 
+
+  /*
+    Putting larger in-space ties next to the notes forces
+    the edges to be opposite (Y-wise) to the tie direction.
+   */
+  if (staff_position == tie_position
+      && in_space
+      && dy > 0.3 * staff_space)
+    {
+      staff_position += 2 * dir; 
+    }
+
   if (!in_between
       && in_space
       && fabs (staff_position - tie_position) <= 1)
@@ -290,14 +292,12 @@ Tie::get_configuration (Grob *me_grob,
 
          Real center = (edge[Y_AXIS] + middle[Y_AXIS])/2.0;
 
-         conf->edge_y_ = staff_position * staff_space * 0.5
-           - center;
+         conf->delta_y_ = - center;
        }
       else
        {
-         conf->edge_y_ = 
-           (staff_position - dir) * staff_space * 0.5
-           + dir * 0.2 * staff_space;
+         conf->delta_y_ = 
+           dir * staff_space * (- 0.3);
        }
     }
   else
@@ -305,24 +305,23 @@ Tie::get_configuration (Grob *me_grob,
       Real where = 0.5 * dir;
       
       Real rounding_dy = (where - middle[Y_AXIS]);
-      conf->edge_y_ = 0.5 * staff_position * staff_space + rounding_dy;
+      conf->delta_y_ = rounding_dy;
 
       if (dir * b.curve_point (0.0)[Y_AXIS] <
          dir * tie_position * 0.5 * staff_space)
-       conf->edge_y_ +=  staff_space * dir; 
+       conf->delta_y_ +=  staff_space * dir; 
     }
 
-  conf->position_ = staff_position;
   conf->dir_ = dir;
+  conf->position_ = staff_position;
   conf->attachment_x_ = attachments;
 }
 
 
-SCM
-Tie::get_control_points (SCM smob)
+void
+Tie::set_default_control_points (Grob *me_grob)
 {
-  Spanner *me = unsmob_spanner (smob);
-
+  Spanner *me = dynamic_cast<Spanner*> (me_grob);
   Grob *common[NO_AXES] = {
     0, 0
   };
@@ -334,31 +333,46 @@ Tie::get_control_points (SCM smob)
     }
   
   Tie_configuration conf;
-  get_configuration (me, common, &conf);
+  if (!get_grob_direction (me))
+    set_grob_direction (me, get_default_dir (me));
+
+  int tie_position = (int) Tie::get_position (me);
+  conf.position_ = tie_position;
+
   
+  get_configuration (me, common, &conf);
+  set_control_points (me, common, conf);
+}
+
+void
+Tie::set_control_points (Grob *me,
+                        Grob **common,
+                        Tie_configuration const &conf)
+{
   SCM details = me->get_property ("details");
   SCM limit
     = scm_assq (ly_symbol2scm ("height-limit"), details);
 
+  Real staff_space = Staff_symbol_referencer::staff_space (me);
   Real h_inf = robust_scm2double (scm_cdr (limit), 0.75) * staff_space;
   Real r_0 = robust_scm2double (scm_cdr (scm_assq (ly_symbol2scm ("ratio"),
                                                   details)),
                                .333);
 
-  Bezier b = slur_shape (conf->attachment_x_.length(),
+  Bezier b = slur_shape (conf.attachment_x_.length(),
                         h_inf, r_0);
-  b.scale (1, conf->dir_);
-  
-  Bezier b;
-  
-  b.translate (Offset (conf->attachment_x_[LEFT]
-                      - me->relative_coordinate (common[X_AXIS], X_AXIS), 0));
+  b.scale (1, conf.dir_);
+  b.translate (Offset (conf.attachment_x_[LEFT]
+                      - me->relative_coordinate (common[X_AXIS], X_AXIS),
+                      0.5 * conf.position_ * staff_space 
+                      + conf.delta_y_
+                      ));
   
   SCM controls = SCM_EOL;
   for (int i = 4; i--;)
     controls = scm_cons (ly_offset2scm (b.control_[i]), controls);
 
-  return controls;
+  me->set_property ("control-points", controls);
 }
 
 
@@ -369,11 +383,14 @@ Tie::print (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
 
+  if (CENTER == get_grob_direction (me))
+    set_direction (me);
+      
   SCM cp = me->get_property ("control-points");
-  if (!scm_is_pair (cp))               // list is more accurate
+  if (!scm_is_pair (cp))
     {
-      cp = get_control_points (smob);
-      me->set_property ("control-points", cp);
+      set_default_control_points (me);
+      cp = me->get_property ("control-points");
     }
 
   if (!scm_is_pair (cp))
@@ -410,16 +427,30 @@ Tie::print (SCM smob)
 
 ADD_INTERFACE (Tie,
               "tie-interface",
+              
               "A tie connecting two noteheads.\n",
               
               "control-points "
-              "dash-fraction"
+              "dash-fraction "
               "dash-period "
               "details "
               "direction "
-              "head-pair "
               "thickness "
               "x-gap ");
 
+int
+Tie_configuration::compare (Tie_configuration const &a,
+                           Tie_configuration const &b)
+{
+  if (a.position_ - b.position_)
+    return sign (a.position_ - b.position_);
+  return sign (a.dir_ - b.dir_);
+}
+                           
 
-
+Tie_configuration::Tie_configuration ()
+{
+  dir_ = CENTER;
+  position_ = 0;
+  delta_y_ = 0.0;
+}
index d211476bbb4e48ffe4ec0b85ba620277a5d8d6d6..18297e98aba6bbdb9015543d78ebeda8d0257b21 100644 (file)
@@ -156,7 +156,7 @@ pitchedTrill =
             )))
      
      (if (ly:pitch? trill-pitch)
-        (for-each (lambda (m) (ly:music-set-property! m 'trill-pitch trill-pitch))
+        (for-each (lambda (m) (ly:music-set-property! m 'pitch trill-pitch))
                   trill-events)
         (begin
           (ly:warning (_ "Second argument of \\pitchedTrill should be single note: "))
index 05c57821361d0bd2dc2a6d8b2817049a29e0c15e..fbf38dc1ded04bb0b1e5bd3b7aca1ef1d705ed52 100644 (file)
@@ -583,9 +583,10 @@ entries @code{name} and @code{interfaces}.")
      ;; TODO: use interface for this!
      (chord-tremolo ,boolean? "if set, this beam is a tremolo. ")
      (begin-of-line-visible ,boolean? "Used for marking ChordNames that should only show changes.")
-     (head-pair ,pair? "Pair of grob pointers, pointing to the two heads of the tie.")
+
      (quant-score ,string? "Beam quanting score -- can be stored for
 debugging")
+     
      (least-squares-dy ,number? 
                       "ideal beam slope, without damping.")
      (ligature-primitive-callback ,procedure? "callback that brews ligature head.")
index fdc5145cfe4bad85965e8ed2e8c965d1ea476fee..b01bb0a91a13c5f21cc930a90d4274e4e2e12d75 100644 (file)
        (print-function . ,Tie::print)
        (details . ((ratio . 0.333) (height-limit . 1.0)))
        (thickness . 1.0)
-       (y-offset . 0.6)
-       (minimum-length . 2.5)
        (meta . ((class . Spanner)
                 (interfaces . (tie-interface))))))