]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/spacing-spanner.cc
''
[lilypond.git] / lily / spacing-spanner.cc
index d99dc2ff5041e380cc2b181e5f0c50817034af60..803265d12a6c9daa17dc9ef955fbf28e287b31d4 100644 (file)
 #include "spring.hh"
 #include "paper-column.hh"
 #include "spaceable-grob.hh"
+#include "break-align-interface.hh"
+
+
+
 
 /*
   paper-column:
-
-  Don't be confused by right-items: each spacing wish can also contain
-  a number of items, with which a spacing constraint may be kept. It's
-  a little baroque, but it might come in handy later on?
-    
  */
 class Spacing_spanner
 {
@@ -42,7 +41,7 @@ public:
   static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment);
   static Real note_spacing (Grob*,Grob*,Grob*,Moment, bool*);
   static Real get_duration_space (Grob*,Moment dur, Rational shortest, bool*);
-  static Rational find_shortest (Link_array<Grob> const &);  
+  static Rational find_shortest (Grob *, Link_array<Grob> const &);  
   static void breakable_column_spacing (Grob*, Item* l, Item *r, Moment);
   static void find_loose_columns () {}
   static void prune_loose_colunms (Grob*,Link_array<Grob> *cols, Rational);
@@ -104,6 +103,28 @@ loose_column (Grob *l, Grob *c, Grob *r)
   if (!l_neighbor || !r_neighbor)
     return false;
 
+
+  /*
+    A rather hairy check, but we really only want to move around clefs. (anything else?)
+
+    in any case, we don't want to move bar lines.
+   */
+  for (SCM e = c->get_grob_property ("elements"); gh_pair_p (e); e = gh_cdr (e))
+    {
+      Grob * g = unsmob_grob (gh_car (e));
+      if (g && Break_align_interface::has_interface (g))
+       {
+         for (SCM s = g->get_grob_property ("elements"); gh_pair_p (s);
+              s = gh_cdr (s))
+           {
+             Grob *h = unsmob_grob (gh_car (s));
+
+             if (h  && h->get_grob_property ("break-align-symbol") == ly_symbol2scm ("bar-line"))
+               return false;
+           }
+       }
+    }
+  
   /*
     Only declare loose if the bounds make a little sense.  This means
     some cases (two isolated, consecutive clef changes) won't be
@@ -343,7 +364,7 @@ Spacing_spanner::set_springs (SCM smob)
 
   set_explicit_neighbor_columns (all);
 
-  Rational global_shortest = find_shortest (all);
+  Rational global_shortest = find_shortest (me, all);
   prune_loose_colunms (me, &all, global_shortest);
   set_implicit_neighbor_columns (all);
 
@@ -375,7 +396,7 @@ Spacing_spanner::set_springs (SCM smob)
 
 */
 Rational
-Spacing_spanner::find_shortest (Link_array<Grob> const &cols)
+Spacing_spanner::find_shortest (Grob *me, Link_array<Grob> const &cols)
 {
   /*
     ascending in duration
@@ -445,10 +466,11 @@ Spacing_spanner::find_shortest (Link_array<Grob> const &cols)
       //      printf ("duration %d/%d, count %d\n", durations[i].num (), durations[i].den (), counts[i]);
     }
 
-  /*
-    TODO: 1/8 should be adjustable?
-   */
+  SCM  bsd = me->get_grob_property ("base-shortest-duration");
   Rational d = Rational (1,8);
+  if (Moment *m = unsmob_moment (bsd))
+    d = m->main_part_;
+  
   if (max_idx >= 0)
     d = d <? durations[max_idx] ;
 
@@ -508,7 +530,8 @@ Spacing_spanner::do_measure (Rational shortest, Grob*me, Link_array<Grob> *cols)
 
 
 /*
-  Generate the space between two musical columns LC and RC, given spacing parameters INCR and SHORTEST.
+  Generate the space between two musical columns LC and RC, given
+  spacing parameters INCR and SHORTEST.
  */
 void
 Spacing_spanner::musical_column_spacing (Grob *me, Item * lc, Item *rc, Real increment, Rational shortest)
@@ -552,15 +575,32 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item * lc, Item *rc, Real inc
   if (max_note_space < 0)
     {
       max_note_space = base_note_space;
-      max_fixed_note_space = increment;
+      max_fixed_note_space =  increment;
     }
 
   bool ragged = to_boolean (me->paper_l ()->get_scmvar ("raggedright"));
+
+  /*
+    Whatever we do, the fixed space is smaller than the real
+    space.
+
+    TODO: this criterion is discontinuous in the derivative.
+    Maybe it should be continuous?
+  */
+  max_fixed_note_space = max_fixed_note_space <?  max_note_space;
+  
   Real strength = (ragged) ? 1.0 : 1 / (max_note_space - max_fixed_note_space);
   Real distance = (ragged) ? max_fixed_note_space : max_note_space;
-  Spaceable_grob::add_spring (lc, rc, distance, strength, expand_only);
+  //  Spaceable_grob::add_spring (lc, rc, distance, strength, expand_only);
+  
+  Spaceable_grob::add_spring (lc, rc, distance, strength, false);  
 }
 
+
+/*
+  The one-size-fits all spacing. It doesn't take into account
+  different spacing wishes from one to the next column.
+ */
 void
 Spacing_spanner::standard_breakable_column_spacing (Grob * me, Item*l, Item*r,
                                   Real * fixed, Real * space,
@@ -632,10 +672,21 @@ Spacing_spanner::breakable_column_spacing (Grob*me, Item* l, Item *r,Moment shor
 
   
   
-
+    
   if (isinf (max_space))
     {
-      programming_error ("No pref spacing found");
+    /*
+      One situation where this can happen is when there is a column
+      that only serves as a spanning point for a short staff-symbol.
+
+     ===============X===
+
+         |=======Y
+
+
+      (here no StaffSpacing from Y to X is found.)
+    */      
+      programming_error ("No StaffSpacing wishes found");
       max_space = 2.0;
       max_fixed = 1.0;
     }
@@ -777,5 +828,5 @@ gets 2 note heads width (i.e. the space following a note is 1 note
 head width) A 16th note is followed by 0.5 note head width. The
 quarter note is followed by  3 NHW, the half by 4 NHW, etc.
 ",
-  "grace-space-factor spacing-increment shortest-duration-space");
+  "grace-space-factor spacing-increment base-shortest-duration shortest-duration-space");