]> git.donarmstrong.com Git - lilypond.git/blob - lily/keep-alive-together-engraver.cc
Issue 4550 (1/2) Avoid "using namespace std;" in included files
[lilypond.git] / lily / keep-alive-together-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2010--2015 Joe Neeman <joeneeman@gmail.com>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "context.hh"
21 #include "dispatcher.hh"
22 #include "engraver.hh"
23 #include "grob.hh"
24 #include "grob-array.hh"
25
26 #include "translator.icc"
27
28 using std::vector;
29
30 class Keep_alive_together_engraver: public Engraver
31 {
32   vector<Grob *> group_spanners_;
33
34 public:
35   TRANSLATOR_DECLARATIONS (Keep_alive_together_engraver);
36   DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner);
37
38   virtual void finalize ();
39 };
40
41 Keep_alive_together_engraver::Keep_alive_together_engraver ()
42 {
43 }
44
45 void
46 Keep_alive_together_engraver::acknowledge_hara_kiri_group_spanner (Grob_info i)
47 {
48   group_spanners_.push_back (i.grob ());
49 }
50
51 void
52 Keep_alive_together_engraver::finalize ()
53 {
54   for (vsize i = 0; i < group_spanners_.size (); ++i)
55     {
56       SCM this_layer = group_spanners_[i]->get_property ("remove-layer");
57       if (scm_is_false (this_layer))
58         continue;
59
60       SCM live_scm = Grob_array::make_array ();
61       Grob_array *live = unsmob<Grob_array> (live_scm);
62       SCM dead_scm = Grob_array::make_array ();
63       Grob_array *dead = unsmob<Grob_array> (dead_scm);
64
65       for (vsize j = 0; j < group_spanners_.size (); ++j)
66         {
67           if (i == j)
68             continue;
69           SCM that_layer = group_spanners_[j]->get_property ("remove-layer");
70           if (scm_is_false (that_layer))
71             continue;
72           if (!scm_is_integer (this_layer))
73             {
74               // Unspecified layers are kept alive by anything else
75               live->add (group_spanners_[j]);
76               continue;
77             }
78           // an explicit layer is only affected by explicit layers
79           if (!scm_is_integer (that_layer))
80             continue;
81           if (scm_is_true (scm_num_eq_p (that_layer, this_layer)))
82             live->add (group_spanners_[j]);
83           else if (scm_is_true (scm_less_p (that_layer, this_layer)))
84             dead->add (group_spanners_[j]);
85         }
86       if (!live->empty ())
87         group_spanners_[i]->set_object ("keep-alive-with", live_scm);
88       if (!dead->empty ())
89         group_spanners_[i]->set_object ("make-dead-when", dead_scm);
90     }
91 }
92
93 ADD_ACKNOWLEDGER (Keep_alive_together_engraver, hara_kiri_group_spanner);
94
95 ADD_TRANSLATOR (Keep_alive_together_engraver,
96                 /* doc */
97                 "This engraver collects all @code{Hara_kiri_group_spanner}s "
98                 "that are created in contexts at or below its own.  "
99                 "These spanners are then tied together so that one will "
100                 "be removed only if all are removed.  For example, "
101                 "if a @code{StaffGroup} uses this engraver, then the staves "
102                 "in the group will all be visible as long as there is a note "
103                 "in at least one of them.",
104
105                 /* create */
106                 "",
107
108                 /* read */
109                 "",
110
111                 /* write */
112                 ""
113                );