summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Neeman <joeneeman@gmail.com>2010-06-08 10:11:04 +0900
committerJoe Neeman <joeneeman@gmail.com>2010-06-10 10:29:04 +0900
commit05d8315484c180e02bf9297513bd0c3db1e4615a (patch)
tree5f5f539140e7a6d80cb78c01d5e2322335326d14
parent229701a3277dad1c8d2057bd8cc1ba085728face (diff)
Make a pure version of calc_next_staff_spacing.
This fixes a bug with StaffGrouper and RemoveEmptyStaffContext, in which the layout for only the first system would be computed correctly.
-rw-r--r--input/regression/page-spacing-staff-group-hara-kiri.ly29
-rw-r--r--lily/align-interface.cc4
-rw-r--r--lily/axis-group-interface.cc28
-rw-r--r--lily/grob-property.cc20
-rw-r--r--lily/grob.cc5
-rw-r--r--lily/include/axis-group-interface.hh2
-rw-r--r--lily/include/grob.hh2
-rw-r--r--lily/include/lily-guile-macros.hh4
-rw-r--r--lily/include/page-layout-problem.hh2
-rw-r--r--lily/include/staff-grouper-interface.hh2
-rw-r--r--lily/page-layout-problem.cc31
-rw-r--r--lily/staff-grouper-interface.cc6
-rw-r--r--scm/define-grobs.scm13
13 files changed, 113 insertions, 35 deletions
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
index 0000000000..c89e123eda
--- /dev/null
+++ b/input/regression/page-spacing-staff-group-hara-kiri.ly
@@ -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
diff --git a/lily/align-interface.cc b/lily/align-interface.cc
index f27316bb27..6d7c34d621 100644
--- a/lily/align-interface.cc
+++ b/lily/align-interface.cc
@@ -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,
diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc
index 2eb061f834..262f387ada 100644
--- a/lily/axis-group-interface.cc
+++ b/lily/axis-group-interface.cc
@@ -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
diff --git a/lily/grob-property.cc b/lily/grob-property.cc
index 55b06d6dfa..f174f7ee01 100644
--- a/lily/grob-property.cc
+++ b/lily/grob-property.cc
@@ -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)
{
diff --git a/lily/grob.cc b/lily/grob.cc
index 911243bd5b..2680f55b47 100644
--- a/lily/grob.cc
+++ b/lily/grob.cc
@@ -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);
diff --git a/lily/include/axis-group-interface.hh b/lily/include/axis-group-interface.hh
index cf230d9fb9..bfe7b8100d 100644
--- a/lily/include/axis-group-interface.hh
+++ b/lily/include/axis-group-interface.hh
@@ -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();
};
diff --git a/lily/include/grob.hh b/lily/include/grob.hh
index 4a037c2705..3d211964a4 100644
--- a/lily/include/grob.hh
+++ b/lily/include/grob.hh
@@ -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);
diff --git a/lily/include/lily-guile-macros.hh b/lily/include/lily-guile-macros.hh
index 901c26f854..b86c31715d 100644
--- a/lily/include/lily-guile-macros.hh
+++ b/lily/include/lily-guile-macros.hh
@@ -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)
diff --git a/lily/include/page-layout-problem.hh b/lily/include/page-layout-problem.hh
index 0b73034c40..0502ce8678 100644
--- a/lily/include/page-layout-problem.hh
+++ b/lily/include/page-layout-problem.hh
@@ -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);
diff --git a/lily/include/staff-grouper-interface.hh b/lily/include/staff-grouper-interface.hh
index 0184a7953b..6f8ae36ea8 100644
--- a/lily/include/staff-grouper-interface.hh
+++ b/lily/include/staff-grouper-interface.hh
@@ -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 */
diff --git a/lily/page-layout-problem.cc b/lily/page-layout-problem.cc
index 25dec6035c..38a7548f3b 100644
--- a/lily/page-layout-problem.cc
+++ b/lily/page-layout-problem.cc
@@ -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);
}
}
diff --git a/lily/staff-grouper-interface.cc b/lily/staff-grouper-interface.cc
index e4a3be02ca..7366190524 100644
--- a/lily/staff-grouper-interface.cc
+++ b/lily/staff-grouper-interface.cc
@@ -19,14 +19,16 @@
#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;
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index 7be62f1c82..aa761fce54 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -2386,16 +2386,17 @@
(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