2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2006--2011 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/>.
22 #include "engraver.hh"
26 #include "side-position-interface.hh"
27 #include "stream-event.hh"
29 #include "axis-group-interface.hh"
36 * Detach from pedal specifics,
38 * Also use this engraver for dynamics.
43 struct Pedal_align_info
45 Spanner
*line_spanner_
;
47 Spanner
*carrying_spanner_
;
48 Spanner
*finished_carrying_spanner_
;
58 carrying_spanner_
= 0;
60 finished_carrying_spanner_
= 0;
64 bool do_continue
= carrying_item_
;
66 do_continue
|= (carrying_spanner_
&& !finished_carrying_spanner_
);
67 do_continue
|= (carrying_spanner_
&& finished_carrying_spanner_
!= carrying_spanner_
);
73 class Piano_pedal_align_engraver
: public Engraver
76 TRANSLATOR_DECLARATIONS (Piano_pedal_align_engraver
);
79 virtual void finalize ();
81 DECLARE_ACKNOWLEDGER (piano_pedal_script
);
82 DECLARE_ACKNOWLEDGER (piano_pedal_bracket
);
83 DECLARE_ACKNOWLEDGER (note_column
);
85 DECLARE_END_ACKNOWLEDGER (piano_pedal_bracket
);
87 void stop_translation_timestep ();
88 void start_translation_timestep ();
97 Pedal_align_info pedal_info_
[NUM_PEDAL_TYPES
];
98 vector
<Grob
*> supports_
;
100 Pedal_type
get_grob_pedal_type (Grob_info g
);
101 Spanner
*make_line_spanner (Pedal_type t
, SCM
);
104 Piano_pedal_align_engraver::Piano_pedal_align_engraver ()
109 Piano_pedal_align_engraver::start_translation_timestep ()
115 Piano_pedal_align_engraver::stop_translation_timestep ()
117 for (int i
= 0; i
< NUM_PEDAL_TYPES
; i
++)
119 if (pedal_info_
[i
].line_spanner_
)
122 if (pedal_info_
[i
].carrying_item_
)
124 if (!pedal_info_
[i
].line_spanner_
->get_bound (LEFT
))
125 pedal_info_
[i
].line_spanner_
->set_bound (LEFT
,
126 pedal_info_
[i
].carrying_item_
);
128 pedal_info_
[i
].line_spanner_
->set_bound (RIGHT
,
129 pedal_info_
[i
].carrying_item_
);
131 else if (pedal_info_
[i
].carrying_spanner_
132 || pedal_info_
[i
].finished_carrying_spanner_
135 if (!pedal_info_
[i
].line_spanner_
->get_bound (LEFT
)
136 && pedal_info_
[i
].carrying_spanner_
->get_bound (LEFT
))
137 pedal_info_
[i
].line_spanner_
->set_bound (LEFT
,
138 pedal_info_
[i
].carrying_spanner_
->get_bound (LEFT
));
141 if (pedal_info_
[i
].finished_carrying_spanner_
)
142 pedal_info_
[i
].line_spanner_
->set_bound (RIGHT
,
143 pedal_info_
[i
].finished_carrying_spanner_
->get_bound (RIGHT
));
146 for (vsize j
= 0; j
< supports_
.size (); j
++)
148 Side_position_interface::add_support (pedal_info_
[i
].line_spanner_
, supports_
[j
]);
151 if (pedal_info_
[i
].is_finished ())
153 announce_end_grob (pedal_info_
[i
].line_spanner_
, SCM_EOL
);
154 pedal_info_
[i
].clear ();
158 pedal_info_
[i
].carrying_item_
= 0;
162 Piano_pedal_align_engraver::Pedal_type
163 Piano_pedal_align_engraver::get_grob_pedal_type (Grob_info g
)
165 if (g
.event_cause ()->in_event_class ("sostenuto-event"))
167 if (g
.event_cause ()->in_event_class ("sustain-event"))
169 if (g
.event_cause ()->in_event_class ("una-corda-event"))
172 programming_error ("Unknown piano pedal type. Defaulting to sustain");
178 Piano_pedal_align_engraver::make_line_spanner (Pedal_type t
, SCM cause
)
180 Spanner
*sp
= pedal_info_
[t
].line_spanner_
;
186 sp
= make_spanner ("SostenutoPedalLineSpanner", cause
);
189 sp
= make_spanner ("SustainPedalLineSpanner", cause
);
192 sp
= make_spanner ("UnaCordaPedalLineSpanner", cause
);
195 programming_error ("No pedal type fonud!") ;
199 pedal_info_
[t
].line_spanner_
= sp
;
206 Piano_pedal_align_engraver::acknowledge_note_column (Grob_info gi
)
208 supports_
.push_back (gi
.grob ());
212 Piano_pedal_align_engraver::acknowledge_piano_pedal_bracket (Grob_info gi
)
214 Pedal_type type
= get_grob_pedal_type (gi
);
215 Grob
*sp
= make_line_spanner (type
, gi
.grob ()->self_scm ());
217 Axis_group_interface::add_element (sp
, gi
.grob ());
218 pedal_info_
[type
].carrying_spanner_
= gi
.spanner ();
222 Piano_pedal_align_engraver::acknowledge_end_piano_pedal_bracket (Grob_info gi
)
224 Pedal_type type
= get_grob_pedal_type (gi
);
225 pedal_info_
[type
].finished_carrying_spanner_
= gi
.spanner ();
229 Piano_pedal_align_engraver::acknowledge_piano_pedal_script (Grob_info gi
)
231 Pedal_type type
= get_grob_pedal_type (gi
);
233 Grob
*sp
= make_line_spanner (type
, gi
.grob ()->self_scm ());
234 Axis_group_interface::add_element (sp
, gi
.grob ());
235 pedal_info_
[type
].carrying_item_
= gi
.grob ();
240 Piano_pedal_align_engraver::finalize ()
242 for (int i
= 0; i
< NUM_PEDAL_TYPES
; i
++)
244 if (pedal_info_
[i
].line_spanner_
)
246 SCM cc
= get_property ("currentCommandColumn");
247 Item
*c
= unsmob_item (cc
);
248 pedal_info_
[i
].line_spanner_
->set_bound (RIGHT
, c
);
250 pedal_info_
[i
].clear ();
255 #include "translator.icc"
257 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver
, note_column
);
258 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver
, piano_pedal_bracket
);
259 ADD_ACKNOWLEDGER (Piano_pedal_align_engraver
, piano_pedal_script
);
261 ADD_END_ACKNOWLEDGER (Piano_pedal_align_engraver
, piano_pedal_bracket
);
264 ADD_TRANSLATOR (Piano_pedal_align_engraver
,
266 "Align piano pedal symbols and brackets.",
269 "SostenutoPedalLineSpanner "
270 "SustainPedalLineSpanner "
271 "UnaCordaPedalLineSpanner ",
274 "currentCommandColumn ",