]> git.donarmstrong.com Git - lilypond.git/commitdiff
Make a pure version of calc_next_staff_spacing.
authorJoe Neeman <joeneeman@gmail.com>
Tue, 8 Jun 2010 01:11:04 +0000 (10:11 +0900)
committerJoe Neeman <joeneeman@gmail.com>
Thu, 10 Jun 2010 01:29:04 +0000 (10:29 +0900)
This fixes a bug with StaffGrouper and RemoveEmptyStaffContext,
in which the layout for only the first system would be computed correctly.

13 files changed:
input/regression/page-spacing-staff-group-hara-kiri.ly [new file with mode: 0644]
lily/align-interface.cc
lily/axis-group-interface.cc
lily/grob-property.cc
lily/grob.cc
lily/include/axis-group-interface.hh
lily/include/grob.hh
lily/include/lily-guile-macros.hh
lily/include/page-layout-problem.hh
lily/include/staff-grouper-interface.hh
lily/page-layout-problem.cc
lily/staff-grouper-interface.cc
scm/define-grobs.scm

diff --git a/input/regression/page-spacing-staff-group-hara-kiri.ly b/input/regression/page-spacing-staff-group-hara-kiri.ly
new file mode 100644 (file)
index 0000000..c89e123
--- /dev/null
@@ -0,0 +1,29 @@
+\version "2.13.23"
+
+\header {
+  texidoc = "StaffGrouper interacts correctly with \RemoveEmptyStaffContext.
+In both systems, there should be a large space between the staff groups."
+}
+
+\layout {
+  \context {
+    \RemoveEmptyStaffContext
+  }
+}
+
+\paper {
+  ragged-right = ##t
+}
+
+\score {
+  <<
+    \new StaffGroup = "G1" \with {
+      \override StaffGrouper #'after-last-staff-spacing #'space = #20
+    }
+    <<
+      \new Staff { c'1 \break c'1 \break R1 }
+      \new Staff { c'1 R1 c'1 }
+    >>
+    \new Staff { c'1 c'1 c'1 }
+  >>
+}
\ No newline at end of file
index f27316bb278535ff049b3d736bebb9e2effb7025..6d7c34d62143037569b2025881219aae99793575 100644 (file)
@@ -177,7 +177,7 @@ Align_interface::get_minimum_translations (Grob *me,
          down_skyline.merge (skylines[j-1][stacking_dir]);
          dy = down_skyline.distance (skylines[j][-stacking_dir]);
 
-         SCM spec = Page_layout_problem::get_spacing_spec (elems[j-1], elems[j]);
+         SCM spec = Page_layout_problem::get_spacing_spec (elems[j-1], elems[j], pure, start, end);
          Page_layout_problem::read_spacing_spec (spec, &padding, ly_symbol2scm ("padding"));
 
          Real min_distance = 0;
@@ -189,7 +189,7 @@ Align_interface::get_minimum_translations (Grob *me,
              // Spaceable staves may have min-distance and padding
              // constraints coming from the previous spaceable staff
              // as well as from the previous staff.
-             spec = Page_layout_problem::get_spacing_spec (last_spaceable_element, elems[j]);
+             spec = Page_layout_problem::get_spacing_spec (last_spaceable_element, elems[j], pure, start, end);
              Real spaceable_padding = 0;
              Page_layout_problem::read_spacing_spec (spec,
                                                      &spaceable_padding,
index 2eb061f83409ba73e1b4f4c87665ba471deae376..262f387ada4aa4e671b6c987a464d9a902c65b6e 100644 (file)
@@ -693,22 +693,40 @@ Axis_group_interface::print (SCM smob)
   return ret.smobbed_copy ();
 }
 
+MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_pure_next_staff_spacing, 3)
+SCM
+Axis_group_interface::calc_pure_next_staff_spacing (SCM smob, SCM start, SCM end)
+{
+  return calc_maybe_pure_next_staff_spacing (unsmob_grob (smob),
+                                            true,
+                                            scm_to_int (start),
+                                            scm_to_int (end));
+}
+
 MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_next_staff_spacing, 1)
 SCM
 Axis_group_interface::calc_next_staff_spacing (SCM smob)
 {
-  Grob *me = unsmob_grob (smob);
+  return calc_maybe_pure_next_staff_spacing (unsmob_grob (smob),
+                                            false,
+                                            0,
+                                            INT_MAX);
+}
+
+SCM
+Axis_group_interface::calc_maybe_pure_next_staff_spacing (Grob *me, bool pure, int start, int end)
+{
   Grob *grouper = unsmob_grob (me->get_object ("staff-grouper"));
 
   if (grouper)
     {
-      Grob *last_in_group = Staff_grouper_interface::get_last_grob (grouper);
+      Grob *last_in_group = Staff_grouper_interface::get_maybe_pure_last_grob (grouper, pure, start, end);
       if (me == last_in_group)
-       return grouper->get_property ("after-last-staff-spacing");
+       return grouper->get_maybe_pure_property ("after-last-staff-spacing", pure, start, end);
       else
-       return grouper->get_property ("between-staff-spacing");
+       return grouper->get_maybe_pure_property ("between-staff-spacing", pure, start, end);
     }
-  return me->get_property ("default-next-staff-spacing");
+  return me->get_maybe_pure_property ("default-next-staff-spacing", pure, start, end);
 }
 
 Real
index 55b06d6dfa2f522052b929b881bf2a974d7609c4..f174f7ee01f6128bd79c6c6d405c80998e862659 100644 (file)
@@ -191,6 +191,26 @@ Grob::internal_get_property (SCM sym) const
   return val;
 }
 
+/* Unlike internal_get_property, this function does no caching. Use it, therefore, with caution. */
+SCM
+Grob::internal_get_pure_property (SCM sym, int start, int end) const
+{
+  SCM val = internal_get_property_data (sym);
+  if (ly_is_procedure (val))
+    return call_pure_function (val, scm_list_1 (self_scm ()), start, end);
+  if (is_simple_closure (val))
+    return evaluate_with_simple_closure (self_scm (),
+                                        simple_closure_expression (val),
+                                        true, start, end);
+  return val;
+}
+
+SCM
+Grob::internal_get_maybe_pure_property (SCM sym, bool pure, int start, int end) const
+{
+  return pure ? internal_get_pure_property (sym, start, end) : internal_get_property (sym);
+}
+
 SCM
 Grob::try_callback_on_alist (SCM *alist, SCM sym, SCM proc)
 {      
index 911243bd5bd0a77a72e4f076a457d94ea9f03ef3..2680f55b47eea839316ec9f68d0cf0fe9814446b 100644 (file)
@@ -448,10 +448,7 @@ Grob::extent (Grob *refp, Axis a) const
 Interval
 Grob::pure_height (Grob *refp, int start, int end)
 {
-  SCM proc = get_property_data (ly_symbol2scm ("Y-extent"));
-  SCM iv_scm = call_pure_function (proc,
-                                  scm_list_1 (self_scm ()),
-                                  start, end);
+  SCM iv_scm = get_pure_property ("Y-extent", start, end);
   Interval iv = robust_scm2interval (iv_scm, Interval (0, 0));
   Real offset = pure_relative_y_coordinate (refp, start, end);
 
index cf230d9fb94370e7b0c7b066b934802b8283e7ce..bfe7b8100dc5a72b21fd00daecd1e2941d4ffd6b 100644 (file)
@@ -39,6 +39,7 @@ struct Axis_group_interface
   DECLARE_SCHEME_CALLBACK (print, (SCM smob));
   DECLARE_SCHEME_CALLBACK (adjacent_pure_heights, (SCM));
   DECLARE_SCHEME_CALLBACK (calc_next_staff_spacing, (SCM));
+  DECLARE_SCHEME_CALLBACK (calc_pure_next_staff_spacing, (SCM, SCM, SCM));
   static Interval relative_group_extent (vector<Grob*> const &list,
                                         Grob *common, Axis);
   static Interval relative_pure_height (Grob *me, int start, int end);
@@ -56,6 +57,7 @@ struct Axis_group_interface
   static Interval staff_extent (Grob *me, Grob *ref, Axis, Grob *staff, Axis);
   static SCM calc_common (Grob *, Axis);
   static Real minimum_distance (Grob*, Grob*, Axis);
+  static SCM calc_maybe_pure_next_staff_spacing (Grob*, bool, int, int);
   DECLARE_GROB_INTERFACE();
 };
 
index 4a037c270590ba1555fd9d108bea802ea1145ad9..3d211964a49a7fae830e0bef1c57d0b4a3e5ad73 100644 (file)
@@ -91,6 +91,8 @@ public:
   SCM get_property_alist_chain (SCM) const;
   SCM internal_get_property (SCM symbol) const;
   SCM internal_get_property_data (SCM symbol) const;
+  SCM internal_get_pure_property (SCM symbol, int start, int end) const;
+  SCM internal_get_maybe_pure_property (SCM symbol, bool pure, int start, int end) const;
   SCM internal_get_non_callback_marker_property_data (SCM symbol) const;
   SCM internal_get_object (SCM symbol) const;
   void internal_set_object (SCM sym, SCM val);
index 901c26f854d7639eaaf13599f8427fd4ecfdff5b..b86c31715da0c88824b8801dbe431a08c0d3a10f 100644 (file)
@@ -196,6 +196,10 @@ void ly_check_name (string cxx, string fname);
                          VAR, ARGLIST, DOCSTRING)
 
 #define get_property(x) internal_get_property (ly_symbol2scm (x))
+#define get_pure_property(x,y,z) \
+  internal_get_pure_property (ly_symbol2scm (x), y, z)
+#define get_maybe_pure_property(w,x,y,z) \
+  internal_get_maybe_pure_property (ly_symbol2scm (w), x, y, z)
 #define get_property_data(x) internal_get_property_data (ly_symbol2scm (x))
 #define get_object(x) internal_get_object (ly_symbol2scm (x))
 #define set_object(x, y) internal_set_object (ly_symbol2scm (x), y)
index 0b73034c4001f80863b352e4a1d45d840fa1b4c9..0502ce86783b35fd3fd2585d579c7a54474417ca 100644 (file)
@@ -34,7 +34,7 @@ public:
   static bool read_spacing_spec (SCM spec, Real* dest, SCM sym);
   static bool is_spaceable (Grob *g);
   static SCM get_details (Grob *g);
-  static SCM get_spacing_spec (Grob *before, Grob *after);
+  static SCM get_spacing_spec (Grob *before, Grob *after, bool pure, int start, int end);
 
 protected:
   void append_system (System*, Spring const&, Real padding);
index 0184a7953b1131460dad9452012791f0ccb88c26..6f8ae36ea8d531f4ee655f1e2ed7ea6e8894b661 100644 (file)
@@ -27,7 +27,7 @@ class Staff_grouper_interface
 public:
   DECLARE_GROB_INTERFACE ();
 
-  static Grob *get_last_grob (Grob *);
+  static Grob *get_maybe_pure_last_grob (Grob *, bool, int, int);
 };
 
 #endif /* STAFF_GROUPER_INTERFACE_HH */
index 25dec6035c88cf9b840e85e1cc8188d58f4201a1..38a7548f3b785fbdbfd0ad83bea6a910a60a9cd1 100644 (file)
@@ -473,7 +473,7 @@ Page_layout_problem::distribute_loose_lines (vector<Grob*> const &loose_lines,
   Simple_spacer spacer;
   for (vsize i = 0; i + 1 < loose_lines.size (); ++i)
     {
-      SCM spec = get_spacing_spec (loose_lines[i], loose_lines[i+1]);
+      SCM spec = get_spacing_spec (loose_lines[i], loose_lines[i+1], false, 0, INT_MAX);
       Spring spring (1.0, 0.0);
       alter_spring_from_spacing_spec (spec, &spring);
       spring.ensure_min_distance (min_distances[i]);
@@ -645,7 +645,7 @@ const double HUGE_STRETCH = 10e7;
 
 // Returns the spacing spec connecting BEFORE to AFTER.
 SCM
-Page_layout_problem::get_spacing_spec (Grob *before, Grob *after)
+Page_layout_problem::get_spacing_spec (Grob *before, Grob *after, bool pure, int start, int end)
 {
   // If there are no spacing wishes, return a very flexible spring.
   // This will occur, for example, if there are lyrics at the bottom of
@@ -657,38 +657,41 @@ Page_layout_problem::get_spacing_spec (Grob *before, Grob *after)
   if (is_spaceable (before))
     {
       if (is_spaceable (after))
-       return before->get_property ("next-staff-spacing");
+       return before->get_maybe_pure_property ("next-staff-spacing", pure, start, end);
       else
        {
-         Direction affinity = to_dir (after->get_property ("staff-affinity"));
+         Direction affinity = to_dir (after->get_maybe_pure_property ("staff-affinity", pure, start, end));
          return (affinity == DOWN)
-           ? add_stretchability (after->get_property ("non-affinity-spacing"), LARGE_STRETCH)
-           : after->get_property ("inter-staff-spacing");
+           ? add_stretchability (after->get_maybe_pure_property ("non-affinity-spacing", pure, start, end),
+                                 LARGE_STRETCH)
+           : after->get_maybe_pure_property ("inter-staff-spacing", pure, start, end);
        }
     }
   else
     {
       if (is_spaceable (after))
        {
-         Direction affinity = to_dir (before->get_property ("staff-affinity"));
+         Direction affinity = to_dir (before->get_maybe_pure_property ("staff-affinity", pure, start, end));
          return (affinity == UP)
-           ? add_stretchability (before->get_property ("non-affinity-spacing"), LARGE_STRETCH)
-           : before->get_property ("inter-staff-spacing");
+           ? add_stretchability (before->get_maybe_pure_property ("non-affinity-spacing", pure, start, end),
+                                 LARGE_STRETCH)
+           : before->get_maybe_pure_property ("inter-staff-spacing", pure, start, end);
        }
       else
        {
-         Direction before_affinity = to_dir (before->get_property ("staff-affinity"));
-         Direction after_affinity = to_dir (after->get_property ("staff-affinity"));
+         Direction before_affinity = to_dir (before->get_maybe_pure_property ("staff-affinity", pure, start, end));
+         Direction after_affinity = to_dir (after->get_maybe_pure_property ("staff-affinity", pure, start, end));
          if (after_affinity > before_affinity)
            {
              warning (_ ("staff-affinities should only decrease"));
              after_affinity = before_affinity;
            }
          if (before_affinity != UP)
-           return before->get_property ("inter-loose-line-spacing");
+           return before->get_maybe_pure_property ("inter-loose-line-spacing", pure, start, end);
          else if (after_affinity != DOWN)
-           return before->get_property ("inter-loose-line-spacing");
-         return add_stretchability (before->get_property ("non-affinity-spacing"), LARGE_STRETCH);
+           return before->get_maybe_pure_property ("inter-loose-line-spacing", pure, start, end);
+         return add_stretchability (before->get_maybe_pure_property ("non-affinity-spacing", pure, start, end),
+                                    LARGE_STRETCH);
        }
     }
 
index e4a3be02ca09bbd268a086e521ba85222b932a47..7366190524cda2a23413ce9e402c55ea00a72b1e 100644 (file)
 
 #include "staff-grouper-interface.hh"
 
+#include "hara-kiri-group-spanner.hh"
 #include "pointer-group-interface.hh"
 
 Grob*
-Staff_grouper_interface::get_last_grob (Grob *me)
+Staff_grouper_interface::get_maybe_pure_last_grob (Grob *me, bool pure, int start, int end)
 {
   extract_grob_set (me, "elements", elts);
   for (vsize i = elts.size (); i--;)
-    if (elts[i]->is_live ())
+    if ((pure && !Hara_kiri_group_spanner::request_suicide (me, start, end))
+       || (!pure && elts[i]->is_live ()))
       return elts[i];
 
   return 0;
index 7be62f1c82cb0ccf5f810ffce2d18be47472d10c..aa761fce54ca5a3b51ea76ed390fbc0039f466b0 100644 (file)
 (define pure-conversions-alist
   `(
     (,ly:accidental-interface::height . ,ly:accidental-interface::pure-height)
-    (,ly:slur::outside-slur-callback . ,ly:slur::pure-outside-slur-callback)
-    (,ly:stem::height . ,ly:stem::pure-height)
-    (,ly:rest::height . ,ly:rest::pure-height)
+    (,ly:axis-group-interface::calc-next-staff-spacing . ,ly:axis-group-interface::calc-pure-next-staff-spacing)
+    (,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height)
     (,ly:grob::stencil-height . ,pure-stencil-height)
+    (,ly:hara-kiri-group-spanner::y-extent . ,ly:hara-kiri-group-spanner::pure-height)
+    (,ly:rest::height . ,ly:rest::pure-height)
     (,ly:self-alignment-interface::y-aligned-on-self . ,ly:self-alignment-interface::pure-y-aligned-on-self)
     (,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side)
-    (,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height)
-    (,ly:hara-kiri-group-spanner::y-extent . ,ly:hara-kiri-group-spanner::pure-height)
+    (,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side)
     (,ly:slur::height . ,ly:slur::pure-height)
-    (,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side)))
+    (,ly:slur::outside-slur-callback . ,ly:slur::pure-outside-slur-callback)
+    (,ly:stem::height . ,ly:stem::pure-height)))
 
 (define pure-functions
   (list