]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/include/tie.hh (struct Tie_details): add x_gap_
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 12 Sep 2005 10:29:33 +0000 (10:29 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 12 Sep 2005 10:29:33 +0000 (10:29 +0000)
(struct Tie_configuration): add head_position_

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

lily/include/tie.hh
lily/tie-column.cc
lily/tie-helper.cc
lily/tie.cc

index 0f407b0ea555ad73bbfb7c5952c37999809f6e08..7327dbd4c4733d9cdefaf2b07ce9b3a5358d5cea 100644 (file)
@@ -24,6 +24,7 @@ struct Tie_details
   Real height_limit_;
   Real ratio_;
   Real staff_space_;
+  Real x_gap_;
   
   Tie_details ();
   void init (Grob *);
@@ -31,7 +32,9 @@ struct Tie_details
   
 struct Tie_configuration
 {
-  Real position_;
+  int head_position_;
+  int position_;
+  
   Direction dir_;
   Interval attachment_x_;
   Real delta_y_;
index 670211562d28d65f5e12eb3441f1a506ed63770c..70b2041067cb9ca44ff5bb10e2e7f5a3329d7e0c 100644 (file)
@@ -9,12 +9,10 @@
 #include "tie-column.hh"
 
 #include <math.h>
-
 #include <map>
 #include <set>
 
-
-#include "stencil.hh"
+#include "note-head.hh"
 #include "stem.hh"
 #include "skyline.hh"
 #include "staff-symbol-referencer.hh"
@@ -93,134 +91,242 @@ Tie_column::before_line_breaking (SCM smob)
 }
 
 
-
 void
-set_chord_outlines (Drul_array< Array<Skyline_entry> > *skyline_drul,
-                   Link_array<Grob> ties,
-                   Grob *common)
+set_chord_outline (Array<Skyline_entry> *skyline,
+                  Link_array<Item> bounds,
+                  Grob *common,
+                  Direction d)
 {
-  Direction d = LEFT;
+  Real staff_space = Staff_symbol_referencer::staff_space (bounds[0]);
 
-  Real staff_space = Staff_symbol_referencer::staff_space (ties[0]);
-  do
+  Array<Box> boxes;
+  Interval x_union;
+
+  Grob *stem = 0;
+  for (int i = 0; i < bounds.size (); i++)
     {
-      Array<Box> boxes;
-      Interval x_union;
+      Grob *head = bounds[i];
+      if (!Note_head::has_interface (head))
+       continue;
+      
+      if (!stem)
+       stem = unsmob_grob (head->get_object ("stem"));
+         
+      Real p = Staff_symbol_referencer::get_position (head);
+      Interval y ((p-1) * 0.5 * staff_space,
+                 (p+1) * 0.5 * staff_space);
 
-      Grob *stem = 0;
-      for (int i = 0; i < ties.size (); i++)
-       {
-         Spanner *tie = dynamic_cast<Spanner*> (ties[i]);
+      Interval x = head->extent (common, X_AXIS);
+      boxes.push (Box (x, y));
+      x_union.unite (x);
+    }
 
-         Grob *head = Tie::head (tie, d);
-         if (!head)
-           continue;
+  (*skyline) = empty_skyline (-d);
 
-         if (!stem)
-           stem = unsmob_grob (head->get_object ("stem"));
+  if (bounds[0]->break_status_dir ())
+    {
+      Real x = robust_relative_extent (bounds[0],  common, X_AXIS)[-d];
+      skyline->elem_ref (0).height_ = x; 
+    }
+         
+  for (int i = 0; i < boxes.size (); i++)
+    insert_extent_into_skyline (skyline,
+                               boxes[i], Y_AXIS, -d);
+  if (stem
+      && !Stem::is_invisible (stem))
+    {
+      Interval x;
+      x.add_point (stem->relative_coordinate (common, X_AXIS));
+      x.widen (staff_space / 20); // ugh.
+      Interval y;
+      y.add_point (Stem::stem_end_position (stem) * staff_space * .5);
+
+      Direction stemdir = Stem::get_direction (stem);
+      y.add_point (Stem::head_positions (stem)[-stemdir]
+                  * staff_space * .5);
          
-         Real p = Tie::get_position (tie);
-         Interval y ((p-1) * 0.5 * staff_space,
-                     (p+1) * 0.5 * staff_space);
+      insert_extent_into_skyline (skyline, Box (x,y), Y_AXIS, -d);
+
+
 
-         Interval x = head->extent (common, X_AXIS);
-         boxes.push (Box (x, y));
-         x_union.unite (x);
+      if (d == LEFT)
+       {
+         Box flag_box = Stem::get_translated_flag (stem).extent_box ();
+         flag_box.translate( Offset (x[RIGHT], X_AXIS));
+         insert_extent_into_skyline (skyline, flag_box,
+                                     Y_AXIS, -d);
+       }
+    }
+  
+  Direction updowndir = DOWN;
+  do
+    {
+      Interval x ;
+      Interval y;
+      if (boxes.size())
+       {
+         Box b = boxes.boundary (updowndir, 0);
+         x = b[X_AXIS];
+         x[-d] =  b[X_AXIS].linear_combination (-d / 2);
+         y[-updowndir] = b[Y_AXIS][updowndir];
+         y[updowndir] = updowndir * infinity_f;
        }
 
-      (*skyline_drul)[d] = empty_skyline (-d);
+      if (!x.is_empty ())
+       insert_extent_into_skyline (skyline,
+                                   Box (x,y),
+                                   Y_AXIS, -d);
+    }
+  while (flip (&updowndir) != DOWN);
+
+  for (int i = 0; i < bounds.size (); i++)
+    {
+      if (!Note_head::has_interface (bounds[i]))
+       continue;
+
       
-      Spanner *tie = dynamic_cast<Spanner*> (ties[0]);
-      if (tie->get_bound (d)->break_status_dir ())
+      Grob *dots = unsmob_grob (bounds[i]->get_object ("dot"));
+      if (dots && d == LEFT)
        {
-         Real x = robust_relative_extent (tie->get_bound (d),
-                                          common,
-                                          X_AXIS)[-d];
+         Interval x = dots->extent (common, X_AXIS);
+         Real p = Staff_symbol_referencer::get_position (dots);
+             
+         Interval y (-1,1);
+         y *= (staff_space /4);
+         y.translate (p * staff_space * .5);
 
-         (*skyline_drul)[d].elem_ref (0).height_ = x; 
+         insert_extent_into_skyline (skyline,
+                                     Box (x,y), Y_AXIS, -d);
        }
-         
-      for (int i = 0; i < boxes.size (); i++)
-       insert_extent_into_skyline (&skyline_drul->elem_ref (d),
-                                   boxes[i], Y_AXIS, -d);
-      if (stem
-         && !Stem::is_invisible (stem))
+    }
+}
+
+void
+set_chord_outlines (Drul_array< Array<Skyline_entry> > *skyline_drul,
+                   Link_array<Grob> ties,
+                   Grob *common)
+{
+  Direction d = LEFT;
+
+  do
+    {
+      Link_array<Item> bounds;
+      
+      for (int i = 0; i < ties.size (); i++)
        {
-         Interval x;
-         x.add_point (stem->relative_coordinate (common, X_AXIS));
-         x.widen (staff_space / 20); // ugh.
-         Interval y;
-         y.add_point (Stem::stem_end_position (stem) * staff_space * .5);
-
-         Direction stemdir = Stem::get_direction (stem);
-         y.add_point (Stem::head_positions (stem)[-stemdir]
-                      * staff_space * .5);
-         
-         insert_extent_into_skyline (&skyline_drul->elem_ref (d),
-                                     Box (x,y), Y_AXIS, -d);
+         Item *it = dynamic_cast<Spanner*> (ties[i])->get_bound (d);
+                                            
+         bounds.push (it);
+       }
+      
+      set_chord_outline (&skyline_drul->elem_ref (d),
+                        bounds, common, d);
+    }
+  while (flip (&d) != LEFT);
+}
 
+void
+shift_small_ties (Array<Tie_configuration> *tie_configs,
+                 Grob *staff_referencer,
+                 Tie_details const &details)
+{
+  set<int> positions_taken;
+  for (int i = 0; i < tie_configs->size (); i++)
+    positions_taken.insert (int (rint (tie_configs->elem (i).position_)));
 
+  for (int i = 0; i < tie_configs->size (); i++)
+    {
+      Tie_configuration * conf = &tie_configs->elem_ref (i);
 
-         if (d == LEFT)
-           {
-             Box flag_box = Stem::get_translated_flag (stem).extent_box ();
-             flag_box.translate( Offset (x[RIGHT], X_AXIS));
-             insert_extent_into_skyline (&skyline_drul->elem_ref (d),
-                                         flag_box,
-                                         Y_AXIS, -d);
-           }
-       }
+      /*
+       on staff line and small enough, translate a little further 
+      */
+      Real h = conf->height (details);
+      bool next_free = positions_taken.find (int (rint (conf->position_ + conf->dir_)))
+       == positions_taken.end ();
 
+      int rounded_pos = int (rint (conf->position_ + conf->delta_y_ / details.staff_space_));
+      bool on_line = Staff_symbol_referencer::on_staffline (staff_referencer, rounded_pos);
       
+      if (next_free)
+       if (on_line && h < 0.4 * details.staff_space_)
+         {
+           positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
+           conf->delta_y_ += 0.2 * details.staff_space_ * conf->dir_;
+         }
+       else if (!on_line && h > 0.6 * details.staff_space_)
+         {
+           positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
+           conf->delta_y_ += 0.5 * details.staff_space_ * conf->dir_;
+         }
+    }
+}
 
 
-      Direction updowndir = DOWN;
-      do
+void
+final_shape_adjustment (Tie_configuration &conf,
+                       Drul_array< Array<Skyline_entry> > const &skylines,
+                       Grob *staff_referencer,
+                       Tie_details const &details)
+{
+  Real line_dy = 0.0;
+  bool on_line = Staff_symbol_referencer::on_staffline (staff_referencer,
+                                                       int (rint (conf.position_)));
+  if (on_line)
+    line_dy = - sign (conf.height (details) - 0.6 * details.staff_space_)
+      * 0.2 * details.staff_space_ * conf.dir_;
+
+  Real y = conf.position_ * details.staff_space_ * 0.5
+    + line_dy;
+  
+  conf.attachment_x_ = get_skyline_attachment (skylines, y);
+  conf.attachment_x_.intersect (get_skyline_attachment (skylines,
+                                                       y + conf.dir_ * details.staff_space_ * 0.5));
+
+  conf.delta_y_ += line_dy;
+  conf.attachment_x_.widen (-details.x_gap_);
+  if (!on_line
+      && Staff_symbol_referencer::staff_radius (staff_referencer) * details.staff_space_ > y)
+    conf.center_tie_vertically (details);
+}
+
+void
+set_tie_config_directions (Array<Tie_configuration> *tie_configs_ptr)
+{
+  Array<Tie_configuration> &tie_configs (*tie_configs_ptr);
+  
+  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)
        {
-         Interval x ;
-         Interval y;
-         if (boxes.size())
-           {
-             Box b = boxes.boundary (updowndir, 0);
-             x = b[X_AXIS];
-             x[-d] =  b[X_AXIS].linear_combination (-d / 2);
-             y[-updowndir] = b[Y_AXIS][updowndir];
-             y[updowndir] = updowndir * infinity_f;
-           }
-
-         if (!x.is_empty ())
-           insert_extent_into_skyline (&skyline_drul->elem_ref (d),
-                                       Box (x,y),
-                                       Y_AXIS, -d);
+         if (!tie_configs[i-1].dir_)
+           tie_configs[i-1].dir_ = DOWN;
+         if (!tie_configs[i].dir_)
+           tie_configs[i].dir_ = UP;
        }
-      while (flip (&updowndir) != DOWN);
+    }
 
-      for (int i = 0; i < ties.size (); i++)
-       {
-         Spanner *tie = dynamic_cast<Spanner*> (ties[i]);
-         Grob *head = Tie::head (tie, d);
-         if (!head)
-           continue;
-
-         Grob *dots = unsmob_grob (head->get_object ("dot"));
-         if (dots && d == LEFT)
-           {
-             Interval x = dots->extent (common, X_AXIS);
-             Real p = Staff_symbol_referencer::get_position (dots);
-             
-             Interval y (-1,1);
-             y *= (staff_space /4);
-             y.translate (p * staff_space * .5);
+  for (int i = 1; i < tie_configs.size() - 1; i++)
+    {
+      if (tie_configs[i].dir_)
+       continue;
 
-             insert_extent_into_skyline (&skyline_drul->elem_ref (d),
-                                         Box (x,y), Y_AXIS, -d);
-           }
-       }
+      Direction position_dir = (Direction) sign (tie_configs[i].position_);
+      if (!position_dir)
+       position_dir = DOWN;
       
+      tie_configs[i].dir_ = position_dir;
     }
-  while (flip (&d) != LEFT);
 }
-
+                          
 
 void
 Tie_column::new_directions (Grob *me)
@@ -258,41 +364,15 @@ Tie_column::new_directions (Grob *me)
        continue;
 
       manual_override = true;
-      tie_configs[k].position_ = robust_scm2double (scm_car (entry), tie_configs[k].position_);
+      Real complete_pos = robust_scm2double (scm_car (entry), tie_configs[k].position_);
+      
+      tie_configs[k].position_ = int (rint (complete_pos));
+      tie_configs[k].delta_y_ = complete_pos - tie_configs[k].position_;
       tie_configs[k].dir_ = Direction (robust_scm2int (scm_cdr (entry), tie_configs[k].dir_));
       k ++;
     }
 
-  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;
-
-      Direction position_dir = (Direction) sign (tie_configs[i].position_);
-      if (!position_dir)
-       position_dir = DOWN;
-      
-      tie_configs[i].dir_ = position_dir;
-    }
+  set_tie_config_directions (&tie_configs);
 
   Grob *common = me;
   for (int i = 0; i < ties.size (); i++)
@@ -326,74 +406,26 @@ Tie_column::new_directions (Grob *me)
   /*
     Calculate final width and shape of the ties.
    */
-  Real staff_space = Staff_symbol_referencer::staff_space (ties[0]);
-  Real gap = robust_scm2double (ties[0]->get_property ("x-gap"), 0.2);
   for (int i = 0; i < ties.size(); i++)
     {
       if (!manual_override
          && (i == 0 || i == ties.size () -1))
        continue;
-      
-      Tie_configuration conf = tie_configs[i];
-      conf = tie_configs[i];
-
-      Real line_dy = 0.0;
-      bool on_line = Staff_symbol_referencer::on_staffline (ties[0],
-                                                           int (rint (conf.position_)));
-      if (on_line)
-       line_dy = - sign (conf.height (details) - 0.6 * staff_space)
-         * 0.2 * staff_space * conf.dir_;
-
-      Real y = conf.position_ * staff_space * 0.5
-       + line_dy;
-      conf.attachment_x_
-       = get_skyline_attachment (skylines, y);
-      conf.attachment_x_.intersect (get_skyline_attachment (skylines,
-                                                           y + conf.dir_ * staff_space * .5));
-
-
-      conf.delta_y_ += line_dy;
-      conf.attachment_x_.widen (-gap);
-      if (!on_line
-         && Staff_symbol_referencer::staff_radius (ties[0]) * staff_space > y)
-       conf.center_tie_vertically (details);
-             
-      tie_configs[i] = conf;
+
+
+      final_shape_adjustment (tie_configs[i],
+                             skylines,
+                             ties[0],
+                             details);
     }
 
+  
   /*
     Try to shift small ties into available spaces.
    */
   if (!manual_override)
     {
-      set<int> positions_taken; 
-      for (int i = 0; i < tie_configs.size (); i++)
-       positions_taken.insert (int (rint (tie_configs[i].position_)));
-
-      for (int i = 0; i < tie_configs.size (); i++)
-       {
-         Tie_configuration * conf = &tie_configs.elem_ref (i);
-
-         /*
-           on staff line and small enough, translate a little further 
-          */
-         Real h = conf->height (details);
-         bool next_free = positions_taken.find (int (rint (conf->position_ + conf->dir_)))
-           == positions_taken.end ();
-         bool on_line = Staff_symbol_referencer::on_staffline (ties[0],
-                                                               int (rint (conf->position_ + conf->delta_y_)));
-         if (next_free)
-           if (on_line && h < 0.4 * staff_space)
-             {
-               positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
-               conf->delta_y_ += 0.2 * staff_space * conf->dir_;
-             }
-           else if (!on_line && h > 0.6 * staff_space)
-             {
-               positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
-               conf->delta_y_ += 0.5 * staff_space * conf->dir_;
-             }
-       }
+      shift_small_ties (&tie_configs, ties[0], details);
     }
   
   for (int i = 0; i < ties.size(); i++)
@@ -408,6 +440,8 @@ Tie_column::new_directions (Grob *me)
 
 ADD_INTERFACE (Tie_column, "tie-column-interface",
               "Object that sets directions of multiple ties in a tied chord",
+
+              /* properties */
               "positioning-done "
               "tie-configuration "
               );
index 1d49dd5aab45e81a79490d5fd103e1597ed3f134..132e7c303cb7494baa50e0ebb77c0642056c8a98 100644 (file)
@@ -96,6 +96,9 @@ Tie_details::init (Grob *me)
   height_limit_ = robust_scm2double (scm_cdr (limit), 0.75) * staff_space_;
   ratio_ = robust_scm2double (scm_cdr (scm_assq (ly_symbol2scm ("ratio"), details)),
                              .333);
+
+  x_gap_ = robust_scm2double (me->get_property ("x-gap"), 0.2);
+
 }
 
 Tie_details::Tie_details ()
index a4c5aaa929a8dc0aa9f285741cedaf3006b18d24..8c812e811e9074226c40e6980f8b0a0564ee7a5b 100644 (file)
@@ -207,53 +207,43 @@ Tie::get_configuration (Grob *me_grob, Grob *common,
   /*
     UGH. Don't mirror Tie_configuration.
    */
-  Direction dir = CENTER;
-  
-  int tie_position = (int) Tie::get_position (me);
-  int staff_position = (int) conf->position_;
-
-  if (conf->dir_)
-    {
-      dir = conf->dir_;
-    }
-  else
-    {
-      dir = get_grob_direction (me);
-      if (!dir)
-       dir = get_default_dir (me);
-    }
+  conf->head_position_ = (int) Tie::get_position (me);
+  if (!conf->dir_)
+    conf->dir_ = get_grob_direction (me);
+  if (!conf->dir_)
+    conf->dir_ = get_default_dir (me);
+    
 
   Real staff_space = details.staff_space_;
-
   bool in_between = true;
-  Interval attachments = conf->attachment_x_;
   Real gap = robust_scm2double (me->get_property ("x-gap"), 0.2);
-  if (attachments.is_empty())
+
+  if (conf->attachment_x_.is_empty())
     {
       if (!skylines)
-       attachments = get_default_attachments (me, common, gap,
-                                              &staff_position,
+       conf->attachment_x_ = get_default_attachments (me, common, gap,
+                                              &conf->position_,
                                               &in_between);
       else
        {
-         Real y = staff_space * 0.5 * staff_position;
-         attachments = get_skyline_attachment (*skylines, y);
-         attachments.widen (-gap);
+         Real y = staff_space * 0.5 * conf->position_;
+         conf->attachment_x_ = get_skyline_attachment (*skylines, y);
+         conf->attachment_x_.widen (-gap);
        }
     }
 
-  Bezier b = slur_shape (attachments.length(),
+  Bezier b = slur_shape (conf->attachment_x_.length(),
                         details.height_limit_,
                         details.ratio_);
-  b.scale (1, dir);
+  b.scale (1, conf->dir_);
   
   Offset middle = b.curve_point (0.5);
   Offset edge = b.curve_point (0.0);
 
-  staff_position = int (rint (staff_position));
+  conf->position_ = int (rint (conf->position_));
   
   Real dy = fabs (middle[Y_AXIS] - edge[Y_AXIS]);
-  bool in_space = !(Staff_symbol_referencer::on_staffline (me, (int) staff_position));
+  bool in_space = !(Staff_symbol_referencer::on_staffline (me, (int) conf->position_));
   bool fits_in_space =
     (dy < 0.6 * staff_space);
   
@@ -265,18 +255,18 @@ Tie::get_configuration (Grob *me_grob, Grob *common,
     ? int (Staff_symbol_referencer::get_position (left_dot))
     : 0;
   if (left_dot
-      && (staff_position == dot_pos
-         || staff_position + dir == dot_pos))
+      && (conf->position_ == dot_pos
+         || conf->position_ + conf->dir_ == dot_pos))
     {
-      staff_position += dir;
+      conf->position_ += conf->dir_;
       in_space = !in_space;
 
       if (skylines)
        {
-         Real y = staff_space * 0.5 * staff_position;
-         attachments = get_skyline_attachment (*skylines, y);
-         attachments.widen (-gap);
-         Bezier b = slur_shape (attachments.length(),
+         Real y = staff_space * 0.5 * conf->position_;
+         conf->attachment_x_ = get_skyline_attachment (*skylines, y);
+         conf->attachment_x_.widen (-gap);
+         Bezier b = slur_shape (conf->attachment_x_.length(),
                                 details.height_limit_,
                                 details.ratio_);
          Offset middle = b.curve_point (0.5);
@@ -294,10 +284,10 @@ Tie::get_configuration (Grob *me_grob, Grob *common,
   if (left_stem)
     {
       Stencil flag = Stem::get_translated_flag (left_stem);
-      Real y = staff_position * staff_space * 0.5;
+      Real y = conf->position_ * staff_space * 0.5;
       if (flag.extent (Y_AXIS).contains (y))
        {
-         staff_position += dir;
+         conf->position_ += conf->dir_;
          in_space = !in_space;
        }
     }
@@ -306,12 +296,12 @@ Tie::get_configuration (Grob *me_grob, Grob *common,
     {
       if (in_space)
        {
-         staff_position += dir;
+         conf->position_ += conf->dir_;
        }
       else
        {
          in_space = true;
-         staff_position += dir;
+         conf->position_ += conf->dir_;
        }
 
       /*
@@ -319,11 +309,11 @@ Tie::get_configuration (Grob *me_grob, Grob *common,
        */
       if (skylines)
        {
-         Real y = staff_space * 0.5 * staff_position;
-         attachments = get_skyline_attachment (*skylines, y);
-         attachments.widen (-gap);
+         Real y = staff_space * 0.5 * conf->position_;
+         conf->attachment_x_ = get_skyline_attachment (*skylines, y);
+         conf->attachment_x_.widen (-gap);
              
-         Bezier b = slur_shape (attachments.length(),
+         Bezier b = slur_shape (conf->attachment_x_.length(),
                                 details.height_limit_,
                                 details.ratio_);
          Offset middle = b.curve_point (0.5);
@@ -339,58 +329,53 @@ Tie::get_configuration (Grob *me_grob, Grob *common,
     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
+  if (conf->position_ == conf->head_position_
       && in_space
-      && Staff_symbol_referencer::staff_radius (me) > fabs (staff_position) / 2
+      && Staff_symbol_referencer::staff_radius (me) > fabs (conf->position_) / 2
       && dy > 0.3 * staff_space)
     {
-      staff_position += 2 * dir
+      conf->position_ += 2 * conf->dir_
     }
 
   if (!in_between
       && in_space
-      && fabs (staff_position - tie_position) <= 1)
-    staff_position += 2*dir;
+      && fabs (conf->position_ - conf->head_position_) <= 1)
+    conf->position_ += 2*conf->dir_;
   
   
-  conf->dir_ = dir;
-  conf->position_ = staff_position;
   if (in_space)
     {
-      if ((fabs (staff_position - tie_position) <= 1
+      if ((fabs (conf->position_ - conf->head_position_) <= 1
           && fabs (dy) < 0.45 * staff_space)
          || fabs (dy) < 0.6 * staff_space)
        {
          /*
            vertically center in space.
          */
-         conf->dir_ = dir;
-         conf->position_ = staff_position;
-         conf->attachment_x_ = attachments;
          conf->center_tie_vertically (details);
        }
       else
        {
          conf->delta_y_ = 
-           dir * staff_space * (- 0.3);
+           conf->dir_ * staff_space * (- 0.3);
        }
     }
   else
     {
-      Real where = 0.5 * dir;
+      Real where = 0.5 * conf->dir_;
       
       Real rounding_dy = (where - middle[Y_AXIS]);
       conf->delta_y_ = rounding_dy;
 
-      if (dir * (b.curve_point (0.0)[Y_AXIS]
+      if (conf->dir_ * (b.curve_point (0.0)[Y_AXIS]
                 + conf->position_ * staff_space * 0.5
                 + conf->delta_y_) <
-         dir * tie_position * 0.5 * staff_space)
+         conf->dir_ * conf->head_position_ * 0.5 * staff_space)
        {
-         if (Staff_symbol_referencer::staff_radius (me) >  fabs (tie_position) / 2)
-           conf->position_ +=  2 * dir;
+         if (Staff_symbol_referencer::staff_radius (me) >  fabs (conf->head_position_) / 2)
+           conf->position_ +=  2 * conf->dir_;
          else
-           conf->position_ += dir;
+           conf->position_ += conf->dir_;
        }
     }
 
@@ -398,13 +383,11 @@ Tie::get_configuration (Grob *me_grob, Grob *common,
   if (skylines)
     {
       Real half_space = 0.5 * staff_space;
-      Real y = staff_position * half_space;
+      Real y = conf->position_ * half_space;
       
-      attachments = get_skyline_attachment (*skylines, y);
-      
-      attachments.widen (-gap);
+      conf->attachment_x_ = get_skyline_attachment (*skylines, y);
+      conf->attachment_x_.widen (-gap);
     }
-  conf->attachment_x_ = attachments;
 }
 
 
@@ -524,7 +507,8 @@ ADD_INTERFACE (Tie,
               "tie-interface",
               
               "A tie connecting two noteheads.\n",
-              
+
+              /* properties */
               "control-points "
               "dash-fraction "
               "dash-period "