From: Joe Neeman Date: Thu, 22 Jul 2010 22:10:51 +0000 (-0700) Subject: Fix 442. X-Git-Tag: release/2.13.30-1~30 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=9e205dd2ae57dce8b8e3a42f86b945517374265a;p=lilypond.git Fix 442. Add an engraver which keeps all of the staves below it alive together. --- diff --git a/input/regression/hara-kiri-alive-with.ly b/input/regression/hara-kiri-alive-with.ly new file mode 100644 index 0000000000..a916c01786 --- /dev/null +++ b/input/regression/hara-kiri-alive-with.ly @@ -0,0 +1,23 @@ +\version "2.13.29" + +\header { + texidoc = "Staves in a PianoStaff remain alive as long as any of +the staves has something interesting." +} + +\layout { + \context { + \Staff + \RemoveEmptyStaves + \override VerticalAxisGroup #'remove-first = ##t + } +} + +<< + \new Staff { c'1 \break c'1 \break c'1 } + \new PianoStaff + << + \new Staff { d'1 R1 R1 } + \new Staff { R1 e'1 R1 } + >> +>> diff --git a/lily/hara-kiri-group-spanner.cc b/lily/hara-kiri-group-spanner.cc index 395bcdb553..8f007197cd 100644 --- a/lily/hara-kiri-group-spanner.cc +++ b/lily/hara-kiri-group-spanner.cc @@ -76,6 +76,20 @@ bool find_in_range (SCM vector, int low, int hi, int min, int max) bool Hara_kiri_group_spanner::request_suicide (Grob *me, int start, int end) +{ + if (!request_suicide_alone (me, start, end)) + return false; + + extract_grob_set (me, "keep-alive-with", friends); + for (vsize i = 0; i < friends.size (); ++i) + if (friends[i]->is_live () && !request_suicide_alone (friends[i], start, end)) + return false; + + return true; +} + +bool +Hara_kiri_group_spanner::request_suicide_alone (Grob *me, int start, int end) { if (!to_boolean (me->get_property ("remove-empty"))) return false; @@ -172,6 +186,7 @@ ADD_INTERFACE (Hara_kiri_group_spanner, /* properties */ "items-worth-living " "important-column-ranks " + "keep-alive-with " "remove-empty " "remove-first " ); diff --git a/lily/include/hara-kiri-group-spanner.hh b/lily/include/hara-kiri-group-spanner.hh index bdc2cf36ff..bea7c3a221 100644 --- a/lily/include/hara-kiri-group-spanner.hh +++ b/lily/include/hara-kiri-group-spanner.hh @@ -34,6 +34,7 @@ public: DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM)); DECLARE_GROB_INTERFACE(); static bool request_suicide (Grob *me, int start, int end); + static bool request_suicide_alone (Grob *me, int start, int end); static void consider_suicide (Grob *me); static void add_interesting_item (Grob *me, Grob *n); }; diff --git a/lily/keep-alive-together-engraver.cc b/lily/keep-alive-together-engraver.cc new file mode 100644 index 0000000000..f4240cd3d6 --- /dev/null +++ b/lily/keep-alive-together-engraver.cc @@ -0,0 +1,85 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2010 Joe Neeman + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . +*/ + +#include "context.hh" +#include "dispatcher.hh" +#include "engraver.hh" +#include "grob.hh" +#include "grob-array.hh" + +#include "translator.icc" + +class Keep_alive_together_engraver: public Engraver +{ + vector group_spanners_; + +public: + TRANSLATOR_DECLARATIONS (Keep_alive_together_engraver); + DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner); + + virtual void finalize (); +}; + +Keep_alive_together_engraver::Keep_alive_together_engraver () +{ +} + +void +Keep_alive_together_engraver::acknowledge_hara_kiri_group_spanner (Grob_info i) +{ + group_spanners_.push_back (i.grob ()); +} + +void +Keep_alive_together_engraver::finalize () +{ + for (vsize i = 0; i < group_spanners_.size (); ++i) + { + SCM grob_array_scm = Grob_array::make_array (); + Grob_array *ga = unsmob_grob_array (grob_array_scm); + + // It would make Hara_kiri_group_spanner::request_suicide a _little_ + // faster if we removed each grob from its own array. It seems + // unnecessary for now, though. + ga->set_array (group_spanners_); + group_spanners_[i]->set_object ("keep-alive-with", grob_array_scm); + } +} + +ADD_ACKNOWLEDGER (Keep_alive_together_engraver, hara_kiri_group_spanner); + +ADD_TRANSLATOR (Keep_alive_together_engraver, + /* doc */ + "This engraver collects all @code{Hara_kiri_group_spanner}s " + "that are created in contexts at or below its own. " + "These spanners are then tied together so that one will " + "be removed only if all are removed. For example, " + "if a @code{StaffGroup} uses this engraver, then the staves " + "in the group will all be visible as long as there is a note " + "in at least one of them.", + + /* create */ + "", + + /* read */ + "", + + /* write */ + "" + ); diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 7b21ff2fef..6ecba2ddf4 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -316,6 +316,7 @@ instrument names at the start of each system." \consists "Instrument_name_engraver" \consists "Vertical_align_engraver" + \consists "Keep_alive_together_engraver" topLevelAlignment = ##f \override StaffGrouper #'between-staff-spacing #'stretchability = #5 diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index b4952e2a49..8fc2db4904 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -950,6 +950,9 @@ in addition to notes and stems.") (items-worth-living ,ly:grob-array? "An array of interesting items. If empty in a particular staff, then that staff is erased.") + (keep-alive-with ,ly:grob-array? "An array of other +@code{VerticalAxisGroup}s. If any of them are alive, then we will stay alive.") + (left-items ,ly:grob-array? "DOCME") (left-neighbor ,ly:grob? "The right-most column that has a spacing-wish for this column.")