]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/staff-spacing.cc
Run grand-replace (issue 3765)
[lilypond.git] / lily / staff-spacing.cc
index 4e92bfce649282b51dc61a12bfa015b2ace7096a..c0219f70652e1cbba2693c3b5e376d3d2a250dc2 100644 (file)
@@ -1,9 +1,20 @@
 /*
-  staff-spacing.cc -- implement Staff_spacing
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 2001--2014  Han-Wen Nienhuys <hanwen@xs4all.nl>
 
-  (c) 2001--2008  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
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "staff-spacing.hh"
@@ -15,7 +26,6 @@ using namespace std;
 #include "paper-column.hh"
 #include "separation-item.hh"
 #include "warn.hh"
-#include "bar-line.hh"
 #include "staff-symbol-referencer.hh"
 #include "note-column.hh"
 #include "stem.hh"
@@ -44,24 +54,14 @@ Staff_spacing::optical_correction (Grob *me, Grob *g, Interval bar_height)
     {
       Direction d = get_grob_direction (stem);
       if (Stem::is_normal_stem (stem) && d == DOWN)
-       {
-
-         /*
-           can't look at stem-end-position, since that triggers
-           beam slope computations.
-         */
-         Real stem_start = Stem::head_positions (stem) [d];
-         Real stem_end = stem_start + 
-           d * robust_scm2double (stem->get_property ("length"), 7);
-         
-         Interval stem_posns (min (stem_start, stem_end),
-                              max (stem_end, stem_start));
-
-         stem_posns.intersect (bar_height);
-
-         ret = min (abs (stem_posns.length () / 7.0), 1.0);
-         ret *= robust_scm2double (me->get_property ("stem-spacing-correction"), 1);
-       }
+        {
+          Interval stem_posns = stem->pure_height (stem, 0, INT_MAX);
+
+          stem_posns.intersect (bar_height);
+
+          ret = min (abs (stem_posns.length () / 7.0), 1.0);
+          ret *= robust_scm2double (me->get_property ("stem-spacing-correction"), 1);
+        }
     }
   return ret;
 }
@@ -74,30 +74,31 @@ Staff_spacing::bar_y_positions (Grob *bar_grob)
 {
   Interval bar_size;
   bar_size.set_empty ();
-  if (Bar_line::has_interface (bar_grob))
+
+  if (bar_grob->internal_has_interface (ly_symbol2scm ("bar-line-interface")))
     {
       SCM glyph = bar_grob->get_property ("glyph-name");
       Grob *staff_sym = Staff_symbol_referencer::get_staff_symbol (bar_grob);
 
       string glyph_string = scm_is_string (glyph) ? ly_scm2string (glyph) : "";
       if (glyph_string.substr (0, 1) == "|"
-         || glyph_string.substr (0, 1) == ".")
-       {
-         Grob *common = bar_grob->common_refpoint (staff_sym, Y_AXIS);
-         bar_size = bar_grob->extent (common, Y_AXIS);
-         bar_size *= 1.0 / Staff_symbol_referencer::staff_space (bar_grob);
-       }
+          || glyph_string.substr (0, 1) == ".")
+        {
+          Grob *common = bar_grob->common_refpoint (staff_sym, Y_AXIS);
+          bar_size = bar_grob->extent (common, Y_AXIS);
+          bar_size *= 1.0 / Staff_symbol_referencer::staff_space (bar_grob);
+        }
     }
   return bar_size;
 }
 
 Real
 Staff_spacing::next_notes_correction (Grob *me,
-                                     Grob *last_grob)
+                                      Grob *last_grob)
 {
   Interval bar_size = bar_y_positions (last_grob);
   Grob *orig = me->original () ? me->original () : me;
-  vector<Item*> note_columns = Spacing_interface::right_note_columns (orig);
+  vector<Item *> note_columns = Spacing_interface::right_note_columns (orig);
 
   Real max_optical = 0.0;
 
@@ -113,7 +114,7 @@ Staff_spacing::next_notes_correction (Grob *me,
    We arrange things so that the fixed distance will be attained when the
    line is compressed with a force of 1.0 */
 Spring
-Staff_spacing::get_spacing (Grob *me, Grob *right_col)
+Staff_spacing::get_spacing (Grob *me, Grob *right_col, Real situational_space)
 {
   Item *me_item = dynamic_cast<Item *> (me);
   Grob *left_col = me_item->get_column ();
@@ -121,26 +122,26 @@ Staff_spacing::get_spacing (Grob *me, Grob *right_col)
   Interval last_ext;
   Direction break_dir = me_item->break_status_dir ();
   Grob *last_grob = Spacing_interface::extremal_break_aligned_grob (me, LEFT,
-                                                                   break_dir,
-                                                                   &last_ext);
+                    break_dir,
+                    &last_ext);
   if (!last_grob)
     {
       /*
-       TODO:
+        TODO:
 
-       Should  insert a adjustable space here? For excercises, you might want to
-       use a staff without a clef in the beginning.
+        Should insert an adjustable space here? For exercises, you might want to
+        use a staff without a clef in the beginning.
       */
 
       /*
-       we used to have a warning here, but it generates a lot of
-       spurious error messages.
+        we used to have a warning here, but it generates a lot of
+        spurious error messages.
       */
       return Spring ();
     }
 
   SCM alist = last_grob->get_property ("space-alist");
-  if (!scm_list_p (alist))
+  if (!ly_is_list (alist))
     return Spring ();
 
   SCM space_def = scm_sloppy_assq (ly_symbol2scm ("first-note"), alist);
@@ -148,7 +149,7 @@ Staff_spacing::get_spacing (Grob *me, Grob *right_col)
     {
       SCM nndef = scm_sloppy_assq (ly_symbol2scm ("next-note"), alist);
       if (scm_is_pair (nndef))
-       space_def = nndef;
+        space_def = nndef;
     }
 
   if (!scm_is_pair (space_def))
@@ -184,27 +185,34 @@ Staff_spacing::get_spacing (Grob *me, Grob *right_col)
       ideal = fixed;
     }
 
+  Real stretchability = ideal - fixed;
+
+  /* 'situational_space' passed by the caller
+      could include full-measure-extra-space */
+  ideal += situational_space;
 
   Real optical_correction = next_notes_correction (me, last_grob);
+  fixed += optical_correction;
+  ideal += optical_correction;
+
   Real min_dist = Paper_column::minimum_distance (left_col, right_col);
 
   /* ensure that the "fixed" distance will leave a gap of at least 0.3 ss. */
   Real min_dist_correction = max (0.0, 0.3 + min_dist - fixed);
-  Real correction = max (optical_correction, min_dist_correction);
-
-  fixed += correction;
-  ideal += correction;
+  fixed += min_dist_correction;
+  ideal = max (ideal, fixed);
 
   Spring ret (ideal, min_dist);
-  ret.set_inverse_stretch_strength (max (0.0, ideal - fixed));
+  ret.set_inverse_stretch_strength (max (0.0, stretchability));
+  ret.set_inverse_compress_strength (max (0.0, ideal - fixed));
   return ret;
 }
 
 ADD_INTERFACE (Staff_spacing,
-              "This object calculates spacing details from a breakable"
-              " symbol (left) to another object.  For example, it takes care"
-              " of optical spacing from a bar line to a note.",
+               "This object calculates spacing details from a breakable"
+               " symbol (left) to another object.  For example, it takes care"
+               " of optical spacing from a bar line to a note.",
 
-              /* properties */
-              "stem-spacing-correction "
-              );
+               /* properties */
+               "stem-spacing-correction "
+              );