From e93ef6da649651c20932fa4acbe807e8cb37e0ac Mon Sep 17 00:00:00 2001
From: Joe Neeman <joeneeman@gmail.com>
Date: Tue, 19 Jun 2007 18:05:03 +1000
Subject: [PATCH] more cleanups, convert-to-springs and code removals

---
 lily/include/paper-column.hh    |  1 +
 lily/include/spacing-spanner.hh |  5 +--
 lily/include/spring.hh          |  1 +
 lily/paper-column.cc            | 25 +++++++++++
 lily/spacing-basic.cc           | 39 +++++-------------
 lily/spacing-interface.cc       |  2 +-
 lily/spacing-loose-columns.cc   | 13 +++---
 lily/spacing-spanner.cc         | 73 ++++++++++-----------------------
 8 files changed, 66 insertions(+), 93 deletions(-)

diff --git a/lily/include/paper-column.hh b/lily/include/paper-column.hh
index 0157eb6bb9..9109e4e697 100644
--- a/lily/include/paper-column.hh
+++ b/lily/include/paper-column.hh
@@ -48,6 +48,7 @@ public:
   static Moment when_mom (Grob *);
   static bool is_used (Grob *);
   static bool is_breakable (Grob *);
+  static Real minimum_distance (Grob *l, Grob *r);
 };
 
 #endif // PAPER_COLUMN_HH
diff --git a/lily/include/spacing-spanner.hh b/lily/include/spacing-spanner.hh
index 60302736bd..9193a187d4 100644
--- a/lily/include/spacing-spanner.hh
+++ b/lily/include/spacing-spanner.hh
@@ -13,6 +13,7 @@
 #include "rational.hh"
 #include "std-vector.hh"
 #include "grob-interface.hh"
+#include "spring.hh"
 
 class Spacing_spanner
 {
@@ -34,9 +35,7 @@ private:
 public:
   static vector<Grob*> get_columns (Grob *me);
   static Real note_spacing (Grob *, Grob *, Grob *, Spacing_options const *);
-  static void standard_breakable_column_spacing (Grob *me, Item *l, Item *r,
-						 Real *fixed, Real *space,
-						 Spacing_options const *);
+  static Spring standard_breakable_column_spacing (Grob *me, Item *l, Item *r, Spacing_options const *);
   
   DECLARE_SCHEME_CALLBACK (set_springs, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_common_shortest_duration, (SCM));
diff --git a/lily/include/spring.hh b/lily/include/spring.hh
index d9b40cca46..a5c2ef0a4b 100644
--- a/lily/include/spring.hh
+++ b/lily/include/spring.hh
@@ -34,6 +34,7 @@ public:
   void set_min_distance (Real);
   void set_inverse_stretch_strength (Real);
   void set_inverse_compress_strength (Real);
+  void set_default_strength ();
 
   void operator*= (Real);
   Grob *other_;
diff --git a/lily/paper-column.cc b/lily/paper-column.cc
index e3f462894a..d09518a590 100644
--- a/lily/paper-column.cc
+++ b/lily/paper-column.cc
@@ -22,6 +22,7 @@
 #include "system.hh"
 #include "spring.hh"
 #include "lookup.hh"
+#include "separation-item.hh"
 #include "string-convert.hh"
 
 Grob *
@@ -136,6 +137,30 @@ Paper_column::is_breakable (Grob *me)
   return scm_is_symbol (me->get_property ("line-break-permission"));
 }
 
+Real
+Paper_column::minimum_distance (Grob *left, Grob *right)
+{
+  Drul_array<Grob*> cols (left, right);
+  Drul_array<Skyline> skys = Drul_array<Skyline> (Skyline (RIGHT), Skyline (LEFT));
+
+  Direction d = LEFT;
+  do
+    {
+      extract_grob_set (cols[d], "elements", elts);
+
+      for (vsize i = 0; i < elts.size (); i++)
+	if (Separation_item::has_interface (elts[i]))
+	  {
+	    Skyline_pair *sp = Skyline_pair::unsmob (elts[i]->get_property ("horizontal-skylines"));
+	    if (sp)
+	      skys[d].merge ((*sp)[-d]);
+	  }
+    }
+  while (flip (&d) != LEFT);
+
+  return min (0.0, skys[LEFT].distance (skys[RIGHT]));
+}
+
 /*
   Print a vertical line and  the rank number, to aid debugging.
 */
diff --git a/lily/spacing-basic.cc b/lily/spacing-basic.cc
index 0d73b4af0b..e2f69b0bea 100644
--- a/lily/spacing-basic.cc
+++ b/lily/spacing-basic.cc
@@ -14,6 +14,8 @@
 #include "warn.hh"
 #include "pointer-group-interface.hh"
 #include "system.hh"
+#include "spacing-interface.hh"
+#include "spring.hh"
 
 /*
   LilyPond spaces by taking a simple-minded spacing algorithm, and
@@ -24,33 +26,11 @@
   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,
-						    Spacing_options const *options)
+Spring
+Spacing_spanner::standard_breakable_column_spacing (Grob *me, Item *l, Item *r, Spacing_options const *options)
 {
-  *fixed = 0.0;
-  Direction d = LEFT;
-  Drul_array<Item *> cols (l, r);
-
-  do
-    {
-      /*
-	TODO: this is fishy, the extent gets distorted due to wide
-	\marks, so better not do this.
-       */
-      if (!Paper_column::is_musical (cols[d]))
-	{
-	  /*
-	    Tied accidentals over barlines cause problems, so lets see
-	    what happens if we do this for non musical columns only.
-	  */
-	  Interval lext = cols[d]->extent (cols [d], X_AXIS);
-	  if (!lext.is_empty ())
-	    *fixed += -d * lext[-d];
-	}
-    }
-  while (flip (&d) != LEFT);
+  Real min_dist = Paper_column::minimum_distance (l, r);
+  Real ideal;
 
   if (Paper_column::is_breakable (l) && Paper_column::is_breakable (r))
     {
@@ -61,7 +41,7 @@ Spacing_spanner::standard_breakable_column_spacing (Grob *me, Item *l, Item *r,
 
       Real incr = robust_scm2double (me->get_property ("spacing-increment"), 1);
 
-      *space = *fixed + incr * double (mlen.main_part_ / options->global_shortest_) * 0.8;
+      ideal = min_dist + incr * double (mlen.main_part_ / options->global_shortest_) * 0.8;
     }
   else
     {
@@ -73,11 +53,12 @@ Spacing_spanner::standard_breakable_column_spacing (Grob *me, Item *l, Item *r,
 	    In this case, Staff_spacing should handle the job,
 	    using dt when it is 0 is silly.
 	  */
-	  *space = *fixed + 0.5;
+	  ideal = min_dist + 0.5;
 	}
       else
-	*space = *fixed + options->get_duration_space (dt.main_part_);
+	ideal = min_dist + options->get_duration_space (dt.main_part_);
     }
+  return Spring (ideal, min_dist);
 }
 
 Moment *
diff --git a/lily/spacing-interface.cc b/lily/spacing-interface.cc
index 33a4e14d39..b5974d301c 100644
--- a/lily/spacing-interface.cc
+++ b/lily/spacing-interface.cc
@@ -30,7 +30,7 @@ Spacing_interface::minimum_distance (Grob *me)
      the broken piece.
 
      FIXME: this only works for the left column. There is only one spacing
-     grob for the original and non-original right column and we have no way
+     grob for both the original and non-original right columns and we have no way
      to tell which one we need */
 
   Grob *orig = me->original () ? me->original () : me;
diff --git a/lily/spacing-loose-columns.cc b/lily/spacing-loose-columns.cc
index ee19b29ab7..a59fa7d0f9 100644
--- a/lily/spacing-loose-columns.cc
+++ b/lily/spacing-loose-columns.cc
@@ -127,14 +127,11 @@ set_loose_columns (System *which, Column_x_positions const *posns)
 							     &options);
 	  else
 	    {
-	      Real fixed, space;
-	      
-	      Spacing_spanner::standard_breakable_column_spacing (spacing, 
-								  loose_col, next_col,
-								  &fixed, &space,
-								  &options);
-
-	      base_note_space = space;
+	      Spring spring = Spacing_spanner::standard_breakable_column_spacing (spacing,
+										  loose_col, next_col,
+										  &options);
+
+	      base_note_space = spring.distance ();
 	    }
 
 	  base_note_space = max (base_note_space,
diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc
index d158883dad..5394677d7c 100644
--- a/lily/spacing-spanner.cc
+++ b/lily/spacing-spanner.cc
@@ -370,12 +370,8 @@ void
 Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r,
 					   Spacing_options const *options)
 {
-  Real compound_fixed = 0.0;
-  Real compound_space = 0.0;
-  Real max_fixed = 0.0;
-  Real max_space = 0.0;
-  
-  int wish_count = 0;
+  vector<Spring> springs;
+  Spring spring;
 
   Moment dt = Paper_column::when_mom (r) - Paper_column::when_mom (l);
 
@@ -396,67 +392,40 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r,
 	  */
 	  assert (spacing_grob->get_column () == l);
 
-	  Spring sp = Staff_spacing::get_spacing (spacing_grob);
-	  Real space = sp.distance ();
-	  Real fixed = sp.min_distance ();
-
-	  if (Paper_column::when_mom (r).grace_part_)
-	    {
-	      /*
-		Correct for grace notes.
-
-		Ugh. The 0.8 is arbitrary.
-	      */
-	      space *= 0.8;
-	    }
-
-	  max_space = max (max_space, space);
-	  max_fixed = max (max_fixed, fixed);
-	  
-	  compound_space += space;
-	  compound_fixed += fixed;
-	  wish_count++;
+	  springs.push_back (Staff_spacing::get_spacing (spacing_grob));
 	}
     }
 
-  if (compound_space <= 0.0 || !wish_count)
-    {
-      standard_breakable_column_spacing (me, l, r, &compound_fixed, &compound_space,
-					 options);
-      wish_count = 1;
-    }
+  if (springs.empty ())
+    spring = standard_breakable_column_spacing (me, l, r, options);
   else
+    spring = merge_springs (springs);
+
+  if (Paper_column::when_mom (r).grace_part_)
     {
-      if (to_boolean (me->get_property ("average-spacing-wishes")))
-	{
-	  compound_space /= wish_count;
-	  compound_fixed /= wish_count;
-	}
-      else
-	{
-	  compound_fixed = max_fixed;
-	  compound_space = max_space;
-	}
-      
+      /*
+	Correct for grace notes.
+	
+	Ugh. The 0.8 is arbitrary.
+      */
+      spring *= 0.8;
     }
 
   if (Paper_column::is_musical (r)
       && l->break_status_dir () == CENTER
       && fills_measure (me, l, r))
     {
-      compound_space += 1.0; 
+      spring.set_distance (spring.distance () + 1.0);
+      spring.set_default_strength ();
     }
   
   if (options->stretch_uniformly_ && l->break_status_dir () != RIGHT)
-    compound_fixed = 0.0;
-
-  assert (!isinf (compound_space));
-  compound_space = max (compound_space, compound_fixed);
-
-  Real inverse_strength = (compound_space - compound_fixed);
-  Real distance = compound_space;
+    {
+      spring.set_min_distance (0.0);
+      spring.set_default_strength ();
+    }
 
-  Spaceable_grob::add_spring (l, r, distance, inverse_strength);
+  Spaceable_grob::add_spring (l, r, spring);
 }
 
 ADD_INTERFACE (Spacing_spanner,
-- 
2.39.5