]> git.donarmstrong.com Git - lilypond.git/blob - lily/span-bar-stub-engraver.cc
Merge branch 'lilypond/translation' into staging
[lilypond.git] / lily / span-bar-stub-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2011--2012 Mike Solomon <mike@apollinemike.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 <map>
21 #include <algorithm>
22
23 #include "align-interface.hh"
24 #include "bar-line.hh"
25 #include "context.hh"
26 #include "grob.hh"
27 #include "item.hh"
28 #include "pointer-group-interface.hh"
29 #include "span-bar.hh"
30 #include "engraver.hh"
31
32 /*
33   Note that span bar stubs exist for pure height calculations ONLY.
34   They should never be visually present on the page and should never
35   be engraved in contexts where BarLines are engraved.
36 */
37
38 class Span_bar_stub_engraver : public Engraver
39 {
40   vector<Grob *> spanbars_;
41   map<Grob *, Context *> axis_groups_;
42
43 public:
44   TRANSLATOR_DECLARATIONS (Span_bar_stub_engraver);
45 protected:
46   DECLARE_ACKNOWLEDGER (span_bar);
47   DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner);
48   void process_acknowledged ();
49 };
50
51 Span_bar_stub_engraver::Span_bar_stub_engraver ()
52 {
53 }
54
55 void
56 Span_bar_stub_engraver::acknowledge_span_bar (Grob_info i)
57 {
58   spanbars_.push_back (i.grob ());
59 }
60
61 void
62 Span_bar_stub_engraver::acknowledge_hara_kiri_group_spanner (Grob_info i)
63 {
64   axis_groups_[i.grob ()] = i.context ();
65 }
66
67 void
68 Span_bar_stub_engraver::process_acknowledged ()
69 {
70   if (!spanbars_.size ())
71     return;
72
73   Grob *vertical_alignment = Grob::get_root_vertical_alignment ((*axis_groups_.begin ()).first);
74   if (!vertical_alignment) // we are at the beginning of a score, so no need for stubs
75     return;
76
77   extract_grob_set (vertical_alignment, "elements", elts);
78
79   for (vsize i = 0; i < spanbars_.size (); i++)
80     {
81       extract_grob_set (spanbars_[i], "elements", bars);
82       vector<vsize> bar_axis_indices;
83       for (vsize j = 0; j < bars.size (); j++)
84         {
85           int i = Grob::get_vertical_axis_group_index (bars[j]);
86           if (i >= 0)
87             bar_axis_indices.push_back ((vsize) i);
88         }
89       vector<Context *> affected_contexts;
90       vector<Grob *> y_parents;
91       vector<bool> keep_extent;
92       for (vsize j = 0; j < elts.size (); j++)
93         {
94           if (j > bar_axis_indices[0]
95               && j < bar_axis_indices.back ()
96               && find (bar_axis_indices.begin (), bar_axis_indices.end (), j) == bar_axis_indices.end ())
97             {
98               vsize k = 0;
99               for (; k < bar_axis_indices.size (); k++)
100                 if (bar_axis_indices[k] > j)
101                   break;
102
103               k--;
104               keep_extent.push_back (to_boolean (bars[k]->get_property ("allow-span-bar")));
105
106               Context *c = axis_groups_[elts[j]];
107               if (c && c->get_parent_context ())
108                 {
109                   y_parents.push_back (elts[j]);
110                   affected_contexts.push_back (c);
111                 }
112             }
113         }
114       reverse (affected_contexts); // from bottom to top
115       reverse (y_parents); // from bottom to top
116       reverse (keep_extent); // from bottom to top
117       for (vsize j = 0; j < affected_contexts.size (); j++)
118         {
119           Item *it = new Item (updated_grob_properties (affected_contexts[j], ly_symbol2scm ("SpanBarStub")));
120           it->set_parent (spanbars_[i], X_AXIS);
121           Grob_info gi = make_grob_info (it, spanbars_[i]->self_scm ());
122           gi.rerouting_daddy_context_ = affected_contexts[j];
123           announce_grob (gi);
124           if (!keep_extent[j])
125             it->suicide ();//it->set_property ("Y-extent", ly_interval2scm (Interval (infinity_f, -infinity_f)));
126         }
127     }
128   spanbars_.clear ();
129 }
130
131 #include "translator.icc"
132
133 ADD_ACKNOWLEDGER (Span_bar_stub_engraver, span_bar);
134 ADD_ACKNOWLEDGER (Span_bar_stub_engraver, hara_kiri_group_spanner);
135 ADD_TRANSLATOR (Span_bar_stub_engraver,
136                 /* doc */
137                 "Make stubs for span bars in all contexts that the span bars cross.",
138
139                 /* create */
140                 "SpanBarStub ",
141
142                 /* read */
143                 "",
144
145                 /* write */
146                 ""
147                );