]> git.donarmstrong.com Git - lilypond.git/commitdiff
new file.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 18 Jul 2004 20:26:33 +0000 (20:26 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 18 Jul 2004 20:26:33 +0000 (20:26 +0000)
input/mutopia/W.A.Mozart/mozart-hrn3-allegro.ily
lily/include/slur.hh
lily/new-slur.cc
lily/phrasing-slur-engraver.cc
lily/slur-engraver.cc
lily/slur-quanting.cc [new file with mode: 0644]
lily/slur.cc
scm/define-grobs.scm

index b51ac1f0bb9068ab42792c35df9436f29d7e176b..16318c38a6514c803aec6d2734c14be0201f93ad 100644 (file)
@@ -157,7 +157,7 @@ allegro =
   \revert Stem #'stroke-style }
   e8[)( d16  c)]
 
-       << d1\trill (
+       << d1\trill _(
          { s2 \grace {
   \override Stem   #'stroke-style = #"grace"
     c16[ d] 
index 166c9f16317c7e8a929f697e3cf07cd316f7df52..4dc24503102a22cf357896cd9c6f8500ff8441f5 100644 (file)
@@ -11,7 +11,7 @@
 #include "lily-proto.hh"
 #include "rod.hh"
 
-class Slur
+class Old_slur
 {
 public:
   static void add_column (Grob *me, Grob *col);
index 6b9b8611e87ec4fda0a6791d4cff21dd5ea3ba64..3ee7f8aec191f696912e5d5c500077fda6446bf0 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <math.h>
 
+#include "new-slur.hh"
 #include "main.hh"
 #include "font-interface.hh"
 #include "text-item.hh"
 #include "warn.hh"
 #include "beam.hh"
 
-/*
-  TODO:
-
-  - curve around flag for y coordinate
-  - better scoring.
-  - short-cut: try a smaller region first.
-  - collisions with accidentals
-  - collisions with scripts (staccato!)
-  - 
-*/
-struct Encompass_info
-{
-  Real x_;
-  Real stem_;
-  Real head_;
-  Encompass_info ()
-  {
-    x_ = 0.0;
-    stem_ = 0.0;
-    head_ = 0.0;
-  }
-};
-
-struct Bound_info
-{
-  Box stem_extent_;
-  Direction stem_dir_;
-  Grob *bound_;
-  Grob *note_column_;
-  Grob *slur_head_;
-  Grob *staff_;
-  Grob *stem_;
-  Interval slur_head_extent_;
-  Real neighbor_y_;
-  Real staff_space_;
-  
-  Bound_info ()
-  {
-    stem_ = 0;
-    neighbor_y_ = 0;
-    staff_ = 0;
-    slur_head_ = 0;
-    stem_dir_ = CENTER;
-    note_column_ = 0;
-  }
-};
-
-/*
-  TODO: put in details property.
-*/
-struct Slur_score_parameters
-{
-  int SLUR_REGION_SIZE;
-  Real HEAD_ENCOMPASS_PENALTY;
-  Real STEM_ENCOMPASS_PENALTY;
-  Real CLOSENESS_FACTOR;
-  Real EDGE_ATTRACTION_FACTOR;
-  Real SAME_SLOPE_PENALTY;
-  Real STEEPER_SLOPE_FACTOR;
-  Real NON_HORIZONTAL_PENALTY;
-  Real HEAD_STRICT_FREE_SPACE;
-  Real MAX_SLOPE;
-  Real MAX_SLOPE_FACTOR;
-  Real FREE_HEAD_DISTANCE;
-  Slur_score_parameters ();
-};
-
-void
-init_score_param (Slur_score_parameters *score_param)
-{
-  score_param->SLUR_REGION_SIZE = 5;
-  score_param->HEAD_ENCOMPASS_PENALTY = 1000.0;
-  score_param->STEM_ENCOMPASS_PENALTY = 30.0;
-  score_param->CLOSENESS_FACTOR = 10;
-  score_param->EDGE_ATTRACTION_FACTOR = 4;
-  score_param->SAME_SLOPE_PENALTY = 20;
-  score_param->STEEPER_SLOPE_FACTOR = 50;
-  score_param->NON_HORIZONTAL_PENALTY = 15;
-  score_param->HEAD_STRICT_FREE_SPACE = 0.2;
-  score_param->MAX_SLOPE = 1.1;
-  score_param->MAX_SLOPE_FACTOR = 10;
-  score_param->FREE_HEAD_DISTANCE = 0.3;
-}
-
-Slur_score_parameters::Slur_score_parameters()
-{
-  init_score_param (this);
-}
-
-#define DEBUG_SLUR_QUANTING 1
-
-struct Slur_score
-{
-  Drul_array<Offset> attachment_;
-  Real score_;
-  Bezier curve_;
-
-#if DEBUG_SLUR_QUANTING
-  String score_card_;
-#endif
-
-  Slur_score()
-  {
-    score_ = 0.0;
-  }
-};
-
-class New_slur
-{
-public:
-  static void add_column (Grob *me, Grob *col);
-  DECLARE_SCHEME_CALLBACK (print, (SCM));
-  static void score_slopes (Grob *me, Grob *common[],
-                           Slur_score_parameters *score_param,
-                           Drul_array<Bound_info>,
-                           Drul_array<Offset> base_attach,
-                           Array<Slur_score> *scores);
-
-  static void score_edges (Grob *me, Grob *common[],
-                          Slur_score_parameters *score_param,
-                          Drul_array<Bound_info> extremes,
-                          Drul_array<Offset> base_attach,
-                          Array<Slur_score> *scores);
-  static void score_encompass (Grob *me, Grob *common[],
-                              Slur_score_parameters*,
-                              Drul_array<Bound_info>,
-                              Drul_array<Offset>, Array<Slur_score> *scores);
-  static Bezier avoid_staff_line (Grob *me, Grob **common,
-                                 Drul_array<Bound_info> extremes,
-                                 Bezier bez);
-
-  static Encompass_info get_encompass_info (Grob *me,
-                                           Grob *col,
-                                           Grob **common);
-  static void set_interface (Grob *);
-  static bool  has_interface (Grob *);
-  static Bezier get_curve (Grob *me);
-  static Bezier get_bezier (Grob *me, Drul_array<Offset>, Real, Real);
-  static Direction get_default_dir (Grob *me);
-  DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM));
-  DECLARE_SCHEME_CALLBACK (height, (SCM,SCM));
-
-  static void set_end_points (Grob *);
-  static Real get_boundary_notecolumn_y (Grob *me, Direction dir);
-  static Real broken_trend_y (Grob *me, Grob **, Direction dir);
-  static void set_control_points (Grob *me);
-  static Drul_array<Bound_info> get_bound_info (Spanner *me, Grob **common);
-
-  static void generate_curves (Grob *me,
-                              Grob *common[],
-                              Drul_array<Bound_info> extremes,
-                              Drul_array<Offset> base_attach,
-                              Array<Slur_score> *scores);
-  static Array<Slur_score> enumerate_attachments
-  (Grob *me, Grob *common[], Slur_score_parameters *score_param,
-   Drul_array<Bound_info> extremes,
-   Drul_array<Offset> base_attachment, Drul_array<Real> end_ys);
-  static Drul_array<Offset> get_base_attachments
-  (Spanner *sp, Grob **common, Drul_array<Bound_info> extremes);
-  static Drul_array<Real> get_y_attachment_range
-  (Spanner *sp, Grob **common, Drul_array<Bound_info> extremes,
-   Drul_array<Offset> base_attachment);
-};
-
-/* HDIR indicates the direction for the slur.  */
-Real
-New_slur::broken_trend_y (Grob *me, Grob **common, Direction hdir)
-{
-  /* A broken slur should maintain the same vertical trend
-    the unbroken slur would have had.  */
-  Real by = 0.0;
-  if (Spanner *mother = dynamic_cast<Spanner*> (me->original_))
-    {
-      int k = broken_spanner_index (dynamic_cast<Spanner*> (me));
-      int j = k + hdir;
-      if (j < 0 || j >= mother->broken_intos_.size ())
-       return by;
-
-      Grob *neighbor = mother->broken_intos_[j];
-      if (hdir == RIGHT)
-       neighbor->set_property ("direction",
-                               me->get_property ("direction"));
-
-      Spanner *common_mother
-       = dynamic_cast<Spanner*> (common[Y_AXIS]->original_);
-      int common_k
-       = broken_spanner_index (dynamic_cast<Spanner*> (common[Y_AXIS]));
-      int common_j = common_k + hdir;
-
-      if (common_j < 0 || common_j >= common_mother->broken_intos_.size())
-       return by;
-
-      Grob *common_next_system = common_mother->broken_intos_[common_j];
-      Link_array<Grob> neighbor_cols
-       = Pointer_group_interface__extract_grobs (neighbor, (Grob *)0,
-                                                 "note-columns");
-
-      Grob *neighbor_col
-       = (hdir == RIGHT) ? neighbor_cols[0] : neighbor_cols.top ();
-      Grob *neighbor_common
-       = common_next_system->common_refpoint (neighbor_col, Y_AXIS);
-
-      Direction vdir = get_grob_direction (me);
-      Real neighbor_y
-       = neighbor_col->extent (neighbor_common, Y_AXIS)
-       .linear_combination (int(neighbor_cols.size()==1 ? CENTER : vdir))
-       - common_next_system->relative_coordinate (neighbor_common, Y_AXIS);
-
-      Link_array<Grob> my_cols
-       = Pointer_group_interface__extract_grobs (me, (Grob *)0,
-                                                 "note-columns");
-
-      Grob *extreme_col = (hdir == RIGHT) ? my_cols.top() : my_cols[0];
-      Real y = extreme_col->extent (common[Y_AXIS], Y_AXIS)
-       .linear_combination (int ((my_cols.size() == 1) ? CENTER : vdir));
-      by = (y*neighbor_cols.size() + neighbor_y*my_cols.size()) /
-       (my_cols.size() + neighbor_cols.size());
-    }
-  return by;
-}
-
-void
-New_slur::set_interface (Grob*me)
-{
-  /* Copy to mutable list. */
-  me->set_property ("attachment",
-                   ly_deep_copy (me->get_property ("attachment")));
-}
-
-void
-New_slur::add_column (Grob*me, Grob*n)
-{
-  Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-columns"), n);
-  me->add_dependency (n);
-
-  add_bound_item (dynamic_cast<Spanner*> (me), dynamic_cast<Item*> (n));
-}
-
-Encompass_info
-New_slur::get_encompass_info (Grob *me,
-                             Grob *col,
-                             Grob **common)
-{
-  Grob* stem = unsmob_grob (col->get_property ("stem"));
-
-  Encompass_info ei;
-
-  Direction dir = get_grob_direction (me);
-
-  if (!stem)
-    {
-      programming_error ("No stem for note column?");
-      ei.x_ = col->relative_coordinate (common[X_AXIS], X_AXIS);
-      ei.head_ = ei.stem_ = col->extent (common[Y_AXIS],
-                                        Y_AXIS)[get_grob_direction (me)];
-      return ei;
-    }
-  Direction stem_dir = get_grob_direction (stem);
-
-  if (Grob *head = Note_column::first_head (col))
-    ei.x_ = head->extent (common[X_AXIS], X_AXIS).center ();
-  else
-    ei.x_ = col->extent (common[X_AXIS], X_AXIS).center ();
-
-  Grob * h = Stem::extremal_heads (stem)[Direction (dir)];
-  if (!h)
-    {
-      ei.head_ = ei.stem_ = col->extent (common[Y_AXIS], Y_AXIS)[dir];
-      return ei;
-    }
-
-  ei.head_ = h->extent (common[Y_AXIS], Y_AXIS)[dir];
-
-  if ((stem_dir == dir)
-      && !stem->extent (stem, Y_AXIS).is_empty ())
-    {
-      ei.stem_ = stem->extent (common[Y_AXIS], Y_AXIS)[dir];
-      if (Grob * b = Stem::get_beam (stem))
-       ei.stem_ += stem_dir * 0.5 * Beam::get_thickness (b);
-      ei.x_  = stem->extent (common[X_AXIS], X_AXIS).center ();
-    }
-  else
-    ei.stem_ = ei.head_;
-
-  return ei;
-}
-
-
-Direction
-New_slur::get_default_dir (Grob*me)
-{
-  Link_array<Grob> encompasses
-    = Pointer_group_interface__extract_grobs (me, (Grob*) 0, "note-columns");
-
-  Direction d = DOWN;
-  for (int i= 0; i < encompasses.size (); i ++)
-    {
-      if (Note_column::dir (encompasses[i]) < 0)
-       {
-         d = UP;
-         break;
-       }
-    }
-  return d;
-}
-
-MAKE_SCHEME_CALLBACK (New_slur, after_line_breaking,1);
-SCM
-New_slur::after_line_breaking (SCM smob)
-{
-  Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (smob));
-  if (!scm_ilength (me->get_property ("note-columns")))
-    {
-      me->suicide ();
-      return SCM_UNSPECIFIED;
-    }
-
-  if (!get_grob_direction (me))
-    set_grob_direction (me, get_default_dir (me));
-
-  set_end_points (me);
-
-  return SCM_UNSPECIFIED;
-}
-
-Bezier
-New_slur::get_bezier (Grob *me, Drul_array<Offset> extremes,
-                     Real r_0,
-                     Real h_inf)
-{
-  Array<Offset> encompasses;
-  encompasses.push (extremes[LEFT]);
-  encompasses.push (extremes[RIGHT]);
-
-  Slur_bezier_bow bb (encompasses,
-                     get_grob_direction (me), h_inf, r_0);
-
-  return bb.get_bezier ();
-}
-
-
-Drul_array<Bound_info>
-New_slur::get_bound_info (Spanner* me,
-                         Grob **common)
-{
-  Drul_array<Bound_info> extremes;
-  Direction d = LEFT;
-  Direction dir = get_grob_direction (me);
-
-  do {
-    extremes[d].bound_ = me->get_bound (d);
-
-    if (Note_column::has_interface (extremes[d].bound_))
-      {
-       extremes[d].note_column_ = extremes[d].bound_;
-       extremes[d].stem_ = Note_column::get_stem (extremes[d].note_column_);
-       extremes[d].stem_dir_ = get_grob_direction (extremes[d].stem_);
-       extremes[d].stem_extent_[X_AXIS] = extremes[d].stem_->extent (common[X_AXIS], X_AXIS);
-       extremes[d].stem_extent_[Y_AXIS] = extremes[d].stem_->extent (common[Y_AXIS], Y_AXIS);
-       extremes[d].slur_head_ = Stem::extremal_heads (extremes[d].stem_)[dir];
-       extremes[d].slur_head_extent_ = extremes[d].slur_head_->extent (common[X_AXIS], X_AXIS);
-       extremes[d].staff_ = Staff_symbol_referencer::get_staff_symbol (extremes[d].slur_head_);
-       extremes[d].staff_space_ = Staff_symbol_referencer::staff_space (extremes[d].slur_head_);
-      }
-    else
-      {
-       extremes[d].neighbor_y_ = broken_trend_y (me, common, d);
-      }
-  } while (flip (&d) != LEFT);
-
-  return extremes;
-}
-
-void
-New_slur::set_end_points (Grob *me)
-{
-  Link_array<Grob> columns
-    = Pointer_group_interface__extract_grobs (me, (Grob *)0, "note-columns");
-  Slur_score_parameters params;
-  if (columns.is_empty ())
-    {
-      me->suicide ();
-      return;
-    }
-
-  SCM eltlist = me->get_property ("note-columns");
-  Grob *common[] = {common_refpoint_of_list (eltlist, me, X_AXIS),
-                   common_refpoint_of_list (eltlist, me, Y_AXIS)};
-
-
-  Spanner *sp = dynamic_cast<Spanner*> (me);
-  common[X_AXIS] = common[X_AXIS]->common_refpoint (sp->get_bound (RIGHT),
-                                                   X_AXIS);
-  common[X_AXIS] = common[X_AXIS]->common_refpoint (sp->get_bound (LEFT),
-                                                   X_AXIS);
-  Drul_array<Bound_info> extremes = get_bound_info (sp, common);
-  Drul_array<Offset> base_attachment
-    = get_base_attachments (sp, common, extremes);
-  Drul_array<Real> end_ys
-    = get_y_attachment_range (sp, common, extremes, base_attachment);
-  Array<Slur_score> scores = enumerate_attachments (me, common, &params,
-                                                   extremes, base_attachment,
-                                                   end_ys);
-
-  generate_curves (me, common, extremes, base_attachment, &scores);
-  score_edges (me, common, &params,extremes, base_attachment, &scores);
-  score_slopes (me, common, &params,extremes, base_attachment, &scores);
-  score_encompass (me, common, &params,extremes, base_attachment, &scores);
-  
-  Real opt = 1e6;
-  int opt_idx = 0;
-  // why backwards?
-  for (int i = scores.size (); i--;)
-    {
-      if (scores[i].score_  < opt)
-       {
-         opt = scores[i].score_;
-         opt_idx = i;
-       }
-    }
-
-#if DEBUG_SLUR_QUANTING
-  SCM inspect_quants = me->get_property ("inspect-quants");
-  if (to_boolean (me->get_paper ()
-                 ->lookup_variable (ly_symbol2scm ("debug-slur-quanting")))
-      && ly_c_pair_p (inspect_quants))
-    {
-      Drul_array<Real> ins = ly_scm2interval (inspect_quants);
-      int i = 0;
-
-      Real mindist = 1e6;
-      for (; i < scores.size (); i ++)
-       {
-         Real d =fabs (scores[i].attachment_[LEFT][Y_AXIS] - ins[LEFT])
-           + fabs (scores[i].attachment_[RIGHT][Y_AXIS] - ins[RIGHT]);
-         if (d < mindist)
-           {
-             opt_idx = i;
-             mindist= d;
-           }
-       }
-      if (mindist > 1e5)
-       programming_error ("Could not find quant.");
-    }
-  scores[opt_idx].score_card_ += to_string ("i%d", opt_idx);
-
-  // debug quanting
-  me->set_property ("quant-score",
-                   scm_makfrom0str (scores[opt_idx].score_card_.to_str0 ()));
-#endif
-  
-
-  Bezier b = scores[opt_idx].curve_;
-  SCM controls = SCM_EOL;
-  for (int i = 4; i--;)
-    {
-      Offset o = b.control_[i] -
-       Offset (me->relative_coordinate (common[X_AXIS], X_AXIS),
-               me->relative_coordinate (common[Y_AXIS], Y_AXIS));
-
-      controls = scm_cons (ly_offset2scm (o), controls);
-    }
-
-  me->set_property ("control-points", controls);
-}
-
-
-Drul_array<Real>
-New_slur::get_y_attachment_range (Spanner*me,
-                                 Grob **common,
-                                 Drul_array<Bound_info> extremes,
-                                 Drul_array<Offset> base_attachment)
-{
-  Drul_array<Real> end_ys;
-  Direction dir = get_grob_direction (me);
-  Direction d = LEFT;
-  do
-    {
-      if (extremes[d].note_column_)
-       {
-         end_ys[d] = dir
-           * ((dir * (base_attachment[d][Y_AXIS] + 4.0 * dir))
-              >? (dir * (dir + extremes[d].note_column_->extent(common[Y_AXIS],
-                                                                Y_AXIS)[dir]))
-              >? (dir * base_attachment[-d][Y_AXIS]));
-       }
-      else
-      end_ys[d] = extremes[d].neighbor_y_ + 4.0 * dir;
-    }
-  while (flip (&d) != LEFT);
-
-  return end_ys;
-}
-
-Drul_array<Offset>
-New_slur::get_base_attachments (Spanner *me,
-                               Grob **common, Drul_array<Bound_info> extremes)
-{
-  Link_array<Grob> columns
-    = Pointer_group_interface__extract_grobs (me, (Grob *)0, "note-columns");
-  Drul_array<Offset> base_attachment;
-  Slur_score_parameters params;
-  Real staff_space = Staff_symbol_referencer::staff_space ((Grob*)me);
-  Direction dir = get_grob_direction (me);
-  Direction d = LEFT;
-  do
-    {
-      Grob *stem = extremes[d].stem_;
-      Grob *head = extremes[d].slur_head_;
-
-      Real x, y;
-      if (!extremes[d].note_column_)
-       {
-         y = extremes[d].neighbor_y_;
-         if (d== RIGHT)
-           x = extremes[d].bound_->extent (common[X_AXIS], X_AXIS)[d];
-         else
-           x = me->get_broken_left_end_align ();
-       }
-      else
-       {
-         if (stem
-             && extremes[d].stem_dir_ == dir
-             && Stem::get_beaming (stem, -d)
-             && columns.size () > 2
-             )
-           y = extremes[d].stem_extent_[Y_AXIS][dir];
-         else if (head)
-           y = head->extent (common[Y_AXIS], Y_AXIS)[dir];
-         y += dir * 0.5 * staff_space;
-
-         Real pos
-           = (y - extremes[d].staff_->relative_coordinate (common[Y_AXIS],
-                                                           Y_AXIS))
-           * 2.0 / Staff_symbol::staff_space (extremes[d].staff_);
-
-         /* start off staffline. */
-         if (fabs (pos - round (pos)) < 0.2
-             && Staff_symbol_referencer::on_staffline (head, (int) rint (pos))
-             && Staff_symbol_referencer::line_count (head) - 1 >= rint (pos)
-             )
-           // TODO: calc from slur thick & line thick, parameter.          
-           y += 1.5 * staff_space * dir / 10;
-
-         Grob * fh = Note_column::first_head (extremes[d].note_column_);
-         x = fh->extent (common[X_AXIS], X_AXIS).linear_combination (CENTER);
-       }
-      base_attachment[d] = Offset (x, y);
-
-    } while (flip (&d) != LEFT);
-
-  return base_attachment;
-}
-
-void
-New_slur::generate_curves (Grob *me, Grob **common,
-                          Drul_array<Bound_info> extremes,
-                          Drul_array<Offset>,
-                          Array<Slur_score> *scores)
-{
-  (void) common;
-  (void) extremes;
-  Real staff_space = Staff_symbol_referencer::staff_space ((Grob *) me);
-  Real r_0 = robust_scm2double (me->get_property ("ratio"), 0.33);
-  Real h_inf = staff_space * ly_scm2double (me->get_property ("height-limit"));
-  for (int i = 0; i < scores->size(); i++)
-    {
-      Bezier bez= get_bezier (me, (*scores)[i].attachment_, r_0, h_inf);
-      bez = avoid_staff_line (me, common, extremes, bez);
-      (*scores)[i].attachment_[LEFT] = bez.control_[0];
-      (*scores)[i].attachment_[RIGHT] = bez.control_[3];
-      (*scores)[i].curve_ = bez;
-    }
-}
-
-Bezier
-New_slur::avoid_staff_line (Grob *me, Grob **common,
-                           Drul_array<Bound_info> extremes,
-                           Bezier bez)
-{
-  Offset horiz (1,0);
-  Array<Real> ts  = bez.solve_derivative (horiz);
-  Real lt =  me->get_paper ()->get_dimension (ly_symbol2scm ("linethickness"));
-  Real thick = robust_scm2double (me->get_property ("thickness"), 1.0) *  lt;
-
-  /* TODO: handle case of broken slur.  */
-  if (!ts.is_empty ()
-      && (extremes[LEFT].staff_ == extremes[RIGHT].staff_)
-      && extremes[LEFT].staff_ && extremes[RIGHT].staff_)
-    {
-      Real y = bez.curve_point (ts[0])[Y_AXIS];
-
-      Grob *staff = extremes[LEFT].staff_;
-
-      Real staff_space = extremes[LEFT].staff_space_;
-      Real p = 2 * (y - staff->relative_coordinate (common[Y_AXIS], Y_AXIS))
-       / staff_space;
-
-      Real distance = fabs (round (p) - p);    //  in halfspaces
-      if (distance < 4 * thick
-         && (int) fabs (round (p))
-         <= 2 * Staff_symbol_referencer::staff_radius (staff) + 0.1
-         && (int (fabs (round (p))) % 2
-             != Staff_symbol_referencer::line_count (staff) % 2))
-       {
-         Direction resolution_dir =  - get_grob_direction (me);
-         //        (distance ?  :sign (p - round(p)))
-
-         // TODO: parameter
-         Real newp = round (p) + resolution_dir
-           * 5 * thick;
-         Real dy = (newp - p) * staff_space / 2.0;
-         bez.translate (Offset (0, dy));
-       }
-    }
-  return bez;
-}
-
-Array<Slur_score>
-New_slur::enumerate_attachments (Grob *me, Grob **,
-                                Slur_score_parameters *score_param,
-                                Drul_array<Bound_info> extremes,
-                                Drul_array<Offset> base_attachment,
-                                Drul_array<Real> end_ys)
-{
-  /*ugh.   */
-  Array<Slur_score> scores;
-
-  Direction dir = get_grob_direction (me);
-  Real staff_space = Staff_symbol_referencer::staff_space ((Grob *)me);
-
-  Drul_array<Offset> os;
-  os[LEFT] = base_attachment[LEFT];
-  Real minimum_length = staff_space
-    * robust_scm2double (me->get_property ("minimum-length"), 2.0);
-
-  for (int i = 0; dir * os[LEFT][Y_AXIS] <= dir * end_ys[LEFT]; i++)
-    {
-      os[RIGHT] = base_attachment[RIGHT];
-      for (int j = 0; dir * os[RIGHT][Y_AXIS] <= dir * end_ys[RIGHT]; j++)
-       {
-         Slur_score s;
-         Direction d = LEFT;
-         Drul_array<bool> attach_to_stem (false, false);
-         do {  
-           os[d][X_AXIS] = base_attachment[d][X_AXIS];
-           if (extremes[d].stem_
-               && !Stem::is_invisible (extremes[d].stem_)
-               && extremes[d].stem_dir_ == dir
-               && dir == -d)
-             {
-               if (extremes[d].stem_extent_[Y_AXIS].contains (os[d][Y_AXIS]))
-                 {
-                   os[d][X_AXIS] =  extremes[d].slur_head_extent_[-d]
-                     - d * 0.3;
-                   attach_to_stem[d] = true;
-                 }
-               else if (dir *extremes[d].stem_extent_[Y_AXIS][dir] < dir * os[d][Y_AXIS])
-                 {
-                   os[d][X_AXIS] = extremes[d].stem_extent_[X_AXIS].center();
-                 }
-             }
-         } while (flip (&d) != LEFT);
-
-         Offset dz;      
-         dz = os[RIGHT] - os[LEFT];
-         if (dz[X_AXIS] < minimum_length
-             || fabs (dz[Y_AXIS] / dz[X_AXIS]) > score_param->MAX_SLOPE
-             )
-           {
-             do
-               {
-                if (extremes[d].slur_head_)
-                  {
-                    os[d][X_AXIS] = extremes[d].slur_head_extent_.center ();
-                    attach_to_stem[d] = false;
-                  }
-             }
-             while (flip (&d) != LEFT);
-           }
-
-         dz = os[RIGHT] - os[LEFT];
-         do {
-           if (extremes[d].slur_head_
-               && !attach_to_stem[d])
-             {
-               /*
-                 horizontally move tilted slurs a little. Move more
-                 for bigger tilts.
-
-                 TODO: parameter
-                */
-               os[d][X_AXIS] -=
-                 dir * extremes[d].slur_head_extent_.length () * sin (dz.arg  ()) / 3;
-             }
-         } while (flip (&d) != LEFT);
-         
-         s.attachment_ = os;
-         scores.push (s);
-
-         os[RIGHT][Y_AXIS] += dir * staff_space / 2;
-       }
-
-      os[LEFT][Y_AXIS] += dir * staff_space / 2;
-    }
-
-  return scores;
-}
-
-void
-New_slur::score_encompass (Grob *me, Grob *common[],
-                          Slur_score_parameters *score_param,
-                          Drul_array<Bound_info> ,
-                          Drul_array<Offset> ,
-                          Array<Slur_score> * scores)
-{
-  Link_array<Grob> encompasses
-    = Pointer_group_interface__extract_grobs (me, (Grob *)0, "note-columns");
-  Direction dir = get_grob_direction (me);
-
-  Array<Encompass_info> infos;
-
-  for (int i = 0; i < encompasses.size(); i++)
-    infos.push (get_encompass_info (me, encompasses[i], common));
-
-  for (int i = 0; i < scores->size (); i++)
-    {
-      Bezier const &bez (scores->elem (i).curve_);
-      Real demerit = 0.0;
-      for (int j = 0; j < infos.size(); j++)
-       {
-         Real x = infos[j].x_;
-
-         bool l_edge = j==0;
-         bool r_edge = j==infos.size()-1;
-         bool edge =  l_edge || r_edge;
-  
-         if (!(x < scores->elem (i).attachment_[RIGHT][X_AXIS]
-               && x > scores->elem (i).attachment_[LEFT][X_AXIS]))
-           continue;
-       
-         Real y = bez.get_other_coordinate (X_AXIS, x);
-         if (!edge)
-           {
-             Real head_dy = (y - infos[j].head_);
-             if (dir * head_dy < 0)
-               demerit += score_param->HEAD_ENCOMPASS_PENALTY;
-             else
-               {
-                 Real hd = (head_dy)
-                   ? (1 / fabs (head_dy) - 1 / score_param->FREE_HEAD_DISTANCE)
-                   : score_param->HEAD_ENCOMPASS_PENALTY;
-                 hd = (hd >? 0)<? score_param->HEAD_ENCOMPASS_PENALTY;
-
-                 demerit += hd;        
-               }
-           }     
-
-         if (dir * (y - infos[j].stem_) < 0)
-           {
-             Real stem_dem =score_param->STEM_ENCOMPASS_PENALTY ; 
-             if ((l_edge && dir == UP)
-                 || (r_edge && dir == DOWN))
-               {
-                 stem_dem /= 5;
-               }
-
-             demerit +=  stem_dem;
-           }
-         else if (!edge)
-           {
-             Interval ext;
-             ext.add_point (infos[j].stem_);
-             ext.add_point (infos[j].head_);
-
-             demerit += - score_param->CLOSENESS_FACTOR * (dir * (y - (ext[dir] + dir * score_param->FREE_HEAD_DISTANCE)) <? 0) /
-               infos.size ();
-           }
-       }
-
-#if DEBUG_SLUR_QUANTING
-      (*scores)[i].score_card_ += to_string ("C%.2f", demerit);
-#endif
-
-      (*scores)[i].score_ += demerit;
-    }
-}
-
-void
-New_slur::score_edges (Grob *me, Grob **,
-                      Slur_score_parameters * score_param,
-                      Drul_array<Bound_info> extremes,
-                      Drul_array<Offset> base_attach,
-                      Array<Slur_score> *scores)
-{
-  Direction dir = get_grob_direction (me);
-
-  for (int i = 0; i < scores->size (); i++)
-    {
-
-      Direction d = LEFT;
-      do {
-       Real y = scores->elem (i).attachment_[d][Y_AXIS];
-       Real dy = fabs (y - base_attach[d][Y_AXIS]);
-       
-       Real factor = score_param->EDGE_ATTRACTION_FACTOR;
-       Real demerit = factor * dy;
-       if (extremes[d].stem_
-           && extremes[d].stem_dir_ == dir
-           && !Stem::get_beaming (extremes[d].stem_, -d)
-           )
-         demerit /= 5;
-       
-       (*scores)[i].score_ += demerit;
-#if DEBUG_SLUR_QUANTING
-       (*scores)[i].score_card_ += to_string ("E%.2f", demerit);
-#endif
-      } while (flip (&d) != LEFT);
-    }
-}
-
-void
-New_slur::score_slopes (Grob *me, Grob *common[],
-                       Slur_score_parameters*score_param,
-                       Drul_array<Bound_info> extremes,
-                       Drul_array<Offset> base_attach,
-                       Array<Slur_score> * scores)
-{
-  Drul_array<Real> ys;
-
-  Direction d = LEFT;
-  do {
-    if (extremes[d].slur_head_)
-      ys[d] = extremes[d].slur_head_ ->relative_coordinate (common[Y_AXIS],
-                                                           Y_AXIS);
-    else
-      ys[d] = extremes[d].neighbor_y_;
-  } while (flip (&d) != LEFT);
-
-  bool has_beams
-    = (extremes[LEFT].stem_ && Stem::get_beam (extremes[LEFT].stem_))
-    || (extremes[RIGHT].stem_ && Stem::get_beam (extremes[RIGHT].stem_));
-
-  Direction dir = get_grob_direction (me);
-  Real dy = ys[RIGHT] - ys[LEFT];
-  for (int i = 0; i < scores->size (); i++)
-    {
-      Offset slur_dz = (*scores)[i].attachment_[RIGHT]
-       -  (*scores)[i].attachment_[LEFT];
-      Real slur_dy = slur_dz[Y_AXIS]; 
-      Real demerit = 0.0;
-
-      demerit += ((fabs (slur_dy/slur_dz[X_AXIS])
-                  - score_param->MAX_SLOPE) >? 0)
-       * score_param->MAX_SLOPE_FACTOR;
-
-       /*
-         0.2: account for staffline offset.
-       */
-      Real max_dy = (fabs (dy) + 0.2);
-      if (has_beams)
-       max_dy += 1.0; 
-      
-      demerit += score_param->STEEPER_SLOPE_FACTOR * ((fabs (slur_dy) -max_dy) >? 0); 
-
-      
-      demerit += ((fabs (slur_dy/slur_dz[X_AXIS]) - score_param->MAX_SLOPE)>?0)  * score_param->MAX_SLOPE_FACTOR;
-      
-      if (sign (dy) == 0 &&
-         sign (slur_dy) != 0)
-       demerit += score_param->NON_HORIZONTAL_PENALTY;
-
-      if (sign (dy)
-         && sign (slur_dy)
-         && sign (slur_dy) != sign (dy))
-       demerit += has_beams
-         ? score_param->SAME_SLOPE_PENALTY / 10
-         : score_param->SAME_SLOPE_PENALTY;
-
-#if DEBUG_SLUR_QUANTING
-      (*scores)[i].score_card_ += to_string ("S%.2f",d);
-#endif
-      (*scores)[i].score_ += demerit;
-    }
-}
-
-
-Bezier
-New_slur::get_curve (Grob*me)
-{
-  Bezier b;
-  int i = 0;
-  for (SCM s = me->get_property ("control-points"); s != SCM_EOL;
-       s = ly_cdr (s))
-    b.control_[i++] = ly_scm2offset (ly_car (s));
-
-  return b;
-}
-
-
 MAKE_SCHEME_CALLBACK (New_slur, height, 2);
 SCM
 New_slur::height (SCM smob, SCM ax)
@@ -998,6 +99,47 @@ New_slur::print (SCM smob)
 }
 
 
+Bezier
+New_slur::get_curve (Grob*me)
+{
+  Bezier b;
+  int i = 0;
+  for (SCM s = me->get_property ("control-points"); s != SCM_EOL;
+       s = ly_cdr (s))
+    b.control_[i++] = ly_scm2offset (ly_car (s));
+
+  return b;
+}
+
+
+void
+New_slur::set_interface (Grob*me)
+{
+  /* Copy to mutable list. */
+  me->set_property ("attachment",
+                   ly_deep_copy (me->get_property ("attachment")));
+}
+
+void
+New_slur::add_column (Grob*me, Grob*n)
+{
+  Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-columns"), n);
+  me->add_dependency (n);
+
+  add_bound_item (dynamic_cast<Spanner*> (me), dynamic_cast<Item*> (n));
+}
+
+
+void
+New_slur::add_extra_encompass (Grob*me, Grob*n)
+{
+  Pointer_group_interface::add_grob (me, ly_symbol2scm ("encompass-objects"), n);
+  me->add_dependency (n);
+
+  add_bound_item (dynamic_cast<Spanner*> (me), dynamic_cast<Item*> (n));
+}
+
+
 ADD_INTERFACE (New_slur, "new-slur-interface",
               "A slur",
-              "control-points dashed details direction height-limit note-columns ratio slope-limit thickness");
+              "extra-encompass control-points dashed details direction height-limit note-columns ratio thickness");
index e3e289ce38371ab2e337d418a38bb0a79e80b11e..69865eae59b8c61853dae0b56c1e0ff43fa4bac9 100644 (file)
@@ -5,7 +5,7 @@
 */
 
 #include "event.hh"
-#include "slur.hh"
+#include "new-slur.hh"
 #include "warn.hh"
 #include "note-column.hh"
 #include "context.hh"
@@ -82,9 +82,9 @@ Phrasing_slur_engraver::acknowledge_grob (Grob_info info)
     {
       Grob *e =info.grob_;
       for (int i = 0; i < phrasing_slurs_.size (); i++)
-       Slur::add_column (phrasing_slurs_[i], e);
+       New_slur::add_column (phrasing_slurs_[i], e);
       for (int i = 0; i < end_phrasing_slurs_.size (); i++)
-       Slur::add_column (end_phrasing_slurs_[i], e);
+       New_slur::add_column (end_phrasing_slurs_[i], e);
     }
 }
 
@@ -133,8 +133,6 @@ Phrasing_slur_engraver::process_acknowledged_grobs ()
          // push a new phrasing_slur onto stack.
          // (use temp. array to wait for all phrasing_slur STOPs)
          Grob* phrasing_slur = make_spanner ("PhrasingSlur", phrasing_slur_ev->self_scm ());
-         Slur::set_interface (phrasing_slur); // can't remove.
-
 
          if (Direction updown = to_dir (phrasing_slur_ev->get_property ("direction")))
            {
index 7c6bc4fb6a160aa325f2448657a94fafa1a55cc0..4164777ea2e39d1a770ab50ec586df6fb44d1435 100644 (file)
@@ -5,7 +5,7 @@
 */
 
 #include "event.hh"
-#include "slur.hh"
+#include "new-slur.hh"
 #include "warn.hh"
 #include "note-column.hh"
 #include "context.hh"
@@ -94,13 +94,20 @@ Slur_engraver::set_melisma (bool m)
 void
 Slur_engraver::acknowledge_grob (Grob_info info)
 {
+  Grob *e =info.grob_;
   if (Note_column::has_interface (info.grob_))
     {
-      Grob *e =info.grob_;
       for (int i = 0; i < slur_stack_.size (); i++)
-       Slur::add_column (slur_stack_[i], e);
+       New_slur::add_column (slur_stack_[i], e);
       for (int i = 0; i < end_slurs_.size (); i++)
-       Slur::add_column (end_slurs_[i], e);
+       New_slur::add_column (end_slurs_[i], e);
+    }
+  else
+    {
+      for (int i = 0; i < slur_stack_.size (); i++)
+       New_slur::add_extra_encompass (end_slurs_[i], e);
+      for (int i = 0; i < end_slurs_.size (); i++)
+       New_slur::add_extra_encompass (end_slurs_[i], e);
     }
 }
 
@@ -150,8 +157,6 @@ Slur_engraver::process_music ()
          // push a new slur onto stack.
          // (use temp. array to wait for all slur STOPs)
          Grob* slur = make_spanner ("Slur", slur_ev->self_scm ());
-         Slur::set_interface (slur); // cannot remove yet!
-
 
          if (Direction updown = to_dir (slur_ev->get_property ("direction")))
            {
@@ -183,6 +188,6 @@ ENTER_DESCRIPTION (Slur_engraver,
 /* descr */       "Build slurs from Slur_evs",
 /* creats*/       "Slur",
 /* accepts */     "slur-event",
-/* acks  */      "note-column-interface",
+/* acks  */      "note-column-interface accidental-interface script-interface",
 /* reads */       "slurMelismaBusy",
 /* write */       "");
diff --git a/lily/slur-quanting.cc b/lily/slur-quanting.cc
new file mode 100644 (file)
index 0000000..8748218
--- /dev/null
@@ -0,0 +1,910 @@
+/*
+  slur.cc -- implement score based Slur
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1996--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+
+#include <math.h>
+
+#include "directional-element-interface.hh"
+#include "group-interface.hh"
+#include "lily-guile.hh"
+#include "note-column.hh"
+#include "output-def.hh"
+#include "slur-bezier-bow.hh"
+#include "new-slur.hh"
+#include "spanner.hh"
+#include "staff-symbol-referencer.hh"
+#include "staff-symbol.hh"
+#include "stem.hh"
+#include "warn.hh"
+#include "beam.hh"
+
+
+
+#define DEBUG_SLUR_QUANTING 1
+
+struct Slur_score
+{
+  Drul_array<Offset> attachment_;
+  Real score_;
+  Bezier curve_;
+
+#if DEBUG_SLUR_QUANTING
+  String score_card_;
+#endif
+
+  Slur_score()
+  {
+    score_ = 0.0;
+  }
+};
+
+/*
+  TODO: put in details property.
+*/
+struct Slur_score_parameters
+{
+  int SLUR_REGION_SIZE;
+  Real HEAD_ENCOMPASS_PENALTY;
+  Real STEM_ENCOMPASS_PENALTY;
+  Real CLOSENESS_FACTOR;
+  Real EDGE_ATTRACTION_FACTOR;
+  Real SAME_SLOPE_PENALTY;
+  Real STEEPER_SLOPE_FACTOR;
+  Real NON_HORIZONTAL_PENALTY;
+  Real HEAD_STRICT_FREE_SPACE;
+  Real MAX_SLOPE;
+  Real MAX_SLOPE_FACTOR;
+  Real FREE_HEAD_DISTANCE;
+  Slur_score_parameters ();
+};
+
+/*
+  TODO:
+
+  - curve around flag for y coordinate
+  - better scoring.
+  - short-cut: try a smaller region first.
+  - collisions with accidentals
+  - collisions with scripts (staccato!)
+  - 
+*/
+struct Encompass_info
+{
+  Real x_;
+  Real stem_;
+  Real head_;
+  Encompass_info ()
+  {
+    x_ = 0.0;
+    stem_ = 0.0;
+    head_ = 0.0;
+  }
+};
+
+struct Bound_info
+{
+  Box stem_extent_;
+  Direction stem_dir_;
+  Grob *bound_;
+  Grob *note_column_;
+  Grob *slur_head_;
+  Grob *staff_;
+  Grob *stem_;
+  Interval slur_head_extent_;
+  Real neighbor_y_;
+  Real staff_space_;
+  
+  Bound_info ()
+  {
+    stem_ = 0;
+    neighbor_y_ = 0;
+    staff_ = 0;
+    slur_head_ = 0;
+    stem_dir_ = CENTER;
+    note_column_ = 0;
+  }
+};
+
+
+
+static void score_slopes (Grob *me, Grob *common[],
+                         Slur_score_parameters *score_param,
+                         Drul_array<Bound_info>,
+                         Drul_array<Offset> base_attach,
+                         Array<Slur_score> *scores);
+
+static void score_edges (Grob *me, Grob *common[],
+                        Slur_score_parameters *score_param,
+                        Drul_array<Bound_info> extremes,
+                        Drul_array<Offset> base_attach,
+                        Array<Slur_score> *scores);
+static void score_encompass (Grob *me, Grob *common[],
+                            Slur_score_parameters*,
+                            Drul_array<Bound_info>,
+                            Drul_array<Offset>, Array<Slur_score> *scores);
+static Bezier avoid_staff_line (Grob *me, Grob **common,
+                               Drul_array<Bound_info> extremes,
+                               Bezier bez);
+
+static Encompass_info get_encompass_info (Grob *me,
+                                         Grob *col,
+                                         Grob **common);
+static Bezier get_bezier (Grob *me, Drul_array<Offset>, Real, Real);
+static Direction get_default_dir (Grob *me);
+
+static void set_end_points (Grob *);
+static Real broken_trend_y (Grob *me, Grob **, Direction dir);
+static Drul_array<Bound_info> get_bound_info (Spanner *me, Grob **common);
+
+static void generate_curves (Grob *me,
+                            Grob *common[],
+                            Drul_array<Bound_info> extremes,
+                            Drul_array<Offset> base_attach,
+                            Array<Slur_score> *scores);
+static Array<Slur_score> enumerate_attachments
+(Grob *me, Grob *common[], Slur_score_parameters *score_param,
+ Drul_array<Bound_info> extremes,
+ Drul_array<Offset> base_attachment, Drul_array<Real> end_ys);
+static Drul_array<Offset> get_base_attachments
+(Spanner *sp, Grob **common, Drul_array<Bound_info> extremes);
+static Drul_array<Real> get_y_attachment_range
+(Spanner *sp, Grob **common, Drul_array<Bound_info> extremes,
+ Drul_array<Offset> base_attachment);
+
+void
+init_score_param (Slur_score_parameters *score_param)
+{
+  score_param->SLUR_REGION_SIZE = 5;
+  score_param->HEAD_ENCOMPASS_PENALTY = 1000.0;
+  score_param->STEM_ENCOMPASS_PENALTY = 30.0;
+  score_param->CLOSENESS_FACTOR = 10;
+  score_param->EDGE_ATTRACTION_FACTOR = 4;
+  score_param->SAME_SLOPE_PENALTY = 20;
+  score_param->STEEPER_SLOPE_FACTOR = 50;
+  score_param->NON_HORIZONTAL_PENALTY = 15;
+  score_param->HEAD_STRICT_FREE_SPACE = 0.2;
+  score_param->MAX_SLOPE = 1.1;
+  score_param->MAX_SLOPE_FACTOR = 10;
+  score_param->FREE_HEAD_DISTANCE = 0.3;
+}
+
+Slur_score_parameters::Slur_score_parameters()
+{
+  init_score_param (this);
+}
+
+/* HDIR indicates the direction for the slur.  */
+Real
+broken_trend_y (Grob *me, Grob **common, Direction hdir)
+{
+  /* A broken slur should maintain the same vertical trend
+     the unbroken slur would have had.  */
+  Real by = 0.0;
+  if (Spanner *mother = dynamic_cast<Spanner*> (me->original_))
+    {
+      int k = broken_spanner_index (dynamic_cast<Spanner*> (me));
+      int j = k + hdir;
+      if (j < 0 || j >= mother->broken_intos_.size ())
+       return by;
+
+      Grob *neighbor = mother->broken_intos_[j];
+      if (hdir == RIGHT)
+       neighbor->set_property ("direction",
+                               me->get_property ("direction"));
+
+      Spanner *common_mother
+       = dynamic_cast<Spanner*> (common[Y_AXIS]->original_);
+      int common_k
+       = broken_spanner_index (dynamic_cast<Spanner*> (common[Y_AXIS]));
+      int common_j = common_k + hdir;
+
+      if (common_j < 0 || common_j >= common_mother->broken_intos_.size())
+       return by;
+
+      Grob *common_next_system = common_mother->broken_intos_[common_j];
+      Link_array<Grob> neighbor_cols
+       = Pointer_group_interface__extract_grobs (neighbor, (Grob *)0,
+                                                 "note-columns");
+
+      Grob *neighbor_col
+       = (hdir == RIGHT) ? neighbor_cols[0] : neighbor_cols.top ();
+      Grob *neighbor_common
+       = common_next_system->common_refpoint (neighbor_col, Y_AXIS);
+
+      Direction vdir = get_grob_direction (me);
+      Real neighbor_y
+       = neighbor_col->extent (neighbor_common, Y_AXIS)
+       .linear_combination (int(neighbor_cols.size()==1 ? CENTER : vdir))
+       - common_next_system->relative_coordinate (neighbor_common, Y_AXIS);
+
+      Link_array<Grob> my_cols
+       = Pointer_group_interface__extract_grobs (me, (Grob *)0,
+                                                 "note-columns");
+
+      Grob *extreme_col = (hdir == RIGHT) ? my_cols.top() : my_cols[0];
+      Real y = extreme_col->extent (common[Y_AXIS], Y_AXIS)
+       .linear_combination (int ((my_cols.size() == 1) ? CENTER : vdir));
+      by = (y*neighbor_cols.size() + neighbor_y*my_cols.size()) /
+       (my_cols.size() + neighbor_cols.size());
+    }
+  return by;
+}
+
+
+Encompass_info
+get_encompass_info (Grob *me,
+                   Grob *col,
+                   Grob **common)
+{
+  Grob* stem = unsmob_grob (col->get_property ("stem"));
+
+  Encompass_info ei;
+
+  Direction dir = get_grob_direction (me);
+
+  if (!stem)
+    {
+      programming_error ("No stem for note column?");
+      ei.x_ = col->relative_coordinate (common[X_AXIS], X_AXIS);
+      ei.head_ = ei.stem_ = col->extent (common[Y_AXIS],
+                                        Y_AXIS)[get_grob_direction (me)];
+      return ei;
+    }
+  Direction stem_dir = get_grob_direction (stem);
+
+  if (Grob *head = Note_column::first_head (col))
+    ei.x_ = head->extent (common[X_AXIS], X_AXIS).center ();
+  else
+    ei.x_ = col->extent (common[X_AXIS], X_AXIS).center ();
+
+  Grob * h = Stem::extremal_heads (stem)[Direction (dir)];
+  if (!h)
+    {
+      ei.head_ = ei.stem_ = col->extent (common[Y_AXIS], Y_AXIS)[dir];
+      return ei;
+    }
+
+  ei.head_ = h->extent (common[Y_AXIS], Y_AXIS)[dir];
+
+  if ((stem_dir == dir)
+      && !stem->extent (stem, Y_AXIS).is_empty ())
+    {
+      ei.stem_ = stem->extent (common[Y_AXIS], Y_AXIS)[dir];
+      if (Grob * b = Stem::get_beam (stem))
+       ei.stem_ += stem_dir * 0.5 * Beam::get_thickness (b);
+      ei.x_  = stem->extent (common[X_AXIS], X_AXIS).center ();
+    }
+  else
+    ei.stem_ = ei.head_;
+
+  return ei;
+}
+
+
+Direction
+get_default_dir (Grob*me)
+{
+  Link_array<Grob> encompasses
+    = Pointer_group_interface__extract_grobs (me, (Grob*) 0, "note-columns");
+
+  Direction d = DOWN;
+  for (int i= 0; i < encompasses.size (); i ++)
+    {
+      if (Note_column::dir (encompasses[i]) < 0)
+       {
+         d = UP;
+         break;
+       }
+    }
+  return d;
+}
+
+MAKE_SCHEME_CALLBACK (New_slur, after_line_breaking,1);
+SCM
+New_slur::after_line_breaking (SCM smob)
+{
+  Spanner *me = dynamic_cast<Spanner*> (unsmob_grob (smob));
+  if (!scm_ilength (me->get_property ("note-columns")))
+    {
+      me->suicide ();
+      return SCM_UNSPECIFIED;
+    }
+
+  if (!get_grob_direction (me))
+    set_grob_direction (me, get_default_dir (me));
+
+  set_end_points (me);
+
+  return SCM_UNSPECIFIED;
+}
+
+
+Bezier
+get_bezier (Grob *me, Drul_array<Offset> extremes,
+           Real r_0,
+           Real h_inf)
+{
+  Array<Offset> encompasses;
+  encompasses.push (extremes[LEFT]);
+  encompasses.push (extremes[RIGHT]);
+
+  Slur_bezier_bow bb (encompasses,
+                     get_grob_direction (me), h_inf, r_0);
+
+  return bb.get_bezier ();
+}
+
+
+Drul_array<Bound_info>
+get_bound_info (Spanner* me,
+               Grob **common)
+{
+  Drul_array<Bound_info> extremes;
+  Direction d = LEFT;
+  Direction dir = get_grob_direction (me);
+
+  do {
+    extremes[d].bound_ = me->get_bound (d);
+
+    if (Note_column::has_interface (extremes[d].bound_))
+      {
+       extremes[d].note_column_ = extremes[d].bound_;
+       extremes[d].stem_ = Note_column::get_stem (extremes[d].note_column_);
+       extremes[d].stem_dir_ = get_grob_direction (extremes[d].stem_);
+       extremes[d].stem_extent_[X_AXIS] = extremes[d].stem_->extent (common[X_AXIS], X_AXIS);
+       extremes[d].stem_extent_[Y_AXIS] = extremes[d].stem_->extent (common[Y_AXIS], Y_AXIS);
+       extremes[d].slur_head_ = Stem::extremal_heads (extremes[d].stem_)[dir];
+       extremes[d].slur_head_extent_ = extremes[d].slur_head_->extent (common[X_AXIS], X_AXIS);
+       extremes[d].staff_ = Staff_symbol_referencer::get_staff_symbol (extremes[d].slur_head_);
+       extremes[d].staff_space_ = Staff_symbol_referencer::staff_space (extremes[d].slur_head_);
+      }
+    else
+      {
+       extremes[d].neighbor_y_ = broken_trend_y (me, common, d);
+      }
+  } while (flip (&d) != LEFT);
+
+  return extremes;
+}
+
+void
+set_end_points (Grob *me)
+{
+  Link_array<Grob> columns
+    = Pointer_group_interface__extract_grobs (me, (Grob *)0, "note-columns");
+  Slur_score_parameters params;
+  if (columns.is_empty ())
+    {
+      me->suicide ();
+      return;
+    }
+
+  SCM eltlist = me->get_property ("note-columns");
+  Grob *common[] = {common_refpoint_of_list (eltlist, me, X_AXIS),
+                   common_refpoint_of_list (eltlist, me, Y_AXIS)};
+
+
+  Spanner *sp = dynamic_cast<Spanner*> (me);
+  common[X_AXIS] = common[X_AXIS]->common_refpoint (sp->get_bound (RIGHT),
+                                                   X_AXIS);
+  common[X_AXIS] = common[X_AXIS]->common_refpoint (sp->get_bound (LEFT),
+                                                   X_AXIS);
+  Drul_array<Bound_info> extremes = get_bound_info (sp, common);
+  Drul_array<Offset> base_attachment
+    = get_base_attachments (sp, common, extremes);
+  Drul_array<Real> end_ys
+    = get_y_attachment_range (sp, common, extremes, base_attachment);
+  Array<Slur_score> scores = enumerate_attachments (me, common, &params,
+                                                   extremes, base_attachment,
+                                                   end_ys);
+
+  generate_curves (me, common, extremes, base_attachment, &scores);
+  score_edges (me, common, &params,extremes, base_attachment, &scores);
+  score_slopes (me, common, &params,extremes, base_attachment, &scores);
+  score_encompass (me, common, &params,extremes, base_attachment, &scores);
+  
+  Real opt = 1e6;
+  int opt_idx = 0;
+  // why backwards?
+  for (int i = scores.size (); i--;)
+    {
+      if (scores[i].score_  < opt)
+       {
+         opt = scores[i].score_;
+         opt_idx = i;
+       }
+    }
+
+#if DEBUG_SLUR_QUANTING
+  SCM inspect_quants = me->get_property ("inspect-quants");
+  if (to_boolean (me->get_paper ()
+                 ->lookup_variable (ly_symbol2scm ("debug-slur-quanting")))
+      && ly_c_pair_p (inspect_quants))
+    {
+      Drul_array<Real> ins = ly_scm2interval (inspect_quants);
+      int i = 0;
+
+      Real mindist = 1e6;
+      for (; i < scores.size (); i ++)
+       {
+         Real d =fabs (scores[i].attachment_[LEFT][Y_AXIS] - ins[LEFT])
+           + fabs (scores[i].attachment_[RIGHT][Y_AXIS] - ins[RIGHT]);
+         if (d < mindist)
+           {
+             opt_idx = i;
+             mindist= d;
+           }
+       }
+      if (mindist > 1e5)
+       programming_error ("Could not find quant.");
+    }
+  scores[opt_idx].score_card_ += to_string ("i%d", opt_idx);
+
+  // debug quanting
+  me->set_property ("quant-score",
+                   scm_makfrom0str (scores[opt_idx].score_card_.to_str0 ()));
+#endif
+  
+
+  Bezier b = scores[opt_idx].curve_;
+  SCM controls = SCM_EOL;
+  for (int i = 4; i--;)
+    {
+      Offset o = b.control_[i] -
+       Offset (me->relative_coordinate (common[X_AXIS], X_AXIS),
+               me->relative_coordinate (common[Y_AXIS], Y_AXIS));
+
+      controls = scm_cons (ly_offset2scm (o), controls);
+    }
+
+  me->set_property ("control-points", controls);
+}
+
+
+Drul_array<Real>
+get_y_attachment_range (Spanner*me,
+                       Grob **common,
+                       Drul_array<Bound_info> extremes,
+                       Drul_array<Offset> base_attachment)
+{
+  Drul_array<Real> end_ys;
+  Direction dir = get_grob_direction (me);
+  Direction d = LEFT;
+  do
+    {
+      if (extremes[d].note_column_)
+       {
+         end_ys[d] = dir
+           * ((dir * (base_attachment[d][Y_AXIS] + 4.0 * dir))
+              >? (dir * (dir + extremes[d].note_column_->extent(common[Y_AXIS],
+                                                                Y_AXIS)[dir]))
+              >? (dir * base_attachment[-d][Y_AXIS]));
+       }
+      else
+       end_ys[d] = extremes[d].neighbor_y_ + 4.0 * dir;
+    }
+  while (flip (&d) != LEFT);
+
+  return end_ys;
+}
+
+Drul_array<Offset>
+get_base_attachments (Spanner *me,
+                     Grob **common, Drul_array<Bound_info> extremes)
+{
+  Link_array<Grob> columns
+    = Pointer_group_interface__extract_grobs (me, (Grob *)0, "note-columns");
+  Drul_array<Offset> base_attachment;
+  Slur_score_parameters params;
+  Real staff_space = Staff_symbol_referencer::staff_space ((Grob*)me);
+  Direction dir = get_grob_direction (me);
+  Direction d = LEFT;
+  do
+    {
+      Grob *stem = extremes[d].stem_;
+      Grob *head = extremes[d].slur_head_;
+
+      Real x, y;
+      if (!extremes[d].note_column_)
+       {
+         y = extremes[d].neighbor_y_;
+         if (d== RIGHT)
+           x = extremes[d].bound_->extent (common[X_AXIS], X_AXIS)[d];
+         else
+           x = me->get_broken_left_end_align ();
+       }
+      else
+       {
+         if (stem
+             && extremes[d].stem_dir_ == dir
+             && Stem::get_beaming (stem, -d)
+             && columns.size () > 2
+             )
+           y = extremes[d].stem_extent_[Y_AXIS][dir];
+         else if (head)
+           y = head->extent (common[Y_AXIS], Y_AXIS)[dir];
+         y += dir * 0.5 * staff_space;
+
+         if (stem)
+           {
+             SCM scripts = stem->get_property ((dir == UP
+                                                ? "script-up"
+                                                : "script-down"));
+
+             /* FIXME: number of scripts, height, priority?
+                articulation scripts should be inside slur, other,
+                such as dynamics, pedals, fingering, should be
+                outside.  */
+             if (!SCM_NULLP (scripts))
+               y += dir * staff_space;
+           }
+
+         Real pos
+           = (y - extremes[d].staff_->relative_coordinate (common[Y_AXIS],
+                                                           Y_AXIS))
+           * 2.0 / Staff_symbol::staff_space (extremes[d].staff_);
+
+         /* start off staffline. */
+         if (fabs (pos - round (pos)) < 0.2
+             && Staff_symbol_referencer::on_staffline (head, (int) rint (pos))
+             && Staff_symbol_referencer::line_count (head) - 1 >= rint (pos)
+             )
+           // TODO: calc from slur thick & line thick, parameter.          
+           y += 1.5 * staff_space * dir / 10;
+
+         Grob * fh = Note_column::first_head (extremes[d].note_column_);
+         x = fh->extent (common[X_AXIS], X_AXIS).linear_combination (CENTER);
+       }
+      base_attachment[d] = Offset (x, y);
+
+    } while (flip (&d) != LEFT);
+
+  return base_attachment;
+}
+
+void
+generate_curves (Grob *me, Grob **common,
+                Drul_array<Bound_info> extremes,
+                Drul_array<Offset>,
+                Array<Slur_score> *scores)
+{
+  (void) common;
+  (void) extremes;
+  Real staff_space = Staff_symbol_referencer::staff_space ((Grob *) me);
+  Real r_0 = robust_scm2double (me->get_property ("ratio"), 0.33);
+  Real h_inf = staff_space * ly_scm2double (me->get_property ("height-limit"));
+  for (int i = 0; i < scores->size(); i++)
+    {
+      Bezier bez= get_bezier (me, (*scores)[i].attachment_, r_0, h_inf);
+      bez = avoid_staff_line (me, common, extremes, bez);
+      (*scores)[i].attachment_[LEFT] = bez.control_[0];
+      (*scores)[i].attachment_[RIGHT] = bez.control_[3];
+      (*scores)[i].curve_ = bez;
+    }
+}
+
+Bezier
+avoid_staff_line (Grob *me, Grob **common,
+                 Drul_array<Bound_info> extremes,
+                 Bezier bez)
+{
+  Offset horiz (1,0);
+  Array<Real> ts  = bez.solve_derivative (horiz);
+  Real lt =  me->get_paper ()->get_dimension (ly_symbol2scm ("linethickness"));
+  Real thick = robust_scm2double (me->get_property ("thickness"), 1.0) *  lt;
+
+  /* TODO: handle case of broken slur.  */
+  if (!ts.is_empty ()
+      && (extremes[LEFT].staff_ == extremes[RIGHT].staff_)
+      && extremes[LEFT].staff_ && extremes[RIGHT].staff_)
+    {
+      Real y = bez.curve_point (ts[0])[Y_AXIS];
+
+      Grob *staff = extremes[LEFT].staff_;
+
+      Real staff_space = extremes[LEFT].staff_space_;
+      Real p = 2 * (y - staff->relative_coordinate (common[Y_AXIS], Y_AXIS))
+       / staff_space;
+
+      Real distance = fabs (round (p) - p);    //  in halfspaces
+      if (distance < 4 * thick
+         && (int) fabs (round (p))
+         <= 2 * Staff_symbol_referencer::staff_radius (staff) + 0.1
+         && (int (fabs (round (p))) % 2
+             != Staff_symbol_referencer::line_count (staff) % 2))
+       {
+         Direction resolution_dir =  
+           (distance ?  get_grob_direction (me) : Direction (sign (p - round(p))));
+
+         // TODO: parameter
+         Real newp = round (p) + resolution_dir
+           * 5 * thick;
+         
+         Real dy = (newp - p) * staff_space / 2.0;
+#if 0
+         bez.translate (Offset (0, dy));
+#else
+         bez.control_[1][Y_AXIS] += dy; 
+         bez.control_[2][Y_AXIS] += dy; 
+         
+#endif
+       }
+    }
+  return bez;
+}
+
+Array<Slur_score>
+enumerate_attachments (Grob *me, Grob **,
+                      Slur_score_parameters *score_param,
+                      Drul_array<Bound_info> extremes,
+                      Drul_array<Offset> base_attachment,
+                      Drul_array<Real> end_ys)
+{
+  /*ugh.   */
+  Array<Slur_score> scores;
+
+  Direction dir = get_grob_direction (me);
+  Real staff_space = Staff_symbol_referencer::staff_space ((Grob *)me);
+
+  Drul_array<Offset> os;
+  os[LEFT] = base_attachment[LEFT];
+  Real minimum_length = staff_space
+    * robust_scm2double (me->get_property ("minimum-length"), 2.0);
+
+  for (int i = 0; dir * os[LEFT][Y_AXIS] <= dir * end_ys[LEFT]; i++)
+    {
+      os[RIGHT] = base_attachment[RIGHT];
+      for (int j = 0; dir * os[RIGHT][Y_AXIS] <= dir * end_ys[RIGHT]; j++)
+       {
+         Slur_score s;
+         Direction d = LEFT;
+         Drul_array<bool> attach_to_stem (false, false);
+         do {  
+           os[d][X_AXIS] = base_attachment[d][X_AXIS];
+           if (extremes[d].stem_
+               && !Stem::is_invisible (extremes[d].stem_)
+               && extremes[d].stem_dir_ == dir
+               && dir == -d)
+             {
+               if (extremes[d].stem_extent_[Y_AXIS].contains (os[d][Y_AXIS]))
+                 {
+                   os[d][X_AXIS] =  extremes[d].slur_head_extent_[-d]
+                     - d * 0.3;
+                   attach_to_stem[d] = true;
+                 }
+               else if (dir *extremes[d].stem_extent_[Y_AXIS][dir] < dir * os[d][Y_AXIS])
+                 {
+                   os[d][X_AXIS] = extremes[d].stem_extent_[X_AXIS].center();
+                 }
+             }
+         } while (flip (&d) != LEFT);
+
+         Offset dz;      
+         dz = os[RIGHT] - os[LEFT];
+         if (dz[X_AXIS] < minimum_length
+             || fabs (dz[Y_AXIS] / dz[X_AXIS]) > score_param->MAX_SLOPE
+             )
+           {
+             do
+               {
+                 if (extremes[d].slur_head_)
+                   {
+                     os[d][X_AXIS] = extremes[d].slur_head_extent_.center ();
+                     attach_to_stem[d] = false;
+                   }
+               }
+             while (flip (&d) != LEFT);
+           }
+
+         dz = os[RIGHT] - os[LEFT];
+         do {
+           if (extremes[d].slur_head_
+               && !attach_to_stem[d])
+             {
+               /*
+                 horizontally move tilted slurs a little. Move more
+                 for bigger tilts.
+
+                 TODO: parameter
+               */
+               os[d][X_AXIS] -=
+                 dir * extremes[d].slur_head_extent_.length () * sin (dz.arg  ()) / 3;
+             }
+         } while (flip (&d) != LEFT);
+         
+         s.attachment_ = os;
+         scores.push (s);
+
+         os[RIGHT][Y_AXIS] += dir * staff_space / 2;
+       }
+
+      os[LEFT][Y_AXIS] += dir * staff_space / 2;
+    }
+
+  return scores;
+}
+
+void
+score_encompass (Grob *me, Grob *common[],
+                Slur_score_parameters *score_param,
+                Drul_array<Bound_info> ,
+                Drul_array<Offset> ,
+                Array<Slur_score> * scores)
+{
+  Link_array<Grob> encompasses
+    = Pointer_group_interface__extract_grobs (me, (Grob *)0, "note-columns");
+  Direction dir = get_grob_direction (me);
+
+  Array<Encompass_info> infos;
+
+  for (int i = 0; i < encompasses.size(); i++)
+    infos.push (get_encompass_info (me, encompasses[i], common));
+
+  for (int i = 0; i < scores->size (); i++)
+    {
+      Bezier const &bez (scores->elem (i).curve_);
+      Real demerit = 0.0;
+      for (int j = 0; j < infos.size(); j++)
+       {
+         Real x = infos[j].x_;
+
+         bool l_edge = j==0;
+         bool r_edge = j==infos.size()-1;
+         bool edge =  l_edge || r_edge;
+  
+         if (!(x < scores->elem (i).attachment_[RIGHT][X_AXIS]
+               && x > scores->elem (i).attachment_[LEFT][X_AXIS]))
+           continue;
+       
+         Real y = bez.get_other_coordinate (X_AXIS, x);
+         if (!edge)
+           {
+             Real head_dy = (y - infos[j].head_);
+             if (dir * head_dy < 0)
+               demerit += score_param->HEAD_ENCOMPASS_PENALTY;
+             else
+               {
+                 Real hd = (head_dy)
+                   ? (1 / fabs (head_dy) - 1 / score_param->FREE_HEAD_DISTANCE)
+                   : score_param->HEAD_ENCOMPASS_PENALTY;
+                 hd = (hd >? 0)<? score_param->HEAD_ENCOMPASS_PENALTY;
+
+                 demerit += hd;        
+               }
+           }     
+
+         if (dir * (y - infos[j].stem_) < 0)
+           {
+             Real stem_dem =score_param->STEM_ENCOMPASS_PENALTY ; 
+             if ((l_edge && dir == UP)
+                 || (r_edge && dir == DOWN))
+               {
+                 stem_dem /= 5;
+               }
+
+             demerit +=  stem_dem;
+           }
+         else if (!edge)
+           {
+             Interval ext;
+             ext.add_point (infos[j].stem_);
+             ext.add_point (infos[j].head_);
+
+             demerit += - score_param->CLOSENESS_FACTOR * (dir * (y - (ext[dir] + dir * score_param->FREE_HEAD_DISTANCE)) <? 0) /
+               infos.size ();
+           }
+       }
+
+#if DEBUG_SLUR_QUANTING
+      (*scores)[i].score_card_ += to_string ("C%.2f", demerit);
+#endif
+
+      (*scores)[i].score_ += demerit;
+    }
+}
+
+void
+score_edges (Grob *me, Grob **,
+            Slur_score_parameters * score_param,
+            Drul_array<Bound_info> extremes,
+            Drul_array<Offset> base_attach,
+            Array<Slur_score> *scores)
+{
+  Direction dir = get_grob_direction (me);
+
+  for (int i = 0; i < scores->size (); i++)
+    {
+
+      Direction d = LEFT;
+      do {
+       Real y = scores->elem (i).attachment_[d][Y_AXIS];
+       Real dy = fabs (y - base_attach[d][Y_AXIS]);
+       
+       Real factor = score_param->EDGE_ATTRACTION_FACTOR;
+       Real demerit = factor * dy;
+       if (extremes[d].stem_
+           && extremes[d].stem_dir_ == dir
+           && !Stem::get_beaming (extremes[d].stem_, -d)
+           )
+         demerit /= 5;
+       
+       (*scores)[i].score_ += demerit;
+#if DEBUG_SLUR_QUANTING
+       (*scores)[i].score_card_ += to_string ("E%.2f", demerit);
+#endif
+      } while (flip (&d) != LEFT);
+    }
+}
+
+void
+score_slopes (Grob *me, Grob *common[],
+             Slur_score_parameters*score_param,
+             Drul_array<Bound_info> extremes,
+             Drul_array<Offset> base_attach,
+             Array<Slur_score> * scores)
+{
+  Drul_array<Real> ys;
+
+  Direction d = LEFT;
+  do {
+    if (extremes[d].slur_head_)
+      ys[d] = extremes[d].slur_head_ ->relative_coordinate (common[Y_AXIS],
+                                                           Y_AXIS);
+    else
+      ys[d] = extremes[d].neighbor_y_;
+  } while (flip (&d) != LEFT);
+
+  bool has_beams
+    = (extremes[LEFT].stem_ && Stem::get_beam (extremes[LEFT].stem_))
+    || (extremes[RIGHT].stem_ && Stem::get_beam (extremes[RIGHT].stem_));
+
+  Direction dir = get_grob_direction (me);
+  Real dy = ys[RIGHT] - ys[LEFT];
+  for (int i = 0; i < scores->size (); i++)
+    {
+      Offset slur_dz = (*scores)[i].attachment_[RIGHT]
+       -  (*scores)[i].attachment_[LEFT];
+      Real slur_dy = slur_dz[Y_AXIS]; 
+      Real demerit = 0.0;
+
+      demerit += ((fabs (slur_dy/slur_dz[X_AXIS])
+                  - score_param->MAX_SLOPE) >? 0)
+       * score_param->MAX_SLOPE_FACTOR;
+
+      /*
+       0.2: account for staffline offset.
+      */
+      Real max_dy = (fabs (dy) + 0.2);
+      if (has_beams)
+       max_dy += 1.0; 
+      
+      demerit += score_param->STEEPER_SLOPE_FACTOR * ((fabs (slur_dy) -max_dy) >? 0); 
+
+      
+      demerit += ((fabs (slur_dy/slur_dz[X_AXIS]) - score_param->MAX_SLOPE)>?0)  * score_param->MAX_SLOPE_FACTOR;
+      
+      if (sign (dy) == 0 &&
+         sign (slur_dy) != 0)
+       demerit += score_param->NON_HORIZONTAL_PENALTY;
+
+      if (sign (dy)
+         && sign (slur_dy)
+         && sign (slur_dy) != sign (dy))
+       demerit += has_beams
+         ? score_param->SAME_SLOPE_PENALTY / 10
+         : score_param->SAME_SLOPE_PENALTY;
+
+#if DEBUG_SLUR_QUANTING
+      (*scores)[i].score_card_ += to_string ("S%.2f",d);
+#endif
+      (*scores)[i].score_ += demerit;
+    }
+}
+
+
index c63cfce064f9e6668aaa78b36c0af2106e886eb4..36a8a2caa9598dacbea2e8952b98c540e1d3c30b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  slur.cc -- implement Slur
+  slur.cc -- implement Old_slur
 
   source file of the GNU LilyPond music typesetter
 
@@ -39,7 +39,7 @@
 
 
 void
-Slur::set_interface (Grob*me)
+Old_slur::set_interface (Grob*me)
 {
   /* Copy to mutable list. */
   me->set_property ("attachment",
@@ -47,7 +47,7 @@ Slur::set_interface (Grob*me)
 }
 
 void
-Slur::add_column (Grob*me, Grob*n)
+Old_slur::add_column (Grob*me, Grob*n)
 {
   Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-columns"), n);
   me->add_dependency (n);
@@ -56,7 +56,7 @@ Slur::add_column (Grob*me, Grob*n)
 }
 
 void
-Slur::de_uglify (Grob*me, Slur_bezier_bow* bb, Real default_height)
+Old_slur::de_uglify (Grob*me, Slur_bezier_bow* bb, Real default_height)
 {
   Real length = bb->curve_.control_[3][X_AXIS] ; 
   Real ff = bb->fit_factor ();
@@ -91,7 +91,7 @@ Slur::de_uglify (Grob*me, Slur_bezier_bow* bb, Real default_height)
 
 
 Direction
-Slur::get_default_dir (Grob*me) 
+Old_slur::get_default_dir (Grob*me) 
 {
   Link_array<Grob> encompasses =
     Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-columns");
@@ -109,9 +109,9 @@ Slur::get_default_dir (Grob*me)
 }
 
 
-MAKE_SCHEME_CALLBACK (Slur, after_line_breaking,1);
+MAKE_SCHEME_CALLBACK (Old_slur, after_line_breaking,1);
 SCM
-Slur::after_line_breaking (SCM smob)
+Old_slur::after_line_breaking (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
   if (!scm_ilength (me->get_property ("note-columns")))
@@ -127,7 +127,7 @@ Slur::after_line_breaking (SCM smob)
 
 
 void
-Slur::check_slope (Grob *me)
+Old_slur::check_slope (Grob *me)
 {
   /*
     Avoid too steep slurs.
@@ -174,7 +174,7 @@ Slur::check_slope (Grob *me)
   Set 'attachment grob property, and return it.
 */
 SCM
-Slur::set_extremities (Grob *me)
+Old_slur::set_extremities (Grob *me)
 {
   if (!get_grob_direction (me))
     set_grob_direction (me, get_default_dir (me));
@@ -214,7 +214,7 @@ Slur::set_extremities (Grob *me)
 
 
 Real
-Slur::get_boundary_notecolumn_y (Grob *me, Direction dir)
+Old_slur::get_boundary_notecolumn_y (Grob *me, Direction dir)
 {
   SCM cols = me->get_property ("note-columns");
 
@@ -248,7 +248,7 @@ Slur::get_boundary_notecolumn_y (Grob *me, Direction dir)
 }
 
 Offset
-Slur::broken_trend_offset (Grob *me, Direction dir)
+Old_slur::broken_trend_offset (Grob *me, Direction dir)
 {
   /*
     A broken slur should maintain the same vertical trend
@@ -284,7 +284,7 @@ UGH: this routine delivers offsets which are *not* relative to COMMON.
 UGH,  we should take COMMON-Y as argument.
 */ 
 Offset
-Slur::get_attachment (Grob *me, Direction dir,
+Old_slur::get_attachment (Grob *me, Direction dir,
                      Grob **common) 
 {
   SCM s = me->get_property ("attachment");
@@ -406,7 +406,7 @@ Slur::get_attachment (Grob *me, Direction dir,
 }
 
 Offset
-Slur::encompass_offset (Grob*me,
+Old_slur::encompass_offset (Grob*me,
                        Grob* col,
                        Grob **common) 
 {
@@ -454,7 +454,7 @@ Slur::encompass_offset (Grob*me,
 }
 
 Array<Offset>
-Slur::get_encompass_offsets (Grob *me)
+Old_slur::get_encompass_offsets (Grob *me)
 {
   Spanner*sp = dynamic_cast<Spanner*> (me);
   SCM eltlist = me->get_property ("note-columns");
@@ -520,9 +520,9 @@ Slur::get_encompass_offsets (Grob *me)
 /*
   ugh ?
  */
-MAKE_SCHEME_CALLBACK (Slur, height, 2);
+MAKE_SCHEME_CALLBACK (Old_slur, height, 2);
 SCM
-Slur::height (SCM smob, SCM ax)
+Old_slur::height (SCM smob, SCM ax)
 {
   Axis a = (Axis)ly_scm2int (ax);
   Grob * me = unsmob_grob (smob);
@@ -538,9 +538,9 @@ Slur::height (SCM smob, SCM ax)
 /*
   Ugh should have dash-length + dash-period
  */
-MAKE_SCHEME_CALLBACK (Slur, print,1);
+MAKE_SCHEME_CALLBACK (Old_slur, print,1);
 SCM
-Slur::print (SCM smob)
+Old_slur::print (SCM smob)
 {
   Grob * me = unsmob_grob (smob);
   if (!scm_ilength (me->get_property ("note-columns")))
@@ -575,7 +575,7 @@ Slur::print (SCM smob)
 }
 
 void
-Slur::set_control_points (Grob*me)
+Old_slur::set_control_points (Grob*me)
 {
   Real staff_space = Staff_symbol_referencer::staff_space ((Grob*)me);
 
@@ -644,7 +644,7 @@ Slur::set_control_points (Grob*me)
 }
   
 Bezier
-Slur::get_curve (Grob*me) 
+Old_slur::get_curve (Grob*me) 
 {
   Bezier b;
   int i = 0;
@@ -695,7 +695,7 @@ Slur::get_curve (Grob*me)
 
 
 
-ADD_INTERFACE (Slur,"slur-interface",
+ADD_INTERFACE (Old_slur,"slur-interface",
   "A slur",
   "attachment attachment-offset beautiful control-points dashed details de-uglify-parameters direction extremity-function extremity-offset-alist height-limit note-columns ratio slope-limit thickness y-free quant-score");
 
index 2cdda26f88ed20a86b3518df5ed189f930801411..8323f77c689e7ce6f89c6ab6c2167e44770334e9 100644 (file)
 
     (PhrasingSlur
      . (
-       (print-function . ,Slur::print)
+       (print-function . ,New_slur::print)
        (thickness . 1.2)               
        (spacing-procedure . ,Spanner::set_spacing_rods)                
        (minimum-length . 1.5)
-       (after-line-breaking-callback . ,Slur::after_line_breaking)
-       (extremity-function . ,calc-slur-extremity)
-       (extremity-offset-alist . ,default-phrasing-slur-extremity-offset-alist)
-       (de-uglify-parameters . (1.5  0.8  -2.0))
-       (Y-extent-callback . ,Slur::height)
+       (after-line-breaking-callback . ,New_slur::after_line_breaking)
+       (Y-extent-callback . ,New_slur::height)
        (height-limit . 2.0)
        (ratio . 0.333)
-       (beautiful . 0.5)
-       (y-free . 0.75)
-       (attachment . (#f . #f))
-       (attachment-offset . ((0 . 0) . (0 . 0)))
-       (slope-limit . 0.8)
-       (details . ((force-blowfit . 0.5)
-                   (bezier-pct-c0 . -0.2) (bezier-pct-c3 . 0.000006)
-                   (bezier-pct-out-max . 0.8) (bezier-pct-in-max . 1.2)
-                   (bezier-area-steps . 1.0)))
        (meta . ((interfaces . (slur-interface spanner-interface))))
        ))
 
     (Slur
      . (
        (print-function . ,New_slur::print)
-       ; ,Slur::print)
        (thickness . 1.2)               
        (spacing-procedure . ,Spanner::set_spacing_rods)                
        (minimum-length . 1.5)
-       (after-line-breaking-callback .
-                                     ,New_slur::after_line_breaking)
-               ;                     ,Slur::after_line_breaking)
-       (extremity-function . ,calc-slur-extremity)
-       (extremity-offset-alist . ,default-slur-extremity-offset-alist)
-       (de-uglify-parameters . (1.5  0.8  -2.0))
-       (Y-extent-callback .
-                          ,New_slur::height)
+       (after-line-breaking-callback . ,New_slur::after_line_breaking)
+       (Y-extent-callback . ,New_slur::height)
                                        ; Slur::height)
        (height-limit . 2.0)
        (ratio . 0.25)
-       (beautiful . 0.5)
-       (y-free . 0.75)
-       (attachment . (#f . #f))
-       (attachment-offset . ((0 . 0) . (0 . 0)))
-       (slope-limit . 0.8)
-       (details . ((force-blowfit . 0.5)
-                   (bezier-pct-c0 . -0.2) (bezier-pct-c3 . 0.000006)
-                   (bezier-pct-out-max . 0.8) (bezier-pct-in-max . 1.2)
-                   (bezier-area-steps . 1.0)))
        (meta . ((interfaces . (slur-interface spanner-interface))))
        ))