]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/note-spacing.cc
Update source file headers. Fixes using standard GNU package conventions.
[lilypond.git] / lily / note-spacing.cc
index 4992fbc3e8712aae6b22b0f89cceabbe993f56d9..20c72829143f47da60c1f614eb187d5ef189df3a 100644 (file)
@@ -1,13 +1,25 @@
 /*
-  note-spacing.cc -- implement Note_spacing
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 2001--2009  Han-Wen Nienhuys <hanwen@xs4all.nl>
 
-  (c) 2001--2007  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 "note-spacing.hh"
 
+#include "bar-line.hh"
 #include "directional-element-interface.hh"
 #include "grob-array.hh"
 #include "paper-column.hh"
 #include "output-def.hh"
 #include "pointer-group-interface.hh"
 
+static bool
+non_empty_barline (Grob *me)
+{
+  return Bar_line::has_interface (me) && !me->extent (me, X_AXIS).is_empty ();
+}
+
 /*
   TODO: detect hshifts due to collisions, and account for them in
   spacing?
@@ -66,21 +84,38 @@ Note_spacing::get_spacing (Grob *me, Item *right_col,
     adjust things so there are no collisions.
   */
   Drul_array<Skyline> skys = Spacing_interface::skylines (me, right_col);
-  Real min_dist = max (0.0, skys[LEFT].distance (skys[RIGHT]));
-  Real min_desired_space = left_head_end + (min_dist - left_head_end) / 2;
-
-  /* if the right object sticks out a lot, include a bit of extra space.
-     But only for non-musical-columns; this shouldn't apply to accidentals */
-  if (!Paper_column::is_musical (right_col))
-    min_desired_space = max (min_desired_space,
-                            left_head_end + LEFT * skys[RIGHT].max_height ());
+  Real distance = skys[LEFT].distance (skys[RIGHT]);
+  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;
+
+  /* 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. */
+  if (!Paper_column::is_musical (right_col)
+      && !skys[RIGHT].is_empty ()
+      && to_boolean (me->get_property ("space-to-barline")))
+    {
+      Grob *bar = Pointer_group_interface::find_grob (right_col,
+                                                     ly_symbol2scm ("elements"),
+                                                     non_empty_barline);
 
-  Real ideal = base_space - increment + min_desired_space;
+      if (bar)
+       {
+         Real shift = bar->extent (right_col, X_AXIS)[LEFT];
+         ideal -= shift;
+         min_desired_space -= max (shift, 0.0);
+       }
+      else
+       ideal -= right_col->extent (right_col, X_AXIS)[RIGHT];
+    }
 
+  ideal = max (ideal, min_desired_space);
   stem_dir_correction (me, right_col, increment, &ideal, &min_desired_space);
 
-  Spring ret (ideal, min_dist);
-  ret.set_inverse_compress_strength (max (0.0, ideal - max (min_dist, 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;
 }
@@ -167,7 +202,7 @@ same_direction_correction (Grob *note_spacing, Drul_array<Interval> head_posns)
 }
 
 
-/**
+/*
    Correct for optical illusions. See [Wanske] p. 138. The combination
    up-stem + down-stem should get extra space, the combination
    down-stem + up-stem less.
@@ -195,10 +230,12 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
 
   Direction d = LEFT;
 
+  bool acc_right = false;
+
   Grob *bar = Spacing_interface::extremal_break_aligned_grob (me, RIGHT,
                                                              rcolumn->break_status_dir (),
                                                              &bar_xextent);
-  if (bar)
+  if (bar && dynamic_cast<Item*> (bar)->get_column () == rcolumn)
     bar_yextent = Staff_spacing::bar_y_positions (bar);
 
   do
@@ -207,12 +244,16 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
       for (vsize i = 0; i < items.size (); i++)
        {
          Item *it = dynamic_cast<Item *> (items[i]);
+         if (!Note_column::has_interface (it))
+           continue;
+         if (d == RIGHT && it->get_column () != rcolumn)
+           continue;
 
          /*
-           don't correct if accidentals are sticking out of the right side.
+           Find accidentals which are sticking out of the right side.
          */
-         if (d == RIGHT && Note_column::accidentals (it))
-           return;
+        if (d == RIGHT)
+            acc_right = acc_right || Note_column::accidentals (it);
 
          Grob *stem = Note_column::get_stem (it);
 
@@ -280,7 +321,12 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
            correction *= 0.5;
        }
     }
-  else if (stem_dirs[LEFT] * stem_dirs[RIGHT] == 1)
+  /*
+    Only apply same direction correction if there are no
+    accidentals sticking out of the right hand side.
+  */
+  else if (stem_dirs[LEFT] * stem_dirs[RIGHT] == 1
+          && !acc_right)
     correction = same_direction_correction (me, head_posns);
 
   *space += correction;
@@ -293,12 +339,12 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn,
 ADD_INTERFACE (Note_spacing,
               "This object calculates spacing wishes for individual voices.",
 
-              
+              /* properties */
               "knee-spacing-correction "
               "left-items "
               "right-items "
               "same-direction-correction "
               "stem-spacing-correction "
-
+              "space-to-barline "
               );