2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2011 Mike Solomon <mike@apollinemike.com>
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.
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.
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/>.
23 #include "align-interface.hh"
24 #include "bar-line.hh"
28 #include "pointer-group-interface.hh"
29 #include "span-bar.hh"
30 #include "engraver.hh"
32 class Span_bar_stub_engraver : public Engraver
34 vector<Grob *> spanbars_;
35 map<Grob *, Context *> axis_groups_;
38 TRANSLATOR_DECLARATIONS (Span_bar_stub_engraver);
40 DECLARE_ACKNOWLEDGER (span_bar);
41 DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner);
42 void process_acknowledged ();
45 Span_bar_stub_engraver::Span_bar_stub_engraver ()
50 Span_bar_stub_engraver::acknowledge_span_bar (Grob_info i)
52 spanbars_.push_back (i.grob ());
55 // note that this can get out of hand if there are lots of vertical axis groups...
58 Span_bar_stub_engraver::acknowledge_hara_kiri_group_spanner (Grob_info i)
60 axis_groups_[i.grob ()] = i.context ();
64 Span_bar_stub_engraver::process_acknowledged ()
66 if (!spanbars_.size ())
69 Grob *vertical_alignment = Grob::get_root_vertical_alignment ((*axis_groups_.begin ()).first);
70 if (!vertical_alignment) // we are at the beginning of a score, so no need for stubs
73 extract_grob_set (vertical_alignment, "elements", elts);
75 for (vsize i = 0; i < spanbars_.size (); i++)
77 extract_grob_set (spanbars_[i], "elements", bars);
78 vector<vsize> bar_axis_indices;
79 for (vsize j = 0; j < bars.size (); j++)
81 int i = Grob::get_vertical_axis_group_index (bars[j]);
83 bar_axis_indices.push_back ((vsize) i);
85 vector<Context *> affected_contexts;
86 vector<Grob *> y_parents;
87 vector<bool> keep_extent;
88 for (vsize j = 0; j < elts.size (); j++)
90 if (j > bar_axis_indices[0]
91 && j < bar_axis_indices.back ()
92 && find (bar_axis_indices.begin (), bar_axis_indices.end (), j) == bar_axis_indices.end ())
95 for (; k < bar_axis_indices.size (); k++)
96 if (bar_axis_indices[k] > j)
100 keep_extent.push_back (to_boolean (bars[k]->get_property ("allow-span-bar")));
102 Context *c = axis_groups_[elts[j]];
103 if (c && c->get_parent_context ())
105 y_parents.push_back (elts[j]);
106 affected_contexts.push_back (c);
110 reverse (affected_contexts); // from bottom to top
111 reverse (y_parents); // from bottom to top
112 reverse (keep_extent); // from bottom to top
113 for (vsize j = 0; j < affected_contexts.size (); j++)
115 Item *it = new Item (updated_grob_properties (affected_contexts[j], ly_symbol2scm ("SpanBarStub")));
116 it->set_parent (spanbars_[i], X_AXIS);
117 Grob_info gi = make_grob_info (it, spanbars_[i]->self_scm ());
118 gi.rerouting_daddy_context_ = affected_contexts[j];
121 it->set_property ("Y-extent", ly_interval2scm (Interval (infinity_f, -infinity_f)));
127 #include "translator.icc"
129 ADD_ACKNOWLEDGER (Span_bar_stub_engraver, span_bar);
130 ADD_ACKNOWLEDGER (Span_bar_stub_engraver, hara_kiri_group_spanner);
131 ADD_TRANSLATOR (Span_bar_stub_engraver,
133 "Make stubs for span bars in all contexts that the span bars cross.",