2 volta-engraver.cc -- implement Volta_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
11 #include "volta-bracket.hh"
12 #include "note-column.hh"
13 #include "bar-line.hh"
14 #include "side-position-interface.hh"
16 #include "staff-symbol.hh"
18 #include "translator.icc"
21 Create Volta spanners, by reading repeatCommands property, usually
22 set by Unfolded_repeat_iterator.
24 class Volta_engraver : public Engraver
27 TRANSLATOR_DECLARATIONS (Volta_engraver);
30 DECLARE_ACKNOWLEDGER(staff_symbol);
31 DECLARE_ACKNOWLEDGER(note_column);
32 DECLARE_ACKNOWLEDGER(bar_line);
34 virtual void finalize ();
36 PRECOMPUTED_VIRTUAL void stop_translation_timestep ();
37 PRECOMPUTED_VIRTUAL void process_music ();
41 Spanner *end_volta_span_;
45 bool staff_eligible ();
48 Volta_engraver::Volta_engraver ()
56 TODO: this logic should be rewritten, it is buggy.
58 One of the problems is that we can't determine wether or not to
59 print the volta bracket during the first step, since that requires
60 acknowledging the staff.
63 Volta_engraver::staff_eligible ()
65 SCM doit = get_property ("voltaOnThisStaff");
66 if (scm_is_bool (doit))
68 return to_boolean (doit);
71 if (!unsmob_grob (staff_))
75 TODO: this does weird things when you open a piece with a
78 SCM staffs = get_property ("stavesFound");
80 /* Only put a volta on the top staff.
81 Maybe this is a bit convoluted, and we should have a single
82 volta engraver in score context or somesuch. */
83 if (!scm_is_pair (staffs))
85 programming_error ("volta engraver can't find staffs");
88 else if (scm_car (scm_last_pair (staffs)) != staff_)
94 Volta_engraver::process_music ()
96 SCM cs = get_property ("repeatCommands");
98 if (!staff_eligible ())
102 start_string_ = SCM_EOL;
103 while (scm_is_pair (cs))
105 SCM c = scm_car (cs);
108 && scm_car (c) == ly_symbol2scm ("volta")
109 && scm_is_pair (scm_cdr (c)))
111 if (scm_cadr (c) == SCM_BOOL_F)
114 start_string_ = scm_cadr (c);
122 SCM l (get_property ("voltaSpannerDuration"));
123 Moment now = now_mom ();
125 bool early_stop = unsmob_moment (l)
126 && *unsmob_moment (l) <= now - started_mom_;
128 end = end || early_stop;
131 if (end && !volta_span_)
132 /* fixme: be more verbose. */
133 warning (_ ("can't end volta spanner"));
136 end_volta_span_ = volta_span_;
141 && (scm_is_string (start_string_) || scm_is_pair (start_string_)))
143 warning (_ ("already have a volta spanner, ending that one prematurely"));
147 warning (_ ("also already have an ended spanner"));
148 warning (_ ("giving up"));
152 end_volta_span_ = volta_span_;
157 && (scm_is_string (start_string_) || scm_is_pair (start_string_)))
159 started_mom_ = now_mom ();
161 volta_span_ = make_spanner ("VoltaBracket", SCM_EOL);
163 volta_span_->set_property ("text", start_string_);
168 Volta_engraver::acknowledge_note_column (Grob_info i)
171 Volta_bracket_interface::add_column (volta_span_, i.grob());
175 Volta_engraver::acknowledge_bar_line (Grob_info i)
178 Volta_bracket_interface::add_bar (volta_span_, i.item ());
180 Volta_bracket_interface::add_bar (end_volta_span_, i.item ());
184 Volta_engraver::acknowledge_staff_symbol (Grob_info i)
187 We only want to know about a single staff: then we add to the
189 if (staff_ != SCM_EOL)
190 staff_ = SCM_UNDEFINED;
192 if (staff_ != SCM_UNDEFINED)
193 staff_ = i.grob ()->self_scm ();
197 Volta_engraver::finalize ()
202 Volta_engraver::stop_translation_timestep ()
204 if (volta_span_ && !staff_eligible ())
209 we need to do this here, because STAFF_ is not initialized yet
210 in the 1st call of process_music ()
213 volta_span_->suicide ();
217 if (end_volta_span_ && !end_volta_span_->get_bound (RIGHT))
219 Grob *cc = unsmob_grob (get_property ("currentCommandColumn"));
220 Item *ci = dynamic_cast<Item *> (cc);
221 end_volta_span_->set_bound (RIGHT, ci);
226 if (volta_span_ && !volta_span_->get_bound (LEFT))
228 Grob *cc = unsmob_grob (get_property ("currentCommandColumn"));
229 Item *ci = dynamic_cast<Item *> (cc);
230 volta_span_->set_bound (LEFT, ci);
235 TODO: should attach volta to paper-column if no bar is found.
237 ADD_ACKNOWLEDGER(Volta_engraver, staff_symbol);
238 ADD_ACKNOWLEDGER(Volta_engraver, note_column);
239 ADD_ACKNOWLEDGER(Volta_engraver, bar_line);
240 ADD_TRANSLATOR (Volta_engraver,
241 /* descr */ "Make volta brackets.",
242 /* creats*/ "VoltaBracket",
245 /* reads */ "repeatCommands voltaSpannerDuration stavesFound",