From 466004b5bf67b03a76a135c14c88c222b3208457 Mon Sep 17 00:00:00 2001
From: Mike Solomon <mike@apollinemike.com>
Date: Wed, 9 Nov 2011 14:41:21 +0100
Subject: [PATCH] Caches full score pure minimum translations in
 align-interface implementing grobs.

---
 lily/align-interface.cc         | 17 ++++++++++++++++-
 lily/include/align-interface.hh |  1 +
 lily/include/lily-guile.hh      |  3 +++
 lily/lily-guile.cc              | 22 ++++++++++++++++++++++
 scm/define-grob-properties.scm  |  2 ++
 scm/define-grobs.scm            |  6 ++++--
 6 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/lily/align-interface.cc b/lily/align-interface.cc
index 00ea0029e3..fb1ccf8a21 100644
--- a/lily/align-interface.cc
+++ b/lily/align-interface.cc
@@ -308,11 +308,25 @@ Align_interface::align_elements_to_minimum_distances (Grob *me, Axis a)
       all_grobs[j]->translate_axis (translates[j], a);
 }
 
+
+MAKE_SCHEME_CALLBACK (Align_interface, full_score_pure_minimum_translations, 1);
+SCM
+Align_interface::full_score_pure_minimum_translations (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  extract_grob_set (me, "elements", all_grobs);
+
+  vector<Real> pure_minimum_translations = Align_interface::get_pure_minimum_translations (me, all_grobs, Y_AXIS, 0, INT_MAX);
+  return ly_floatvector2scm (pure_minimum_translations);
+}
+
 Real
 Align_interface::get_pure_child_y_translation (Grob *me, Grob *ch, int start, int end)
 {
   extract_grob_set (me, "elements", all_grobs);
-  vector<Real> translates = get_pure_minimum_translations (me, all_grobs, Y_AXIS, start, end);
+  vector<Real> translates = start == 0 && end == INT_MAX
+                            ? ly_scm2floatvector (me->get_object ("full-score-pure-minimum-translations"))
+                            : get_pure_minimum_translations (me, all_grobs, Y_AXIS, start, end);
 
   if (translates.size ())
     {
@@ -369,6 +383,7 @@ ADD_INTERFACE (Align_interface,
                /* properties */
                "align-dir "
                "axes "
+               "full-score-pure-minimum-translations "
                "elements "
                "padding "
                "positioning-done "
diff --git a/lily/include/align-interface.hh b/lily/include/align-interface.hh
index b7ef1d5f01..f7b85f42aa 100644
--- a/lily/include/align-interface.hh
+++ b/lily/include/align-interface.hh
@@ -29,6 +29,7 @@ class Align_interface
 public:
   DECLARE_SCHEME_CALLBACK (align_to_minimum_distances, (SCM));
   DECLARE_SCHEME_CALLBACK (align_to_ideal_distances, (SCM));
+  DECLARE_SCHEME_CALLBACK (full_score_pure_minimum_translations, (SCM));
   static void align_elements_to_minimum_distances (Grob *, Axis a);
   static void align_elements_to_ideal_distances (Grob *);
   static vector<Real> get_minimum_translations (Grob *, vector<Grob *> const &, Axis a);
diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh
index 160729e905..c153aeb4dc 100644
--- a/lily/include/lily-guile.hh
+++ b/lily/include/lily-guile.hh
@@ -26,6 +26,7 @@
 
 #include <libguile.h>
 #include <string.h>
+#include <vector>
 
 /*
   Hack for various MacOS incarnations.
@@ -78,6 +79,8 @@ Interval robust_scm2interval (SCM, Drul_array<Real>);
 Offset robust_scm2offset (SCM, Offset);
 string robust_scm2string (SCM, string);
 Rational robust_scm2rational (SCM, Rational);
+vector<Real> ly_scm2floatvector (SCM);
+SCM ly_floatvector2scm (vector<Real> v);
 
 SCM ly_quote_scm (SCM s);
 bool type_check_assignment (SCM val, SCM sym, SCM type_symbol);
diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc
index 933bf27170..6aa40f7804 100644
--- a/lily/lily-guile.cc
+++ b/lily/lily-guile.cc
@@ -527,6 +527,28 @@ robust_scm2double (SCM k, double x)
   return x;
 }
 
+vector<Real>
+ly_scm2floatvector (SCM l)
+{
+  vector<Real> floats;
+  for (SCM s = l; scm_is_pair (s); s = scm_cdr (s))
+    floats.push_back (robust_scm2double (scm_car (s), 0.0));
+  return floats;
+}
+
+SCM
+ly_floatvector2scm (vector<Real> v)
+{
+  SCM l = SCM_EOL;
+  SCM *tail = &l;
+  for (vsize i = 0; i < v.size (); i++)
+    {
+      *tail = scm_cons (scm_from_double (v[i]), SCM_EOL);
+      tail = SCM_CDRLOC (*tail);
+    }
+  return l;
+}
+
 string
 robust_scm2string (SCM k, string s)
 {
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index b5acc268c3..a6273dd307 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -1033,6 +1033,8 @@ in addition to notes and stems.")
      (figures ,ly:grob-array? "Figured bass objects for continuation line.")
      (flag ,ly:grob? "A pointer to a @code{Flag} object.")
      (footnote-stencil ,ly:stencil? "The stencil of a system's footnotes.")
+     (full-score-pure-minimum-translations ,list? "A list of translations
+for a full score's worth of grobs.")
 
      (glissando-index ,integer? "The index of a glissando in its note
 column.")
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index 9e213c6daa..36340f4a26 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -278,7 +278,8 @@
 	(stacking-dir . ,DOWN)
 	(Y-extent . ,ly:axis-group-interface::height)
 	(meta . ((class . Spanner)
-		 (object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
+		 (object-callbacks . ((full-score-pure-minimum-translations . ,ly:align-interface::full-score-pure-minimum-translations)
+				      (pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
 				      (pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
 		 (interfaces . (align-interface
 				axis-group-interface
@@ -2437,7 +2438,8 @@
 	(X-extent . ,ly:axis-group-interface::width)
 	(Y-extent . ,ly:axis-group-interface::height)
 	(meta . ((class . Spanner)
-		 (object-callbacks . ((Y-common . ,ly:axis-group-interface::calc-y-common)
+		 (object-callbacks . ((full-score-pure-minimum-translations . ,ly:align-interface::full-score-pure-minimum-translations)
+				      (Y-common . ,ly:axis-group-interface::calc-y-common)
 				      (pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)
 				      (pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)))
 		 (interfaces . (align-interface
-- 
2.39.5