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"
19 Create Volta spanners, by reading repeatCommands property, usually
20 set by Unfolded_repeat_iterator.
22 class Volta_engraver : public Engraver
25 TRANSLATOR_DECLARATIONS (Volta_engraver);
28 virtual void acknowledge_grob (Grob_info);
29 virtual void finalize ();
30 virtual void stop_translation_timestep ();
31 virtual void process_music ();
35 Spanner *end_volta_span_;
39 bool staff_eligible ();
42 Volta_engraver::Volta_engraver ()
50 TODO: this logic should be rewritten, it is buggy.
52 One of the problems is that we can't determine wether or not to
53 print the volta bracket during the first step, since that requires
54 acknowledging the staff.
57 Volta_engraver::staff_eligible ()
59 SCM doit = get_property ("voltaOnThisStaff");
60 if (scm_is_bool (doit))
62 return to_boolean (doit);
65 if (!unsmob_grob (staff_))
69 TODO: this does weird things when you open a piece with a
72 SCM staffs = get_property ("stavesFound");
75 only put a volta on the top staff.
77 May be this is a bit convoluted, and we should have a single
78 volta engraver in score context or somesuch.
81 if (!scm_is_pair (staffs))
83 programming_error ("Huh? Volta engraver can't find staffs?");
86 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_)
133 warning (_ ("No volta spanner to end")); // fixme: be more verbose.
137 end_volta_span_ = volta_span_;
142 && (scm_is_string (start_string_) || scm_is_pair (start_string_)))
144 warning (_ ("Already have a volta spanner. Stopping that one prematurely."));
148 warning (_ ("Also have a stopped spanner. 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_grob (Grob_info i)
170 if (Item *item = dynamic_cast<Item *> (i.grob_))
172 if (Note_column::has_interface (item))
175 Volta_bracket_interface::add_column (volta_span_, item);
177 if (Bar_line::has_interface (item))
180 Volta_bracket_interface::add_bar (volta_span_, item);
182 Volta_bracket_interface::add_bar (end_volta_span_, item);
185 else if (Staff_symbol::has_interface (i.grob_))
188 We only want to know about a single staff: then we add to the
190 if (staff_ != SCM_EOL)
191 staff_ = SCM_UNDEFINED;
193 if (staff_ != SCM_UNDEFINED)
194 staff_ = i.grob_->self_scm ();
199 Volta_engraver::finalize ()
204 Volta_engraver::stop_translation_timestep ()
206 if (volta_span_ && !staff_eligible ())
211 we need to do this here, because STAFF_ is not initialized yet
212 in the 1st call of process_music ()
215 volta_span_->suicide ();
219 if (end_volta_span_ && !end_volta_span_->get_bound (RIGHT))
221 Grob *cc = unsmob_grob (get_property ("currentCommandColumn"));
222 Item *ci = dynamic_cast<Item *> (cc);
223 end_volta_span_->set_bound (RIGHT, ci);
228 if (volta_span_ && !volta_span_->get_bound (LEFT))
230 Grob *cc = unsmob_grob (get_property ("currentCommandColumn"));
231 Item *ci = dynamic_cast<Item *> (cc);
232 volta_span_->set_bound (LEFT, ci);
237 TODO: should attach volta to paper-column if no bar is found.
240 ADD_TRANSLATOR (Volta_engraver,
241 /* descr */ "Make volta brackets.",
242 /* creats*/ "VoltaBracket",
244 /* acks */ "bar-line-interface staff-symbol-interface note-column-interface",
245 /* reads */ "repeatCommands voltaSpannerDuration stavesFound",