2 piano-pedal-align-engraver.cc -- implement Piano_pedal_align_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2006--2009 Han-Wen Nienhuys <hanwen@lilypond.org>
11 #include "engraver.hh"
15 #include "side-position-interface.hh"
16 #include "stream-event.hh"
18 #include "axis-group-interface.hh"
25 * Detach from pedal specifics,
27 * Also use this engraver for dynamics.
32 struct Pedal_align_info
34 Spanner *line_spanner_;
36 Spanner *carrying_spanner_;
37 Spanner *finished_carrying_spanner_;
47 carrying_spanner_ = 0;
49 finished_carrying_spanner_ = 0;
53 bool do_continue = carrying_item_;
55 do_continue |= (carrying_spanner_ && !finished_carrying_spanner_);
56 do_continue |= (carrying_spanner_ && finished_carrying_spanner_ != carrying_spanner_);
62 class Piano_pedal_align_engraver : public Engraver
65 TRANSLATOR_DECLARATIONS (Piano_pedal_align_engraver);
68 virtual void finalize ();
70 DECLARE_ACKNOWLEDGER (piano_pedal_script);
71 DECLARE_ACKNOWLEDGER (piano_pedal_bracket);
72 DECLARE_ACKNOWLEDGER (note_column);
74 DECLARE_END_ACKNOWLEDGER (piano_pedal_bracket);
76 void stop_translation_timestep ();
77 void start_translation_timestep ();
86 Pedal_align_info pedal_info_[NUM_PEDAL_TYPES];
87 vector<Grob *> supports_;
89 Pedal_type get_grob_pedal_type (Grob_info g);
90 Spanner *make_line_spanner (Pedal_type t, SCM);
93 Piano_pedal_align_engraver::Piano_pedal_align_engraver ()
98 Piano_pedal_align_engraver::start_translation_timestep ()
104 Piano_pedal_align_engraver::stop_translation_timestep ()
106 for (int i = 0; i < NUM_PEDAL_TYPES; i ++)
108 if (pedal_info_[i].line_spanner_)
111 if (pedal_info_[i].carrying_item_)
113 if (!pedal_info_[i].line_spanner_->get_bound (LEFT))
114 pedal_info_[i].line_spanner_->set_bound (LEFT,
115 pedal_info_[i].carrying_item_);
117 pedal_info_[i].line_spanner_->set_bound (RIGHT,
118 pedal_info_[i].carrying_item_);
120 else if (pedal_info_[i].carrying_spanner_
121 || pedal_info_[i].finished_carrying_spanner_
124 if (!pedal_info_[i].line_spanner_->get_bound (LEFT)
125 && pedal_info_[i].carrying_spanner_->get_bound (LEFT))
126 pedal_info_[i].line_spanner_->set_bound (LEFT,
127 pedal_info_[i].carrying_spanner_->get_bound (LEFT));
130 if (pedal_info_[i].finished_carrying_spanner_)
131 pedal_info_[i].line_spanner_->set_bound (RIGHT,
132 pedal_info_[i].finished_carrying_spanner_->get_bound (RIGHT));
135 for (vsize j = 0; j < supports_.size (); j++)
137 Side_position_interface::add_support (pedal_info_[i].line_spanner_, supports_[j]);
140 if (pedal_info_[i].is_finished ())
142 announce_end_grob (pedal_info_[i].line_spanner_, SCM_EOL);
143 pedal_info_[i].clear ();
147 pedal_info_[i].carrying_item_ = 0;
151 Piano_pedal_align_engraver::Pedal_type
152 Piano_pedal_align_engraver::get_grob_pedal_type (Grob_info g)
154 if (g.event_cause ()->in_event_class ("sostenuto-event"))
156 if (g.event_cause ()->in_event_class ("sustain-event"))
158 if (g.event_cause ()->in_event_class ("una-corda-event"))
161 programming_error ("Unknown piano pedal type. Defaulting to sustain");
167 Piano_pedal_align_engraver::make_line_spanner (Pedal_type t, SCM cause)
169 Spanner *sp = pedal_info_[t].line_spanner_;
175 sp = make_spanner ("SostenutoPedalLineSpanner", cause);
178 sp = make_spanner ("SustainPedalLineSpanner", cause);
181 sp = make_spanner ("UnaCordaPedalLineSpanner", cause);
184 programming_error ("No pedal type fonud!") ;
188 pedal_info_[t].line_spanner_ = sp;
195 Piano_pedal_align_engraver::acknowledge_note_column (Grob_info gi)
197 supports_.push_back (gi.grob ());
201 Piano_pedal_align_engraver::acknowledge_piano_pedal_bracket (Grob_info gi)
203 Pedal_type type = get_grob_pedal_type (gi);
204 Grob *sp = make_line_spanner (type, gi.grob ()->self_scm ());
206 Axis_group_interface::add_element (sp, gi.grob ());
207 pedal_info_[type].carrying_spanner_ = gi.spanner ();
211 Piano_pedal_align_engraver::acknowledge_end_piano_pedal_bracket (Grob_info gi)
213 Pedal_type type = get_grob_pedal_type (gi);
214 pedal_info_[type].finished_carrying_spanner_ = gi.spanner ();
218 Piano_pedal_align_engraver::acknowledge_piano_pedal_script (Grob_info gi)
220 Pedal_type type = get_grob_pedal_type (gi);
222 Grob *sp = make_line_spanner (type, gi.grob ()->self_scm ());
223 Axis_group_interface::add_element (sp, gi.grob ());
224 pedal_info_[type].carrying_item_ = gi.grob ();
229 Piano_pedal_align_engraver::finalize ()
231 for (int i = 0; i < NUM_PEDAL_TYPES; i ++)
233 if (pedal_info_[i].line_spanner_)
235 SCM cc = get_property ("currentCommandColumn");
236 Item *c = unsmob_item (cc);
237 pedal_info_[i].line_spanner_->set_bound (RIGHT, c);
239 pedal_info_[i].clear ();
244 #include "translator.icc"
246 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, note_column);
247 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_bracket);
248 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_script);
250 ADD_END_ACKNOWLEDGER (Piano_pedal_align_engraver, piano_pedal_bracket);
253 ADD_TRANSLATOR (Piano_pedal_align_engraver,
255 "Align piano pedal symbols and brackets.",
258 "SostenutoPedalLineSpanner "
259 "SustainPedalLineSpanner "
260 "UnaCordaPedalLineSpanner ",
263 "currentCommandColumn ",