]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 1.3.64.jcn1
authorJan Nieuwenhuizen <janneke@gnu.org>
Mon, 26 Jun 2000 14:21:27 +0000 (16:21 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Mon, 26 Jun 2000 14:21:27 +0000 (16:21 +0200)
1.3.63.jcn1
============

* Started grand redo of slur endings, interstaff slurs are broken for now.

* Fixed download url.

* Moved direction.cc to flower.

CHANGES
VERSION
flower/direction.cc [new file with mode: 0644]
lily/direction.cc
lily/include/slur-bezier-bow.hh [new file with mode: 0644]
lily/include/slur.hh
lily/slur-bezier-bow.cc [new file with mode: 0644]
lily/slur.cc
ly/declarations.ly
scm/slur.scm [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index da042c27fc0ea9dec4e0ff1703e13bc3cdef155a..0d289e95fa1040fa987ed68e99bab2fe2114389d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+1.3.63.jcn1
+============
+* Started grand redo of slur endings, interstaff slurs are broken for now.
+
+* Fixed download url.
+
+* Moved direction.cc to flower.
+
 1.3.63.uu1
 ==========
 
diff --git a/VERSION b/VERSION
index 98dbd94bffe78b7ce704ae0c9a81e1bd1a7d7871..914fac17459bbd811d22598683883b1463865ca7 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
 PATCH_LEVEL=64
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=jcn1
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
diff --git a/flower/direction.cc b/flower/direction.cc
new file mode 100644 (file)
index 0000000..aeddc31
--- /dev/null
@@ -0,0 +1,25 @@
+/*   
+  direction.cc --  implement Direction
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1998--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "direction.hh"
+
+String
+direction_str (Direction d, Axis a)
+{
+  String s("center");
+  if (a == Y_AXIS)
+    {
+       s =( d == UP ? "up" : "down");
+    }
+  else if (a == X_AXIS)
+    {
+      s = (d == LEFT ? "left" : "right" );
+    }
+  return s;
+}
index aeddc311a27d733bcbf7321fcd4dce837018d932..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,25 +0,0 @@
-/*   
-  direction.cc --  implement Direction
-  
-  source file of the GNU LilyPond music typesetter
-  
-  (c) 1998--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-  
- */
-
-#include "direction.hh"
-
-String
-direction_str (Direction d, Axis a)
-{
-  String s("center");
-  if (a == Y_AXIS)
-    {
-       s =( d == UP ? "up" : "down");
-    }
-  else if (a == X_AXIS)
-    {
-      s = (d == LEFT ? "left" : "right" );
-    }
-  return s;
-}
diff --git a/lily/include/slur-bezier-bow.hh b/lily/include/slur-bezier-bow.hh
new file mode 100644 (file)
index 0000000..7fbbffd
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+  slur-bezier-bow.hh -- declare Slur_bezier_bow
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2000  Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#ifndef SLUR_BEZIER_BOW_HH
+#define SLUR_BEZIER_BOW_HH
+
+#include "bezier-bow.hh"
+
+class Slur_bezier_bow : public Bezier_bow
+{
+public:
+  Slur_bezier_bow (Array<Offset> encompass, Direction dir);
+  Array<Real> area_x_gradients_array (Real area);
+  void blow_fit ();
+  Real enclosed_area_f () const;
+  Real fit_factor () const;
+  void minimise_enclosed_area (Paper_def* paper_l, Real default_height);
+};
+#endif /* SLUR_BEZIER_BOW_HH */
index 654bc45685dec606e24036afc8f73c3d4db4ca50..80b18fbfc7569a1100ad96951262969011140aec 100644 (file)
@@ -26,17 +26,12 @@ public:
   virtual Array<Offset> get_encompass_offset_arr () const;
   Bezier get_curve () const;
 
-  /*
-    JUNKME
-   */
-  Drul_array<Real> dy_f_drul_;
-  Drul_array<Real> dx_f_drul_;
-
   virtual Direction get_default_dir () const;
   SCM member_after_line_breaking ();
   static SCM after_line_breaking (SCM);
   virtual void do_add_processing ();
   Array<Rod> get_rods () const;
+  Offset get_attachment (Direction dir) const;
 
 private:  
   void de_uglyfy (Slur_bezier_bow* bb, Real default_height);
diff --git a/lily/slur-bezier-bow.cc b/lily/slur-bezier-bow.cc
new file mode 100644 (file)
index 0000000..0dc7ba2
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+  slur-bezier-bow.cc -- implement Slur_bezier_bow
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2000  Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+#include "debug.hh"
+#include "paper-def.hh"
+#include "slur-bezier-bow.hh"
+#include "main.hh"
+
+Slur_bezier_bow::Slur_bezier_bow (Array<Offset> encompass, Direction dir)
+  : Bezier_bow (encompass, dir)
+{
+}
+
+void
+Slur_bezier_bow::blow_fit ()
+{
+  Real len = curve_.control_[3][X_AXIS]; 
+  Real h = curve_.control_[1][Y_AXIS] * fit_factor () / len;
+  curve_.control_[1][Y_AXIS] = h * len;
+  curve_.control_[2][Y_AXIS] = h * len;  
+  curve_.assert_sanity ();
+}
+
+
+Real
+Slur_bezier_bow::enclosed_area_f () const
+{
+  Real a = 0;
+  for (int i=0; i < encompass_.size (); i++)
+    {
+      Interval x;
+      Interval y;
+      if (i == 0)
+       {
+         x = Interval (0, encompass_[1][X_AXIS] / 2);
+         y = Interval (0,
+                       curve_.get_other_coordinate (X_AXIS,
+                                                    encompass_[1][X_AXIS]
+                                                    / 2));
+       }
+      else if (i == encompass_.size () - 1)
+       {
+         x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS])/2, 
+                       encompass_[i][X_AXIS]);
+         y = Interval (0,
+                       (curve_.get_other_coordinate (X_AXIS,
+                                                     (x[MIN] + x[MAX]) / 2)));
+       }
+      else
+       {
+         x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS]) / 2, 
+                       (encompass_[i][X_AXIS] + encompass_[i+1][X_AXIS]) / 2);
+         y = Interval (encompass_[i][Y_AXIS],
+                       (curve_.get_other_coordinate (X_AXIS, x[MIN])
+                        + curve_.get_other_coordinate (X_AXIS,
+                                                       (x[MIN] + x[MAX]) / 2)
+                        + curve_.get_other_coordinate (X_AXIS, x[MAX])) / 3);
+       }
+      
+      Real da = x.length () * y.length ();
+      a += da;
+    }
+  return a;
+}
+
+Array<Real>
+Slur_bezier_bow::area_x_gradients_array (Real area)
+{
+  Real len = curve_.control_[3][X_AXIS]; 
+  Real grow = len / 10.0;
+  Array<Real> da (2);
+  for (int i=0; i < 2; i++)
+    {
+      Real r = curve_.control_[i+1][X_AXIS];
+      curve_.control_[i+1][X_AXIS] += grow;
+      da[i] = (enclosed_area_f () - area) / grow;
+      curve_.control_[i+1][X_AXIS] = r; 
+    }
+  return da;
+}
+
+void
+Slur_bezier_bow::minimise_enclosed_area (Paper_def* paper_l,
+                                        Real default_height)
+{
+  Real length = curve_.control_[3][X_AXIS]; 
+  Real sb = paper_l->get_var ("slur_beautiful");
+  Real beautiful = length * default_height * sb;
+
+  DEBUG_OUT << to_str ("Beautiful: %f\n", beautiful);
+  DEBUG_OUT << to_str ("Length: %f\n", length);
+  DEBUG_OUT << to_str ("D-height: %f\n", default_height);
+  DEBUG_OUT << to_str ("FitFac: %f\n", fit_factor ());
+
+  if (fit_factor () > 1.0)
+    blow_fit ();
+  
+  Real pct_c0 = paper_l->get_var ("bezier_pct_c0");
+  Real pct_c3 = paper_l->get_var ("bezier_pct_c3");
+  Real pct_in_max = paper_l->get_var ("bezier_pct_in_max");
+  Real pct_out_max = paper_l->get_var ("bezier_pct_out_max");
+  Real steps = paper_l->get_var ("bezier_area_steps");
+
+  for (int i=0; i < steps; i++)
+    {
+      Real area = enclosed_area_f ();
+      if (!i)
+       DEBUG_OUT << to_str ("Init area: %f\n", area);
+
+      if (area <= beautiful)
+       break;
+
+      Array<Real> da = area_x_gradients_array (area);
+
+      // urg
+      Real pct = pct_c0 + pct_c3 * length * length * length;
+      pct *= (steps - i) / steps;
+      if (da[0] > 0 || da[1] < 0)
+       pct = pct <? pct_out_max;
+      else
+       pct = pct <? pct_in_max;
+
+      Real u = (abs (curve_.control_[1][X_AXIS] / da[0])
+               <? abs ((curve_.control_[3][X_AXIS]
+                        - curve_.control_[2][X_AXIS]) / da[1]));
+
+      DEBUG_OUT << to_str ("pct: %f\n", pct);
+      DEBUG_OUT << to_str ("u: %f\n", u);
+
+      DEBUG_OUT << to_str ("da: (%f, %f)\n", da[0], da[1]);
+      DEBUG_OUT << to_str ("da*u: (%f, %f)\n", da[0]*u*pct, da[1]*u*pct);
+      DEBUG_OUT << to_str ("cx: (%f, %f)\n", curve_.control_[1][X_AXIS],
+                          curve_.control_[2][X_AXIS]);
+
+      curve_.control_[1][X_AXIS] -= da[0] * u * pct;
+      curve_.control_[2][X_AXIS] -= da[1] * u * pct;
+    }
+
+  Real area = enclosed_area_f ();
+  DEBUG_OUT << to_str ("Exarea: %f\n", area);
+}
+
+
+
+/*
+  max ( encompass.y / curve.y )
+  
+ */
+Real
+Slur_bezier_bow::fit_factor () const
+{
+  Real x1 = encompass_[0][X_AXIS];
+  Real x2 = encompass_.top ()[X_AXIS];
+
+  Real factor = 0.0;
+  for (int i=1; i < encompass_.size ()-1; i++)
+    {
+      if (encompass_[i][X_AXIS] > x1 && encompass_[i][X_AXIS] < x2)
+       {
+        Real y = curve_.get_other_coordinate (X_AXIS, encompass_[i][X_AXIS]);
+        if (y>0)
+          {
+            Real f = encompass_[i][Y_AXIS] / y;
+            factor = factor >? f;
+          }
+       }
+    }
+
+
+  return factor;
+}
+
+
+
+
index fd59628e5703066ceb55b88b747b067e9c95ad86..aaed8b51a148a4244748f9cff1fac1a15caae66c 100644 (file)
 #include "paper-column.hh"
 #include "molecule.hh"
 #include "debug.hh"
-#include "box.hh"
-#include "bezier-bow.hh"
+#include "slur-bezier-bow.hh"
 #include "main.hh"
 #include "cross-staff.hh"
 #include "group-interface.hh"
 #include "staff-symbol-referencer.hh"
 
-class Slur_bezier_bow : public Bezier_bow
-{
-public:
-  Slur_bezier_bow (Array<Offset> encompass, Direction dir);
-  Array<Real> area_x_gradients_array (Real area);
-  void blow_fit ();
-  Real enclosed_area_f () const;
-  Real fit_factor () const;
-  void minimise_enclosed_area (Paper_def* paper_l, Real default_height);
-};
-
-Slur_bezier_bow::Slur_bezier_bow (Array<Offset> encompass, Direction dir)
-  : Bezier_bow (encompass, dir)
-{
-}
-
-void
-Slur_bezier_bow::blow_fit ()
-{
-  Real len = curve_.control_[3][X_AXIS]; 
-  Real h = curve_.control_[1][Y_AXIS] * fit_factor () / len;
-  curve_.control_[1][Y_AXIS] = h * len;
-  curve_.control_[2][Y_AXIS] = h * len;  
-  curve_.assert_sanity ();
-}
-
-
-Real
-Slur_bezier_bow::enclosed_area_f () const
-{
-  Real a = 0;
-  for (int i=0; i < encompass_.size (); i++)
-    {
-      Interval x;
-      Interval y;
-      if (i == 0)
-       {
-         x = Interval (0, encompass_[1][X_AXIS] / 2);
-         y = Interval (0,
-                       curve_.get_other_coordinate (X_AXIS,
-                                                    encompass_[1][X_AXIS]
-                                                    / 2));
-       }
-      else if (i == encompass_.size () - 1)
-       {
-         x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS])/2, 
-                       encompass_[i][X_AXIS]);
-         y = Interval (0,
-                       (curve_.get_other_coordinate (X_AXIS,
-                                                     (x[MIN] + x[MAX]) / 2)));
-       }
-      else
-       {
-         x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS]) / 2, 
-                       (encompass_[i][X_AXIS] + encompass_[i+1][X_AXIS]) / 2);
-         y = Interval (encompass_[i][Y_AXIS],
-                       (curve_.get_other_coordinate (X_AXIS, x[MIN])
-                        + curve_.get_other_coordinate (X_AXIS,
-                                                       (x[MIN] + x[MAX]) / 2)
-                        + curve_.get_other_coordinate (X_AXIS, x[MAX])) / 3);
-       }
-      
-      Real da = x.length () * y.length ();
-      a += da;
-    }
-  return a;
-}
-
-Array<Real>
-Slur_bezier_bow::area_x_gradients_array (Real area)
-{
-  Real len = curve_.control_[3][X_AXIS]; 
-  Real grow = len / 10.0;
-  Array<Real> da (2);
-  for (int i=0; i < 2; i++)
-    {
-      Real r = curve_.control_[i+1][X_AXIS];
-      curve_.control_[i+1][X_AXIS] += grow;
-      da[i] = (enclosed_area_f () - area) / grow;
-      curve_.control_[i+1][X_AXIS] = r; 
-    }
-  return da;
-}
-
-void
-Slur_bezier_bow::minimise_enclosed_area (Paper_def* paper_l,
-                                        Real default_height)
-{
-  Real length = curve_.control_[3][X_AXIS]; 
-  Real sb = paper_l->get_var ("slur_beautiful");
-  Real beautiful = length * default_height * sb;
-
-  DEBUG_OUT << to_str ("Beautiful: %f\n", beautiful);
-  DEBUG_OUT << to_str ("Length: %f\n", length);
-  DEBUG_OUT << to_str ("D-height: %f\n", default_height);
-  DEBUG_OUT << to_str ("FitFac: %f\n", fit_factor ());
-
-  if (fit_factor () > 1.0)
-    blow_fit ();
-  
-  Real pct_c0 = paper_l->get_var ("bezier_pct_c0");
-  Real pct_c3 = paper_l->get_var ("bezier_pct_c3");
-  Real pct_in_max = paper_l->get_var ("bezier_pct_in_max");
-  Real pct_out_max = paper_l->get_var ("bezier_pct_out_max");
-  Real steps = paper_l->get_var ("bezier_area_steps");
-
-  for (int i=0; i < steps; i++)
-    {
-      Real area = enclosed_area_f ();
-      if (!i)
-       DEBUG_OUT << to_str ("Init area: %f\n", area);
-
-      if (area <= beautiful)
-       break;
-
-      Array<Real> da = area_x_gradients_array (area);
-
-      // urg
-      Real pct = pct_c0 + pct_c3 * length * length * length;
-      pct *= (steps - i) / steps;
-      if (da[0] > 0 || da[1] < 0)
-       pct = pct <? pct_out_max;
-      else
-       pct = pct <? pct_in_max;
-
-      Real u = (abs (curve_.control_[1][X_AXIS] / da[0])
-               <? abs ((curve_.control_[3][X_AXIS]
-                        - curve_.control_[2][X_AXIS]) / da[1]));
-
-      DEBUG_OUT << to_str ("pct: %f\n", pct);
-      DEBUG_OUT << to_str ("u: %f\n", u);
-
-      DEBUG_OUT << to_str ("da: (%f, %f)\n", da[0], da[1]);
-      DEBUG_OUT << to_str ("da*u: (%f, %f)\n", da[0]*u*pct, da[1]*u*pct);
-      DEBUG_OUT << to_str ("cx: (%f, %f)\n", curve_.control_[1][X_AXIS],
-                          curve_.control_[2][X_AXIS]);
-
-      curve_.control_[1][X_AXIS] -= da[0] * u * pct;
-      curve_.control_[2][X_AXIS] -= da[1] * u * pct;
-    }
-
-  Real area = enclosed_area_f ();
-  DEBUG_OUT << to_str ("Exarea: %f\n", area);
-}
-
-
-
-/*
-  max ( encompass.y / curve.y )
-  
- */
-Real
-Slur_bezier_bow::fit_factor () const
-{
-  Real x1 = encompass_[0][X_AXIS];
-  Real x2 = encompass_.top ()[X_AXIS];
-
-  Real factor = 0.0;
-  for (int i=1; i < encompass_.size ()-1; i++)
-    {
-      if (encompass_[i][X_AXIS] > x1 && encompass_[i][X_AXIS] < x2)
-       {
-        Real y = curve_.get_other_coordinate (X_AXIS, encompass_[i][X_AXIS]);
-        if (y>0)
-          {
-            Real f = encompass_[i][Y_AXIS] / y;
-            factor = factor >? f;
-          }
-       }
-    }
-
-
-  return factor;
-}
-
-
-
-
-
-/*
-  Slur
-*/
-
 Slur::Slur (SCM s)
   : Spanner (s)
 {
-  // URG
-  dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = 0.0;
-  dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0;
-
+  /*
+    silly value for testing
+   */
+  set_elt_property ("attachment", gh_cons (ly_symbol2scm ("alongside-stem"),
+                                          ly_symbol2scm ("alongside-stem")));
   set_elt_pointer ("note-columns", SCM_EOL);
   set_elt_property ("control-points", SCM_EOL);
 }
@@ -351,168 +168,121 @@ Slur::member_after_line_breaking ()
   return SCM_UNDEFINED;
 } 
 
-/*
-  urg
-  FIXME
- */
-void
-Slur::set_extremities ()
+SCM
+slur_get_bound (SCM slur, SCM dir)
 {
-  Link_array<Note_column> encompass_arr =
-    Pointer_group_interface__extract_elements (this, (Note_column*)0, "note-columns");
-
-  if (!encompass_arr.size ())
-    {
-      suicide();
-      return;
-    }
-
-  if (!directional_element (this).get ())
-    directional_element (this).set (get_default_dir ());
-
-
-  /* 
-   Slur and tie placement [OSU]
-
-   Slurs:
-   * x = centre of head - d * x_gap_f
+  return ((Slur*)unsmob_element (slur))->get_bound (to_dir (dir))->self_scm_;
+}
 
-   TODO:
-   * y = length < 5ss : horizontal tangent + d * 0.25 ss
-     y = length >= 5ss : y next interline - d * 0.25 ss
-   */
+SCM
+score_element_get_pointer (SCM se, SCM name)
+{
+  SCM s = scm_assq (name, unsmob_element (se)->pointer_alist_);
+  return (s == SCM_BOOL_F) ? SCM_UNDEFINED : gh_cdr (s); 
+}
 
-  Real staff_space = paper_l ()->get_var ("interline");
-  Real half_staff_space = staff_space / 2;
+SCM
+score_element_get_property (SCM se, SCM name)
+{
+  SCM s = scm_assq (name, unsmob_element (se)->property_alist_);
+  return (s == SCM_BOOL_F) ? SCM_UNDEFINED : gh_cdr (s); 
+}
 
-  Real x_gap_f = paper_l ()->get_var ("slur_x_gap");
-  Real y_gap_f = paper_l ()->get_var ("slur_y_gap");
+void
+init_score_elts ()
+{
+  scm_make_gsubr ("get-pointer", 2 , 0, 0,  
+                 (SCM(*)(...)) score_element_get_pointer);
+  scm_make_gsubr ("get-property", 2 , 0, 0,  
+                 (SCM(*)(...)) score_element_get_property);
+  scm_make_gsubr ("get-bound", 2 , 0, 0,  
+                 (SCM(*)(...)) slur_get_bound);
+}
 
-  Drul_array<Note_column*> note_column_drul;
-  note_column_drul[LEFT] = encompass_arr[0];
-  note_column_drul[RIGHT] = encompass_arr.top ();
+ADD_SCM_INIT_FUNC (score_elt, init_score_elts);
 
-  bool fix_broken_b = false;
+void
+Slur::set_extremities ()
+{
+  if (!directional_element (this).get ())
+    directional_element (this).set (get_default_dir ());
 
-  Direction my_dir = directional_element (this).get ();
-  
-  Direction d = LEFT;
+  Direction dir = LEFT;
   do 
     {
-      dx_f_drul_[d] = 0;
-      dy_f_drul_[d] = 0;
-      
-      if ((note_column_drul[d] == get_bound (d))
-         && note_column_drul[d]->first_head ()
-         && (note_column_drul[d]->stem_l ()))
+      // for (SCM s = get_elt_property ("slur-extremity-rules"); s != SCM_EOL; s = gh_cdr (s))
+      for (SCM s = scm_eval (ly_symbol2scm ("slur-extremity-rules"));
+          s != SCM_EOL; s = gh_cdr (s))
        {
-         Stem* stem_l = note_column_drul[d]->stem_l ();
-         /*
-           side directly attached to note head;
-           no beam getting in the way
-         */
-         if ((stem_l->extent (Y_AXIS).empty_b ()
-              || !((stem_l->get_direction () == my_dir) && (my_dir != d)))
-             && !((my_dir == stem_l->get_direction ())
-                  && stem_l->beam_l () && (stem_l->beam_count (-d) >= 1)))
+         SCM r = scm_eval (scm_listify (gh_caar (s),
+                                        this->self_scm_,
+                                        gh_int2scm ((int)dir),
+                                        SCM_UNDEFINED));
+         if (r != SCM_BOOL_F)
            {
-             dx_f_drul_[d] = get_bound (d)->extent (X_AXIS).length () / 2;
-             dx_f_drul_[d] -= d * x_gap_f;
+             index_set_cell (get_elt_property ("attachment"), dir,
+                             gh_cdar (s));
+             break;
+           }
+       }
+    }
+  while (flip (&dir) != LEFT);
+}
 
-             if (stem_l->get_direction () != my_dir)
-               {
-                 dy_f_drul_[d] = note_column_drul[d]->extent (Y_AXIS)[my_dir];
-               }
-             else
-               {
-                 dy_f_drul_[d] = stem_l->chord_start_f ()
-                   + my_dir * half_staff_space;
-               }
-             dy_f_drul_[d] += my_dir * y_gap_f;
+Offset
+Slur::get_attachment (Direction dir) const
+{
+  SCM s = get_elt_property ("attachment");
+  SCM a = dir == LEFT ? gh_car (s) : gh_cdr (s);
+  Real ss = Staff_symbol_referencer_interface (this).staff_space ();
+  Real hs = ss / 2.0;
+  Offset o;
+  if (Note_column* n = dynamic_cast<Note_column*> (get_bound (dir)))
+    {
+      if (Stem* st = dynamic_cast<Stem*> (n->stem_l ()))
+       {
+         String str = ly_symbol2string (a);
+         if (str == "head")
+           {
+             o = Offset (0, st->chord_start_f ());
            }
-         /*
-           side attached to (visible) stem
-         */
-         else
+         else if (str == "alongside-stem")
            {
-             dx_f_drul_[d] = stem_l->relative_coordinate (0, X_AXIS)
-               - get_bound (d)->relative_coordinate (0, X_AXIS);
-             /*
-               side attached to beamed stem
-              */
-             if (stem_l->beam_l () && (stem_l->beam_count (-d) >= 1))
-               {
-                 dy_f_drul_[d] = stem_l->extent (Y_AXIS)[my_dir];
-                 dy_f_drul_[d] += my_dir * 2 * y_gap_f;
-               }
-             /*
-               side attached to notehead, with stem getting in the way
-              */
-             else
+             o = Offset (0, st->chord_start_f ());
+           }
+         else if (str == "stem")
+           {
+             o = Offset (0, st->stem_end_position () * hs);
+           }
+         else if (str == "loose-end")
+           {
+             SCM other_a = dir == LEFT ? gh_cdr (s) : gh_car (s);
+             if (ly_symbol2string (other_a) != "loose-end")
                {
-                 dx_f_drul_[d] -= d * x_gap_f;
-                 
-                 dy_f_drul_[d] = stem_l->chord_start_f ()
-                   + my_dir * half_staff_space;
-                 dy_f_drul_[d] += my_dir * y_gap_f;
+                 o = Offset (0, get_attachment (-dir)[Y_AXIS]);
                }
            }
-       }
-      /*
-       loose end
-      */
-      else
-       {
-         dx_f_drul_[d] = get_broken_left_end_align ();
-               
-         /*
-           broken: should get y from other piece, so that slur
-           continues up/down trend
-
-           for now: be horizontal..
-         */
-         fix_broken_b = true;
-       }
-    }
-  while (flip (&d) != LEFT);
-
-  int cross_count =  cross_staff_count ();
-  bool interstaff_b = (0 < cross_count) && (cross_count < encompass_arr.size ());
 
-  Drul_array<Offset> info_drul;
-  Drul_array<Real> interstaff_interval;
-
-  do
-    {
-      info_drul[d] = encompass_offset (encompass_arr.boundary (d, 0));
-      interstaff_interval[d] = - calc_interstaff_dist (encompass_arr.boundary (d,0),
-                                                    this);
-    }
-  while (flip (&d) != LEFT);
-  
-  Real interstaff_f = interstaff_interval[RIGHT] - interstaff_interval[LEFT];
-
-  if (fix_broken_b)
-    {
-      Direction d = (encompass_arr.top () != get_bound (RIGHT)) ?
-       RIGHT : LEFT;
-      dy_f_drul_[d] = info_drul[d][Y_AXIS];
-      if (!interstaff_b)
-       {
-         dy_f_drul_[d] -= interstaff_interval[d];
-         if (cross_count)      // interstaff_i  ? 
+         o += Offset (0.5 * st->get_direction ()
+                      * n->extent (X_AXIS).length (), 0);
+         
+         SCM l = scm_assoc
+           (scm_listify (a,
+                         gh_int2scm (st->get_direction () * dir),
+                         gh_int2scm (directional_element (this).get () * dir),
+                         SCM_UNDEFINED),
+            scm_eval (ly_symbol2scm ("slur-extremity-offset-alist")));
+         
+         if (l != SCM_BOOL_F)
            {
-             dy_f_drul_[LEFT] += interstaff_interval[d];
-             dy_f_drul_[RIGHT] += interstaff_interval[d];
+             o += ly_scm2offset (gh_cdr (l)) * ss * dir;
            }
        }
     }
-       
-  if (!fix_broken_b)
-    dy_f_drul_[RIGHT] += interstaff_f;
+  
+  return o;
 }
 
-
 int
 Slur::cross_staff_count ()const
 {
@@ -538,27 +308,16 @@ Slur::get_encompass_offset_arr () const
   
   Array<Offset> offset_arr;
 
-#if 0
-  /*
-    check non-disturbed slur
-    FIXME: x of ends off by a tiny bit!!
-  */
-  offset_arr.push (Offset (0, dy_f_drul_[LEFT]));
-  offset_arr.push (Offset (0, dy_f_drul_[RIGHT]));
-  return offset_arr;
-#endif
-  
   Offset origin (relative_coordinate (0, X_AXIS), 0);
 
   int first = 1;
   int last = encompass_arr.size () - 2;
 
-  offset_arr.push (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT]));
+  offset_arr.push (get_attachment (LEFT));
 
   /*
     left is broken edge
   */
-
   int cross_count  = cross_staff_count ();
   bool cross_b = cross_count && cross_count < encompass_arr.size ();
   if (encompass_arr[0] != get_bound (LEFT))
@@ -583,8 +342,7 @@ Slur::get_encompass_offset_arr () const
       offset_arr.push (o - origin);
     }
 
-  offset_arr.push (Offset (spanner_length ()+  dx_f_drul_[RIGHT],
-                          dy_f_drul_[RIGHT]));
+  offset_arr.push (Offset (spanner_length (), 0) + get_attachment (RIGHT));
 
   return offset_arr;
 }
index e6f16c153990b2bd36921c4a15db6494995cf6af..ec640fb578d0d2522df10b4bb185498f3f447ef1 100644 (file)
@@ -6,6 +6,9 @@ maxima = \duration #'( -3 0 )
 
 #(eval-string (ly-gulp-file "generic-property.scm"))
 
+% urg, move to basic property?
+#(eval-string (ly-gulp-file "slur.scm"))
+
 \include "nederlands.ly"               % dutch
 \include "chord-modifiers.ly"
 \include "script.ly"
diff --git a/scm/slur.scm b/scm/slur.scm
new file mode 100644 (file)
index 0000000..ce6f4be
--- /dev/null
@@ -0,0 +1,62 @@
+
+;;;  als aan echte stok
+;;;      if ((note_column_drul[d] == get_bound (d))
+;;;      && note_column_drul[d]->first_head ()
+;;;      && (note_column_drul[d]->stem_l ()))
+;;;
+;;;  *Need: Score_elment::pointer_alist_
+;;;         Score_elment::property_alist_
+;;;         Spanner::Drul_array<Item*> spanned_drul_;
+;;;         spanner:: (cons get_bound (LEFT) get_bound (RIGHT))
+
+(define (attached-to-stem slur dir)
+  (let* ((note-columns (get-pointer slur 'note-columns))
+        (col (if (= dir 1) (car note-columns) (car (reverse note-columns))))
+        (stem (get-pointer col 'stem)))
+    (and
+     (eq? col (get-bound slur dir))
+     stem
+     (get-pointer stem 'heads))))
+
+(define slur-extremity-rules
+  '(
+    ;;if (stem_l->beam_l () && (stem_l->beam_count (-d) >= 1))
+    ((lambda (slur dir)
+       ;; urg, code dup
+       ;; if attached-to-stem
+       (let* ((note-columns (get-pointer slur 'note-columns))
+        (col (if (= dir 1) (car note-columns) (car (reverse note-columns))))
+        (stem (get-pointer col 'stem)))
+        (and
+         (and
+          (eq? col (get-bound slur dir))
+          stem
+          (get-pointer stem 'heads))
+         ;; and got beam
+         (and (get-pointer stem 'beam)
+              ;; and beam on same side as slur
+              (let ((beaming (get-property stem 'beaming)))
+                (if (pair? beaming)
+                    (>= 1
+                        (if (= dir -1) (car beaming) (cdr beaming)))
+                    #f)))))) . stem)
+    ((lambda (slur dir) (not (attached-to-stem slur dir))) . loose-end)
+    ;; default case, attach to head
+    ((lambda (x y) #t) . head)
+    
+  ;; silly rule, just to check
+  ((lambda (slur dir)
+       (and (attached-to-stem slur dir) 
+           (= (get-property slur 'direction) dir))) . stem)
+  ))
+
+
+(define slur-extremity-offset-alist
+  '(
+    ((head 1 1) . (-0.25 . 0.2))
+    ((head 1 -1) . (-0.25 . -0.75))
+    ((head -1 1) . (-0.25 . 0.75))
+    ((head -1 -1) . (-0.75 . 1.2))
+    ((stem 1 1) . (0 . 0.2))
+    ((stem -1 -1) . (0 . 0.2))
+    ))