]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/slur-configuration.cc
Properly implement fromproperty markup handing in the pdftitle header field
[lilypond.git] / lily / slur-configuration.cc
index d6d231de305e2b90c6aabdb80ea581c6dfb35064..b144b2656ff927aeb5a51f506e631b98cf441499 100644 (file)
@@ -28,6 +28,7 @@
 #include "spanner.hh"
 #include "staff-symbol-referencer.hh"
 #include "stem.hh"
+#include "tie.hh"
 #include "warn.hh"
 
 Bezier
@@ -49,19 +50,15 @@ avoid_staff_line (Slur_score_state const &state,
       Real p = 2 * (y - staff->relative_coordinate (state.common_[Y_AXIS], Y_AXIS))
                / state.staff_space_;
 
-      Real distance = fabs (my_round (p) - p);  //  in halfspaces
-      if (distance < 4 * state.thickness_
-          && (int) fabs (my_round (p))
-          <= 2 * Staff_symbol_referencer::staff_radius (staff) + 0.1
-          && (int (fabs (my_round (p))) % 2
-              != Staff_symbol_referencer::line_count (staff) % 2))
+      Real const round = my_round (p);
+      Real const frac = p - round;
+      if (fabs (frac) < 4 * state.thickness_
+          && Staff_symbol_referencer::on_staff_line (staff, int (round)))
         {
-          Direction resolution_dir
-            = (distance ? state.dir_ : Direction (sign (p - my_round (p))));
+          Direction resolution_dir = frac ? state.dir_ : CENTER;
 
           // TODO: parameter
-          Real newp = my_round (p) + resolution_dir
-                      * 5 * state.thickness_;
+          Real newp = round + resolution_dir * 5 * state.thickness_;
 
           Real dy = (newp - p) * state.staff_space_ / 2.0;
 
@@ -194,7 +191,7 @@ Slur_configuration::add_score (Real s, string desc)
 {
   if (s < 0)
     {
-      programming_error ("Negative demerits found for slur. Ignoring");
+      programming_error ("Negative demerits found for slur.  Ignoring");
       s = 0.0;
     }
 
@@ -278,11 +275,12 @@ Slur_configuration::score_encompass (Slur_score_state const &state)
     }
   add_score (demerit, "encompass");
 
-  if (convex_head_distances.size ())
+  if (vsize n = convex_head_distances.size ())
     {
       Real avg_distance = 0.0;
       Real min_dist = infinity_f;
-      for (vsize j = 0; j < convex_head_distances.size (); j++)
+
+      for (vsize j = 0; j < n; j++)
         {
           min_dist = min (min_dist, convex_head_distances[j]);
           avg_distance += convex_head_distances[j];
@@ -292,12 +290,11 @@ Slur_configuration::score_encompass (Slur_score_state const &state)
         For slurs over 3 or 4 heads, the average distance is not a
         good normalizer.
       */
-      Real n = convex_head_distances.size ();
       if (n <= 2)
         {
           Real fact = 1.0;
           avg_distance += height_ * fact;
-          n += fact;
+          ++n;
         }
 
       /*
@@ -320,6 +317,39 @@ Slur_configuration::score_encompass (Slur_score_state const &state)
 void
 Slur_configuration::score_extra_encompass (Slur_score_state const &state)
 {
+  // we find forbidden attachments
+  vector<Offset> forbidden_attachments;
+  for (vsize i = 0; i < state.extra_encompass_infos_.size (); i++)
+    if (Tie::has_interface (state.extra_encompass_infos_[i].grob_))
+      {
+        Grob *t = state.extra_encompass_infos_[i].grob_;
+        Grob *common_x = Grob::get_vertical_axis_group (t);
+        Real rp = t->relative_coordinate (common_x, X_AXIS);
+        SCM cp = t->get_property ("control-points");
+
+        Bezier b;
+        int j = 0;
+        for (SCM s = cp; scm_is_pair (s); s = scm_cdr (s))
+          {
+            b.control_[j] = ly_scm2offset (scm_car (s));
+            j++;
+          }
+        forbidden_attachments.push_back (Offset (b.control_[0]) + Offset (rp, 0));
+        forbidden_attachments.push_back (Offset (b.control_[3]) + Offset (rp, 0));
+      }
+
+  bool too_close = false;
+  for (vsize k = 0; k < forbidden_attachments.size (); k++)
+    for (LEFT_and_RIGHT (side))
+      if ((forbidden_attachments[k] - attachment_[side]).length () < state.parameters_.slur_tie_extrema_min_distance_)
+        {
+          too_close = true;
+          break;
+        }
+
+  if (too_close)
+    add_score (state.parameters_.slur_tie_extrema_min_distance_penalty_, "extra");
+
   for (vsize j = 0; j < state.extra_encompass_infos_.size (); j++)
     {
       Drul_array<Offset> attachment = attachment_;