]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/spacing-spanner.cc
2003 -> 2004
[lilypond.git] / lily / spacing-spanner.cc
index 4e733fe639b4d4d2984e938e3a100de1de5db260..4d1cdd89017955c49812ddc4ff90c8bb8832773d 100644 (file)
@@ -3,7 +3,7 @@
   
   source file of the GNU LilyPond music typesetter
   
-  (c) 1999--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
   
  */
 
 #include "break-align-interface.hh"
 #include "spacing-interface.hh"
 
+
+/*
+  TODO: this file/class is too complex. Should figure out how to chop
+  this up even more.
+    
+ */
+
 class Spacing_spanner
 {
 public:
@@ -157,7 +164,7 @@ void
 Spacing_spanner::prune_loose_columns (Grob*me,Link_array<Grob> *cols, Rational shortest)
 {
   Link_array<Grob> newcols;
-  Real increment = gh_scm2double (me->get_grob_property ("spacing-increment"));
+  Real increment = robust_scm2double (me->get_grob_property ("spacing-increment"), 1.2);
   for (int i=0; i < cols->size ();  i++)
     {
       if (Item::breakable_b (cols->elem(i)) || Paper_column::musical_b (cols->elem (i)))
@@ -361,7 +368,7 @@ Spacing_spanner::set_springs (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
 
-  Link_array<Grob> all (me->pscore_->system_->columns ()) ;
+  Link_array<Grob> all (me->pscore_->system_->columns ());
 
   set_explicit_neighbor_columns (all);
 
@@ -438,7 +445,7 @@ Spacing_spanner::find_shortest (Grob *me, Link_array<Grob> const &cols)
          assert (this_shortest.to_bool());
          shortest_in_measure = shortest_in_measure <? this_shortest.main_part_;
        }
-      else if (!shortest_in_measure.infty_b()
+      else if (!shortest_in_measure.is_infinity ()
               && Item::breakable_b (cols[i]))
        {
          int j = 0;
@@ -501,7 +508,7 @@ void
 Spacing_spanner::do_measure (Rational shortest, Grob*me, Link_array<Grob> *cols) 
 {
 
-  Real headwid =       gh_scm2double (me->get_grob_property ("spacing-increment"));
+  Real headwid = robust_scm2double (me->get_grob_property ("spacing-increment"), 1);
   for (int i= 0; i < cols->size () - 1; i++)
     {
       Item * l = dynamic_cast<Item*> (cols->elem (i));
@@ -661,7 +668,6 @@ Spacing_spanner::standard_breakable_column_spacing (Grob * me, Item*l, Item*r,
                                   Real * fixed, Real * space,
                                   Moment shortest)
 {
   *fixed = 0.0;
   Direction d = LEFT;
   Drul_array<Item*> cols(l,r);
@@ -675,10 +681,12 @@ Spacing_spanner::standard_breakable_column_spacing (Grob * me, Item*l, Item*r,
            what happens if we do this for non musical columns only.
           */
          Interval lext = cols[d]->extent (cols [d], X_AXIS);
-         *fixed += -d * lext[-d];
+         if (!lext.is_empty ())
+           *fixed += -d * lext[-d];
        }
     }
   while (flip (&d) != LEFT);
+  
 
   if (l->breakable_b (l) && r->breakable_b(r))
     {
@@ -687,98 +695,99 @@ Spacing_spanner::standard_breakable_column_spacing (Grob * me, Item*l, Item*r,
       if (dt)
        mlen = *dt;
       
-      Real incr = gh_scm2double (me->get_grob_property ("spacing-increment"));
+      Real incr = robust_scm2double (me->get_grob_property ("spacing-increment"), 1);
 
       *space =  *fixed + incr * double (mlen.main_part_ / shortest.main_part_) * 0.8;
     }
   else
     {
       Moment dt = Paper_column::when_mom (r) - Paper_column::when_mom (l);
-      bool dummy;
 
-      *space = *fixed + get_duration_space (me, dt, shortest.main_part_, &dummy);
+      if (dt == Moment (0,0))
+       {
+         /*
+           In this case, Staff_spacing should handle the job,
+           using dt when it is 0 is silly.
+          */
+         *space = *fixed + 0.5; 
+       }
+      else
+       {
+         bool dummy;
+         *space = *fixed + get_duration_space (me, dt, shortest.main_part_, &dummy);
+       }
     }
 }
 
 
 /*
   Read hints from L and generate springs.
- */
+*/
 void
 Spacing_spanner::breakable_column_spacing (Grob*me, Item* l, Item *r,Moment shortest)
 {
-  Real max_fixed = -infinity_f;
-  Real max_space = -infinity_f;
-
-  standard_breakable_column_spacing (me, l, r, &max_fixed, &max_space ,
-                                    shortest);
-  
-  for (SCM s = l->get_grob_property ("spacing-wishes");
-       gh_pair_p (s); s = gh_cdr (s))
-    {
-      Item * spacing_grob = dynamic_cast<Item*> (unsmob_grob (gh_car (s)));
-
-      if (!spacing_grob || !Staff_spacing::has_interface (spacing_grob))
-       continue;
+  Real compound_fixed = 0.0;
+  Real compound_space = 0.0;
+  int wish_count = 0;
 
-      Real space;
-      Real fixed_space;
+  Moment dt = Paper_column::when_mom (r) - Paper_column::when_mom (l);
 
-      /*
-       column for the left one settings should be ok due automatic
-       pointer munging.
+  if (dt == Moment (0,0))
+    {
+      for (SCM s = l->get_grob_property ("spacing-wishes");
+          gh_pair_p (s); s = gh_cdr (s))
+       {
+         Item * spacing_grob = dynamic_cast<Item*> (unsmob_grob (gh_car (s)));
 
-      */
-      assert (spacing_grob-> get_column () == l);
+         if (!spacing_grob || !Staff_spacing::has_interface (spacing_grob))
+           continue;
 
-      Staff_spacing::get_spacing_params (spacing_grob,
-                                        &space, &fixed_space);
+         Real space;
+         Real fixed_space;
 
-      if (Paper_column::when_mom (r).grace_part_)
-       {
          /*
-           Correct for grace notes.
+           column for the left one settings should be ok due automatic
+           pointer munging.
 
-           Ugh. The 0.8 is arbitrary.
-          */
-         space *= 0.8;
-       }
-      if (space > max_space)
-       {
-         max_space = space;
-         max_fixed = fixed_space;
-       }
-    }
+         */
+         assert (spacing_grob-> get_column () == l);
 
-  
-  
-    
-  if (isinf (max_space))
-    {
-    /*
-      One situation where this can happen is when there is a column
-      that only serves as a spanning point for a short staff-symbol.
+         Staff_spacing::get_spacing_params (spacing_grob,
+                                            &space, &fixed_space);
 
-     ===============X===
+         if (Paper_column::when_mom (r).grace_part_)
+           {
+             /*
+               Correct for grace notes.
 
-         |=======Y
+               Ugh. The 0.8 is arbitrary.
+             */
+             space *= 0.8;
+           }
 
 
-      (here no StaffSpacing from Y to X is found.)
-    */      
-      warning ("No spacing wishes found. Does your score have a staff?");
-      max_space = 2.0;
-      max_fixed = 1.0;
+         compound_space += space;
+         compound_fixed += fixed_space;
+         wish_count ++ ;
+       }
     }
 
-  
-  if (l->break_status_dir() == RIGHT
-      && Paper_column::when_mom (l) == Paper_column::when_mom (r))
+  if (compound_space <= 0.0 || !wish_count)
     {
-      /* Start of line: this space is not stretchable */
-      max_fixed = max_space;
+      standard_breakable_column_spacing (me, l, r, &compound_fixed, &compound_space ,
+                                        shortest);
+      wish_count = 1;
+    }
+  else
+    {
+      compound_space /= wish_count;
+      compound_fixed /= wish_count;
     }
 
+  assert (!isinf (compound_space));
+  compound_space = compound_space >? compound_fixed;
+
+  
   /*
     Hmm.  we do 1/0 in the next thing. Perhaps we should check if this
     works on all architectures.
@@ -791,8 +800,8 @@ Spacing_spanner::breakable_column_spacing (Grob*me, Item* l, Item *r,Moment shor
     Do it more cleanly, or rename the property. 
     
    */
-  Real strength = 1 / (max_space - max_fixed);
-  Real distance =  max_space;
+  Real strength = 1 / (compound_space - compound_fixed);
+  Real distance = compound_space;
   Spaceable_grob::add_spring (l, r, distance, strength, false);
 }
 
@@ -803,8 +812,8 @@ Spacing_spanner::breakable_column_spacing (Grob*me, Item* l, Item *r,Moment shor
 Real
 Spacing_spanner::get_duration_space (Grob*me, Moment d, Rational shortest, bool * expand_only) 
 {
-  Real k = gh_scm2double (me->get_grob_property ("shortest-duration-space"));
-  Real incr = gh_scm2double (me->get_grob_property ("spacing-increment"));
+  Real k = robust_scm2double (me->get_grob_property ("shortest-duration-space"), 1);
+  Real incr = robust_scm2double (me->get_grob_property ("spacing-increment"), 1);
   
   if (d < shortest)
     {
@@ -919,10 +928,8 @@ Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc,
       */
       dist = get_duration_space (me, shortest, shortest.main_part_, expand_only);
 
-      Real grace_fact = 1.0;
-      SCM gf = me->get_grob_property ("grace-space-factor");
-      if (gh_number_p (gf))
-       grace_fact = gh_scm2double (gf);
+      Real grace_fact
+       = robust_scm2double (me->get_grob_property ("grace-space-factor"), 1);
 
       dist *= grace_fact;
     }