]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/tie-formatting-problem.cc
* Documentation/pictures/GNUmakefile (local-dist): loose the rule
[lilypond.git] / lily / tie-formatting-problem.cc
index 8309db2660ddd43ac2e1a7bcaa0b6854040cd3a5..8d40e75f71784c9f4aad5ed497fd7abbd824c656 100644 (file)
@@ -59,12 +59,13 @@ Tie_formatting_problem::~Tie_formatting_problem ()
 }
 
 void
-Tie_formatting_problem::set_chord_outline (Link_array__Item_ bounds,
+Tie_formatting_problem::set_chord_outline (vector<Item*> bounds,
                                           Direction d)
 {
   Real staff_space = Staff_symbol_referencer::staff_space (bounds[0]);
 
-  std::vector<Box> boxes;
+  vector<Box> boxes;
+  vector<Box> head_boxes;
 
   Grob *stem = 0;
   for (vsize i = 0; i < bounds.size (); i++)
@@ -81,26 +82,26 @@ Tie_formatting_problem::set_chord_outline (Link_array__Item_ bounds,
                  (p+1) * 0.5 * staff_space);
 
       Interval x = head->extent (x_refpoint_, X_AXIS);
+      head_boxes.push_back (Box (x, y));
       boxes.push_back (Box (x, y));
 
       Grob *dots = Rhythmic_head::get_dots (head);
       if (d == LEFT && dots)
        {
          Interval x = dots->extent (x_refpoint_, X_AXIS);
-         Interval y (-0.5, 0.5);
          int p = int (Staff_symbol_referencer::get_position (dots));
-         y.translate (p);
 
          dot_positions_.insert (p);
          dot_x_.unite (x);
+
+         Interval y (dots->extent (dots, Y_AXIS));
+         y.translate (p * staff_space * 0.5);
          
-         y *= staff_space * 0.5;
-         // boxes.push_back (Box (x, y));
+         boxes.push_back (Box (x, y));
        }
     }
 
   chord_outlines_[d] = empty_skyline (-d);
-
   if (bounds[0]->break_status_dir ())
     {
       Real x = robust_relative_extent (bounds[0],  x_refpoint_, X_AXIS)[-d];
@@ -142,9 +143,9 @@ Tie_formatting_problem::set_chord_outline (Link_array__Item_ bounds,
     {
       Interval x;
       Interval y;
-      if (boxes.size())
+      if (head_boxes.size())
        {
-         Box b = boundary (boxes, updowndir, 0);
+         Box b = boundary (head_boxes, updowndir, 0);
          x = b[X_AXIS];
          x[-d] =  b[X_AXIS].linear_combination (-d / 2);
          y[-updowndir] = b[Y_AXIS][updowndir];
@@ -163,7 +164,7 @@ Tie_formatting_problem::set_chord_outline (Link_array__Item_ bounds,
 void
 Tie_formatting_problem::from_tie (Grob *tie)
 {
-  Link_array__Grob_ ties;
+  vector<Grob*> ties;
   ties.push_back (tie);
   from_ties (ties);
 
@@ -177,7 +178,7 @@ Tie_formatting_problem::common_x_refpoint () const
 }
 
 void
-Tie_formatting_problem::from_ties (Link_array__Grob_ const &ties)
+Tie_formatting_problem::from_ties (vector<Grob*> const &ties)
 {
   if (ties.empty ())
     return;
@@ -194,7 +195,7 @@ Tie_formatting_problem::from_ties (Link_array__Grob_ const &ties)
   Direction d = LEFT;
   do
     {
-      Link_array__Item_ bounds;
+      vector<Item*> bounds;
       
       for (vsize i = 0; i < ties.size (); i++)
        {
@@ -231,13 +232,13 @@ Tie_formatting_problem::from_ties (Link_array__Grob_ const &ties)
 }
 
 void
-Tie_formatting_problem::from_lv_ties (Link_array__Grob_ const &lv_ties)
+Tie_formatting_problem::from_lv_ties (vector<Grob*> const &lv_ties)
 {
   if (lv_ties.empty ())
     return;
   
   details_.from_grob (lv_ties[0]);
-  Link_array__Item_ heads;
+  vector<Item*> heads;
   
   for (vsize i = 0; i < lv_ties.size (); i++)
     {
@@ -259,9 +260,9 @@ Tie_formatting_problem::from_lv_ties (Link_array__Grob_ const &lv_ties)
 
   x_refpoint_ = lv_ties [0];
   for (vsize i = 0; i < lv_ties.size (); i++)
-    {
-      x_refpoint_ = lv_ties[i]->common_refpoint (x_refpoint_, X_AXIS); 
-    }
+    x_refpoint_ = lv_ties[i]->common_refpoint (x_refpoint_, X_AXIS); 
+  for (vsize i = 0; i < heads.size (); i++)
+    x_refpoint_ = heads[i]->common_refpoint (x_refpoint_, X_AXIS); 
 
   set_chord_outline (heads, LEFT);
 
@@ -299,7 +300,7 @@ Tie_formatting_problem::get_configuration (int pos, Direction dir)
     }
 
   
-  Tie_configuration *conf = generate_configuration (pos,dir);
+  Tie_configuration *conf = generate_configuration (pos, dir);
   possibilities_[key] = conf;
   return conf;
 }
@@ -320,6 +321,21 @@ Tie_formatting_problem::generate_configuration (int pos, Direction dir) const
   conf->attachment_x_ = get_attachment (y + conf->delta_y_);
 
   Real h =  conf->height (details_);
+
+  if (h <  details_.intra_space_threshold_ * 0.5 * details_.staff_space_)
+    {
+      /*
+       This is less sensible for long ties, since those are more
+       horizontal.
+      */
+      Interval close_by = get_attachment (y
+                                         + conf->delta_y_
+                                         + (dir * details_.intra_space_threshold_ * 0.25
+                                            * details_.staff_space_));
+      
+      conf->attachment_x_.intersect (close_by);
+    }
+  
   if (!conf->delta_y_)
     {
       /*
@@ -418,8 +434,8 @@ Tie_formatting_problem::score_configuration (Tie_configuration const &conf) cons
 {
   Real penalty = 0.0;
   Real length = conf.attachment_x_.length ();
-  if (length < details_.min_length_)
-    penalty += details_.length_penalty_factor_ / max (0.01, length);
+
+  penalty += peak_around (0.5 * details_.min_length_, details_.min_length_, length);
 
   Real tip_pos = conf.position_ + conf.delta_y_ / 0.5 * details_.staff_space_;
   Real tip_y = tip_pos * details_.staff_space_ * 0.5;
@@ -477,7 +493,7 @@ Tie_formatting_problem::score_configuration (Tie_configuration const &conf) cons
 Tie_configuration
 Tie_formatting_problem::find_optimal_tie_configuration (Tie_specification const &spec) const
 {
-  Link_array__Tie_configuration_ confs;
+  vector<Tie_configuration*> confs;
 
   int pos = spec.position_;
   Direction dir = spec.manual_dir_;
@@ -488,7 +504,7 @@ Tie_formatting_problem::find_optimal_tie_configuration (Tie_specification const
       confs.push_back (generate_configuration (pos + i * dir, dir));
     }
 
-  std::vector<Real> scores;
+  vector<Real> scores;
 
   int best_idx = -1;
   Real best_score = 1e6;
@@ -663,7 +679,7 @@ Ties_configuration
 Tie_formatting_problem::generate_optimal_chord_configuration ()
 {
   Ties_configuration base = generate_base_chord_configuration ();
-  std::vector<Tie_configuration_variation> vars = get_variations (base);
+  vector<Tie_configuration_variation> vars = get_variations (base);
 
   Ties_configuration best = base;
   Real best_score = score_ties (best);
@@ -737,12 +753,12 @@ Tie_configuration_variation::Tie_configuration_variation ()
   suggestion_ = 0;
 }
 
-std::vector<Tie_configuration_variation>
+vector<Tie_configuration_variation>
 Tie_formatting_problem::get_variations (Ties_configuration const &ties) 
 {
   Real center_distance_tolerance = 0.25;
   
-  std::vector<Tie_configuration_variation> vars;
+  vector<Tie_configuration_variation> vars;
   Real last_center = 0.0;
   for (vsize i = 0; i < ties.size (); i++)
     {
@@ -776,12 +792,22 @@ Tie_formatting_problem::get_variations (Ties_configuration const &ties)
                  vars.push_back (var);
                }
            }
+         else if (dot_positions_.find (ties[i].position_) != dot_positions_.end ()
+                  && !specifications_[i].has_manual_position_)
+           {
+             Tie_configuration_variation var;
+             var.index_ = i;
+             var.suggestion_ = get_configuration (ties[i].position_  + ties[i].dir_,
+                                                  ties[i].dir_);
+             vars.push_back (var);
+           }
+         
        }
 
       last_center = center;
     }
 
-  /*  TODO: switch off? */
+  /* TODO: switch off? */
   Direction d = DOWN;
   do
     {
@@ -811,16 +837,16 @@ Tie_formatting_problem::set_manual_tie_configuration (SCM manual_configs)
        {
          Tie_specification &spec = specifications_[k];
 
-         if (scm_is_number (scm_cdr (entry)))
-           {
-             spec.has_manual_dir_ = true;
-             spec.manual_dir_ = Direction (scm_to_int (scm_cdr (entry)));
-           }
          if (scm_is_number (scm_car (entry)))
            {
              spec.has_manual_position_ = true;
              spec.manual_position_ = scm_to_double (scm_car (entry));
            }
+         if (scm_is_number (scm_cdr (entry)))
+           {
+             spec.has_manual_dir_ = true;
+             spec.manual_dir_ = Direction (scm_to_int (scm_cdr (entry)));
+           }
        }         
       k ++;
     }