]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/slur.cc
release: 1.3.19
[lilypond.git] / lily / slur.cc
index 30112212c89861d337631def9ace88c889c1b919..e7adc849b420636686c597bae4a1dbe10a98ed35 100644 (file)
@@ -3,7 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1996,  1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  (c) 1996,  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
     Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
 #include "debug.hh"
 #include "box.hh"
 #include "bezier.hh"
+#include "bezier-bow.hh"
 #include "main.hh"
 #include "cross-staff.hh"
 #include "group-interface.hh"
 
 Slur::Slur ()
 {
+  dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = 0.0;
+  dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0;
   set_elt_property ("note-columns", SCM_EOL);
 }
 
@@ -322,8 +325,11 @@ Slur::do_post_processing ()
    */
   for (int i = 0; i < 3; i++)
     {
-      Real height_f = curve_extent (Y_AXIS).length ();
-      Real width_f = curve_extent (X_AXIS).length ();
+      Bezier c (get_curve ());
+      
+
+      Real height_f = c.extent (X_AXIS).length ();
+      Real width_f = c.extent (Y_AXIS).length ();
       
       dy_f = dy_f_drul_[RIGHT] - dy_f_drul_[LEFT];
       if (!fix_broken_b)
@@ -518,3 +524,123 @@ Slur::get_rods () const
 }
 
 
+
+
+
+Molecule*
+Slur::do_brew_molecule_p () const
+{
+  Real thick = paper_l ()->get_var ("slur_thickness");
+  Bezier one = get_curve ();
+
+  Molecule a;
+  SCM d =  get_elt_property ("dashed");
+  if (gh_number_p (d))
+    a = lookup_l ()->dashed_slur (one, thick, gh_scm2int (d));
+  else
+    a = lookup_l ()->slur (one, directional_element (this).get () * thick, thick);
+  
+  return new Molecule (a); 
+}
+
+
+
+Bezier
+Slur::get_curve () const
+{
+  Bezier_bow b (get_encompass_offset_arr (), directional_element (this).get ());
+
+  b.ratio_ = paper_l ()->get_var ("slur_ratio");
+  b.height_limit_ = paper_l ()->get_var ("slur_height_limit");
+  b.rc_factor_ = paper_l ()->get_var ("slur_rc_factor");
+
+  b.calculate ();
+  return b.get_curve ();
+}
+
+#if 0
+
+/*
+  TODO: FIXME.
+ */
+
+/*
+  Clipping
+
+  This function tries to address two issues:
+    * the tangents of the slur should always point inwards 
+      in the actual slur, i.e.  *after rotating back*.
+
+    * slurs shouldn't be too high 
+      let's try : h <= 1.2 b && h <= 3 staffheight?
+
+  We could calculate the tangent of the bezier curve from
+  both ends going inward, and clip the slur at the point
+  where the tangent (after rotation) points up (or inward
+  with a certain maximum angle).
+  
+  However, we assume that real clipping is not the best
+  answer.  We expect that moving the outer control point up 
+  if the slur becomes too high will result in a nicer slur 
+  after recalculation.
+
+  Knowing that the tangent is the line through the first
+  two control points, we'll clip (move the outer control
+  point upwards) too if the tangent points outwards.
+ */
+
+bool
+Bezier_bow::calc_clipping ()
+{
+  Real clip_height = paper_l_->get_var ("slur_clip_height");
+  Real clip_ratio = paper_l_->get_var ("slur_clip_ratio");
+  Real clip_angle = paper_l_->get_var ("slur_clip_angle");
+
+  Real b = curve_.control_[3][X_AXIS] - curve_.control_[0][X_AXIS];
+  Real clip_h = clip_ratio * b <? clip_height;
+  Real begin_h = curve_.control_[1][Y_AXIS] - curve_.control_[0][Y_AXIS];
+  Real end_h = curve_.control_[2][Y_AXIS] - curve_.control_[3][Y_AXIS];
+  Real begin_dy = 0 >? begin_h - clip_h;
+  Real end_dy = 0 >? end_h - clip_h;
+  
+  Real pi = M_PI;
+  Real begin_alpha = (curve_.control_[1] - curve_.control_[0]).arg () + dir_ * alpha_;
+  Real end_alpha = pi -  (curve_.control_[2] - curve_.control_[3]).arg () - dir_  * alpha_;
+
+  Real max_alpha = clip_angle / 90 * pi / 2;
+  if ((begin_dy < 0) && (end_dy < 0)
+    && (begin_alpha < max_alpha) && (end_alpha < max_alpha))
+    return false;
+
+  transform_back ();
+
+  if ((begin_dy > 0) || (end_dy > 0))
+    {
+      Real dy = (begin_dy + end_dy) / 4;
+      dy *= cos (alpha_);
+      encompass_[0][Y_AXIS] += dir_ * dy;
+      encompass_.top ()[Y_AXIS] += dir_ * dy;
+    }
+  else
+    {
+      //ugh
+      Real c = 0.4;
+      if (begin_alpha >= max_alpha)
+       begin_dy = 0 >? c * begin_alpha / max_alpha * begin_h;
+      if (end_alpha >= max_alpha)
+       end_dy = 0 >? c * end_alpha / max_alpha * end_h;
+
+      encompass_[0][Y_AXIS] += dir_ * begin_dy;
+      encompass_.top ()[Y_AXIS] += dir_ * end_dy;
+
+      Offset delta = encompass_.top () - encompass_[0];
+      alpha_ = delta.arg ();
+    }
+
+  to_canonic_form ();
+
+  return true;
+}
+#endif
+
+