2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2006--2015 Han-Wen Nienhuys <hanwen@lilypond.org>
7 LilyPond is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 LilyPond is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21 #include "engraver.hh"
25 #include "side-position-interface.hh"
26 #include "stream-event.hh"
28 #include "axis-group-interface.hh"
30 #include "translator.icc"
36 * Detach from pedal specifics,
38 * Also use this engraver for dynamics.
41 struct Pedal_align_info
43 Spanner *line_spanner_;
45 Spanner *carrying_spanner_;
46 Spanner *finished_carrying_spanner_;
56 carrying_spanner_ = 0;
58 finished_carrying_spanner_ = 0;
62 bool do_continue = carrying_item_;
64 do_continue |= (carrying_spanner_ && !finished_carrying_spanner_);
65 do_continue |= (carrying_spanner_ && finished_carrying_spanner_ != carrying_spanner_);
71 class Piano_pedal_align_engraver : public Engraver
74 TRANSLATOR_DECLARATIONS (Piano_pedal_align_engraver);
77 virtual void finalize ();
79 void acknowledge_piano_pedal_script (Grob_info);
80 void acknowledge_piano_pedal_bracket (Grob_info);
81 void acknowledge_note_column (Grob_info);
83 void acknowledge_end_piano_pedal_bracket (Grob_info);
85 void stop_translation_timestep ();
86 void start_translation_timestep ();
96 Pedal_align_info pedal_info_[NUM_PEDAL_TYPES];
97 vector<Grob *> supports_;
99 Pedal_type get_grob_pedal_type (Grob_info g);
100 Spanner *make_line_spanner (Pedal_type t, SCM);
103 Piano_pedal_align_engraver::Piano_pedal_align_engraver ()
108 Piano_pedal_align_engraver::start_translation_timestep ()
114 Piano_pedal_align_engraver::stop_translation_timestep ()
116 for (int i = 0; i < NUM_PEDAL_TYPES; i++)
118 if (pedal_info_[i].line_spanner_)
121 if (pedal_info_[i].carrying_item_)
123 if (!pedal_info_[i].line_spanner_->get_bound (LEFT))
124 pedal_info_[i].line_spanner_->set_bound (LEFT,
125 pedal_info_[i].carrying_item_);
127 pedal_info_[i].line_spanner_->set_bound (RIGHT,
128 pedal_info_[i].carrying_item_);
130 else if (pedal_info_[i].carrying_spanner_
131 || pedal_info_[i].finished_carrying_spanner_
134 if (!pedal_info_[i].line_spanner_->get_bound (LEFT)
135 && pedal_info_[i].carrying_spanner_->get_bound (LEFT))
136 pedal_info_[i].line_spanner_->set_bound (LEFT,
137 pedal_info_[i].carrying_spanner_->get_bound (LEFT));
139 if (pedal_info_[i].finished_carrying_spanner_)
140 pedal_info_[i].line_spanner_->set_bound (RIGHT,
141 pedal_info_[i].finished_carrying_spanner_->get_bound (RIGHT));
144 for (vsize j = 0; j < supports_.size (); j++)
146 Side_position_interface::add_support (pedal_info_[i].line_spanner_, supports_[j]);
149 if (pedal_info_[i].is_finished ())
151 announce_end_grob (pedal_info_[i].line_spanner_, SCM_EOL);
152 pedal_info_[i].clear ();
156 pedal_info_[i].carrying_item_ = 0;
160 Piano_pedal_align_engraver::Pedal_type
161 Piano_pedal_align_engraver::get_grob_pedal_type (Grob_info g)
163 if (g.event_cause ()->in_event_class ("sostenuto-event"))
165 if (g.event_cause ()->in_event_class ("sustain-event"))
167 if (g.event_cause ()->in_event_class ("una-corda-event"))
170 programming_error ("Unknown piano pedal type. Defaulting to sustain");
175 Piano_pedal_align_engraver::make_line_spanner (Pedal_type t, SCM cause)
177 Spanner *sp = pedal_info_[t].line_spanner_;
183 sp = make_spanner ("SostenutoPedalLineSpanner", cause);
186 sp = make_spanner ("SustainPedalLineSpanner", cause);
189 sp = make_spanner ("UnaCordaPedalLineSpanner", cause);
192 programming_error ("No pedal type fonud!");
196 pedal_info_[t].line_spanner_ = sp;
203 Piano_pedal_align_engraver::acknowledge_note_column (Grob_info gi)
205 supports_.push_back (gi.grob ());
209 Piano_pedal_align_engraver::acknowledge_piano_pedal_bracket (Grob_info gi)
211 Pedal_type type = get_grob_pedal_type (gi);
212 Grob *sp = make_line_spanner (type, gi.grob ()->self_scm ());
214 Axis_group_interface::add_element (sp, gi.grob ());
215 pedal_info_[type].carrying_spanner_ = gi.spanner ();
219 Piano_pedal_align_engraver::acknowledge_end_piano_pedal_bracket (Grob_info gi)
221 Pedal_type type = get_grob_pedal_type (gi);
222 pedal_info_[type].finished_carrying_spanner_ = gi.spanner ();
226 Piano_pedal_align_engraver::acknowledge_piano_pedal_script (Grob_info gi)
228 Pedal_type type = get_grob_pedal_type (gi);
230 Grob *sp = make_line_spanner (type, gi.grob ()->self_scm ());
231 Axis_group_interface::add_element (sp, gi.grob ());
232 pedal_info_[type].carrying_item_ = gi.grob ();
236 Piano_pedal_align_engraver::finalize ()
238 for (int i = 0; i < NUM_PEDAL_TYPES; i++)
240 if (pedal_info_[i].line_spanner_)
242 SCM cc = get_property ("currentCommandColumn");
243 Item *c = unsmob<Item> (cc);
244 pedal_info_[i].line_spanner_->set_bound (RIGHT, c);
246 pedal_info_[i].clear ();
254 Piano_pedal_align_engraver::boot ()
256 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, note_column);
257 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_bracket);
258 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_script);
259 ADD_END_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_bracket);
262 ADD_TRANSLATOR (Piano_pedal_align_engraver,
264 "Align piano pedal symbols and brackets.",
267 "SostenutoPedalLineSpanner "
268 "SustainPedalLineSpanner "
269 "UnaCordaPedalLineSpanner ",
272 "currentCommandColumn ",