]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/note-spacing.cc
note-spacing: stretch somewhat uniformly
[lilypond.git] / lily / note-spacing.cc
index 8153af96358c37f99438cfb31fa31eb2d5a21fd2..e59aa6ec841f4660148a4e104759aeebae25afea 100644 (file)
@@ -1,7 +1,7 @@
 /*
   This file is part of LilyPond, the GNU music typesetter.
 
-  Copyright (C) 2001--2011  Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Copyright (C) 2001--2012  Han-Wen Nienhuys <hanwen@xs4all.nl>
 
   LilyPond is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
 #include "separation-item.hh"
 #include "spacing-interface.hh"
 #include "staff-spacing.hh"
+#include "staff-symbol-referencer.hh"
 #include "stem.hh"
 #include "warn.hh"
 
   TODO: detect hshifts due to collisions, and account for them in
   spacing?
 */
-
+/*
+  Adjust the ideal and minimum distance between note columns,
+  based on the notehead size, skylines, and optical illusions.
+*/
 Spring
 Note_spacing::get_spacing (Grob *me, Item *right_col,
-                           Real base_space, Real increment)
+                           Spring base, Real increment)
 {
   vector<Item *> note_columns = Spacing_interface::left_note_columns (me);
   Real left_head_end = 0;
@@ -77,11 +81,12 @@ Note_spacing::get_spacing (Grob *me, Item *right_col,
     the full amount of space. We give them half the amount of space, but then
     adjust things so there are no collisions.
   */
+  Real ideal = base.distance () - increment + left_head_end;
   Drul_array<Skyline> skys = Spacing_interface::skylines (me, right_col);
-  Real distance = skys[LEFT].distance (skys[RIGHT]);
+  Real distance = skys[LEFT].distance (skys[RIGHT], robust_scm2double (right_col->get_property ("skyline-vertical-padding"), 0.0));
   Real min_dist = max (0.0, distance);
-  Real min_desired_space = left_head_end + (min_dist - left_head_end + base_space - increment) / 2;
-  Real ideal = base_space - increment + left_head_end;
+  Real min_desired_space = (ideal + min_dist) / 2;
+  base.set_min_distance (min_dist);
 
   /* If we have a NonMusical column on the right, we measure the ideal distance
      to the bar-line (if present), not the start of the column. */
@@ -106,12 +111,9 @@ Note_spacing::get_spacing (Grob *me, Item *right_col,
   ideal = max (ideal, min_desired_space);
   stem_dir_correction (me, right_col, increment, &ideal, &min_desired_space);
 
-  /* TODO: grace notes look bad when things are stretched. Should we increase
-     their stretch strength? */
-  Spring ret (max (0.0, ideal), min_dist);
-  ret.set_inverse_compress_strength (max (0.0, ideal - min_desired_space));
-  ret.set_inverse_stretch_strength (max (0.1, base_space - increment));
-  return ret;
+  base.set_distance (max (0.0, ideal));
+  base.set_inverse_compress_strength (max (0.0, ideal - min_desired_space));
+  return base;
 }
 
 static Real
@@ -221,8 +223,6 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
   Interval bar_xextent;
   Interval bar_yextent;
 
-  Direction d = LEFT;
-
   bool acc_right = false;
 
   Grob *bar = Spacing_interface::extremal_break_aligned_grob (me, RIGHT,
@@ -231,7 +231,7 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
   if (bar && dynamic_cast<Item *> (bar)->get_column () == rcolumn)
     bar_yextent = Staff_spacing::bar_y_positions (bar);
 
-  do
+  for (LEFT_and_RIGHT (d))
     {
       vector<Grob *> const &items (ly_scm2link_array (props [d]));
       for (vsize i = 0; i < items.size (); i++)
@@ -273,22 +273,12 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
           Interval hp = Stem::head_positions (stem);
           if (!hp.is_empty ())
             {
-              Real chord_start = hp[stem_dir];
-
-              /*
-                can't look at stem-end-position, since that triggers
-                beam slope computations.
-              */
-              Real stem_end = hp[stem_dir]
-                              + stem_dir * robust_scm2double (stem->get_property ("length"), 7);
-
-              stem_posns[d] = Interval (min (chord_start, stem_end),
-                                        max (chord_start, stem_end));
+              Real ss = Staff_symbol_referencer::staff_space (stem);
+              stem_posns[d] = stem->pure_height (stem, 0, INT_MAX) * (2 / ss);
               head_posns[d].unite (hp);
             }
         }
     }
-  while (flip (&d) != LEFT);
 
   Real correction = 0.0;
 
@@ -304,7 +294,6 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
       if (beams_drul[LEFT] && beams_drul[LEFT] == beams_drul[RIGHT])
         {
           correction = knee_correction (me, stems_drul[RIGHT], increment);
-          *fixed += correction;
         }
       else
         {
@@ -322,6 +311,7 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
            && !acc_right)
     correction = same_direction_correction (me, head_posns);
 
+  *fixed += correction;
   *space += correction;
 
   /* there used to be a correction for bar_xextent () here, but