diff options
author | Joe Neeman <joeneeman@gmail.com> | 2010-06-08 10:11:04 +0900 |
---|---|---|
committer | Joe Neeman <joeneeman@gmail.com> | 2010-06-10 10:29:04 +0900 |
commit | 05d8315484c180e02bf9297513bd0c3db1e4615a (patch) | |
tree | 5f5f539140e7a6d80cb78c01d5e2322335326d14 | |
parent | 229701a3277dad1c8d2057bd8cc1ba085728face (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.ly | 29 | ||||
-rw-r--r-- | lily/align-interface.cc | 4 | ||||
-rw-r--r-- | lily/axis-group-interface.cc | 28 | ||||
-rw-r--r-- | lily/grob-property.cc | 20 | ||||
-rw-r--r-- | lily/grob.cc | 5 | ||||
-rw-r--r-- | lily/include/axis-group-interface.hh | 2 | ||||
-rw-r--r-- | lily/include/grob.hh | 2 | ||||
-rw-r--r-- | lily/include/lily-guile-macros.hh | 4 | ||||
-rw-r--r-- | lily/include/page-layout-problem.hh | 2 | ||||
-rw-r--r-- | lily/include/staff-grouper-interface.hh | 2 | ||||
-rw-r--r-- | lily/page-layout-problem.cc | 31 | ||||
-rw-r--r-- | lily/staff-grouper-interface.cc | 6 | ||||
-rw-r--r-- | scm/define-grobs.scm | 13 |
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 |