2 volta-engraver.cc -- implement Volta_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "engraver.hh"
12 #include "volta-bracket.hh"
13 #include "note-column.hh"
14 #include "bar-line.hh"
15 #include "side-position-interface.hh"
17 #include "staff-symbol.hh"
20 Create Volta spanners, by reading repeatCommands property, usually
21 set by Unfolded_repeat_iterator.
23 class Volta_engraver : public Engraver
26 TRANSLATOR_DECLARATIONS (Volta_engraver);
29 virtual void acknowledge_grob (Grob_info);
30 virtual void finalize ();
31 virtual void stop_translation_timestep ();
32 virtual void process_music ();
36 Spanner *end_volta_span_;
40 bool staff_eligible ();
44 Volta_engraver::Volta_engraver ()
53 TODO: this logic should be rewritten, it is buggy.
55 One of the problems is that we can't determine wether or not to
56 print the volta bracket during the first step, since that requires
57 acknowledging the staff.
60 Volta_engraver::staff_eligible ()
62 SCM doit = get_property ("voltaOnThisStaff");
63 if (scm_is_bool (doit))
65 return to_boolean (doit);
69 if (!unsmob_grob (staff_))
73 TODO: this does weird things when you open a piece with a
76 SCM staffs = get_property ("stavesFound");
79 only put a volta on the top staff.
81 May be this is a bit convoluted, and we should have a single
82 volta engraver in score context or somesuch.
85 if (!scm_is_pair (staffs))
87 programming_error ("Huh? Volta engraver can't find staffs?");
90 else if (scm_car (scm_last_pair (staffs)) != staff_)
99 Volta_engraver::process_music ()
101 SCM cs = get_property ("repeatCommands");
103 if (!staff_eligible ())
108 start_string_ = SCM_EOL;
109 while (scm_is_pair (cs))
111 SCM c = scm_car (cs);
114 && scm_car (c) == ly_symbol2scm ("volta")
115 && scm_is_pair (scm_cdr (c)))
117 if (scm_cadr (c) == SCM_BOOL_F)
120 start_string_ = scm_cadr (c);
128 SCM l (get_property ("voltaSpannerDuration"));
129 Moment now = now_mom ();
131 bool early_stop = unsmob_moment (l)
132 && *unsmob_moment (l) <= now - started_mom_;
134 end = end || early_stop;
138 if (end && !volta_span_)
140 warning (_ ("No volta spanner to end")); // fixme: be more verbose.
144 end_volta_span_ = volta_span_;
149 (scm_is_string (start_string_) || scm_is_pair (start_string_)))
151 warning (_ ("Already have a volta spanner. Stopping that one prematurely."));
155 warning (_ ("Also have a stopped spanner. Giving up."));
159 end_volta_span_ = volta_span_;
164 (scm_is_string (start_string_) || scm_is_pair (start_string_)))
166 started_mom_ = now_mom () ;
168 volta_span_ = make_spanner ("VoltaBracket", SCM_EOL);
171 volta_span_->set_property ("text", start_string_);
177 Volta_engraver::acknowledge_grob (Grob_info i)
179 if (Item* item = dynamic_cast<Item*> (i.grob_))
181 if (Note_column::has_interface (item))
184 Volta_bracket_interface::add_column (volta_span_,item);
186 if (Bar_line::has_interface (item))
189 Volta_bracket_interface::add_bar (volta_span_, item);
191 Volta_bracket_interface::add_bar (end_volta_span_ , item);
194 else if (Staff_symbol::has_interface (i.grob_))
197 We only want to know about a single staff: then we add to the
199 if (staff_ != SCM_EOL)
200 staff_ = SCM_UNDEFINED;
202 if (staff_ != SCM_UNDEFINED)
203 staff_ = i.grob_->self_scm ();
208 Volta_engraver::finalize ()
215 Volta_engraver::stop_translation_timestep ()
217 if (volta_span_ && !staff_eligible ())
222 we need to do this here, because STAFF_ is not initialized yet
223 in the 1st call of process_music ()
226 volta_span_->suicide ( );
230 if (end_volta_span_ && !end_volta_span_->get_bound (RIGHT))
232 Grob * cc = unsmob_grob (get_property ("currentCommandColumn"));
233 Item * ci = dynamic_cast<Item*> (cc);
234 end_volta_span_->set_bound (RIGHT, ci);
239 if (volta_span_ && !volta_span_->get_bound (LEFT))
241 Grob * cc = unsmob_grob (get_property ("currentCommandColumn"));
242 Item * ci = dynamic_cast<Item*> (cc);
243 volta_span_->set_bound (LEFT, ci);
249 TODO: should attach volta to paper-column if no bar is found.
252 ADD_TRANSLATOR (Volta_engraver,
253 /* descr */ "Make volta brackets.",
254 /* creats*/ "VoltaBracket",
256 /* acks */ "bar-line-interface staff-symbol-interface note-column-interface",
257 /* reads */ "repeatCommands voltaSpannerDuration stavesFound",