X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fvolta-engraver.cc;h=03e940650d32e43ac20ee09c4758b4a255b9e60b;hb=32cdc3e2bc738e82c0965bdc5d8d99830e929092;hp=d53dbbedd7d8c8cfe6bb21f46d3a201c128c0bfa;hpb=df4a7c4a55148e065d878dcc2f7e09ac27ea9c32;p=lilypond.git diff --git a/lily/volta-engraver.cc b/lily/volta-engraver.cc index d53dbbedd7..03e940650d 100644 --- a/lily/volta-engraver.cc +++ b/lily/volta-engraver.cc @@ -1,190 +1,240 @@ -/* - volta-engraver.cc -- implement Volta_engraver - +/* + volta-engraver.cc -- implement Volta_engraver + source file of the GNU LilyPond music typesetter - - (c) 2000 Han-Wen Nienhuys - - */ + + (c) 2000--2005 Han-Wen Nienhuys +*/ #include "engraver.hh" -#include "translator-group.hh" -#include "volta-spanner.hh" -#include "item.hh" +#include "context.hh" +#include "volta-bracket.hh" #include "note-column.hh" -#include "bar.hh" +#include "bar-line.hh" #include "side-position-interface.hh" +#include "warn.hh" +#include "staff-symbol.hh" /* Create Volta spanners, by reading repeatCommands property, usually set by Unfolded_repeat_iterator. - */ +*/ class Volta_engraver : public Engraver { public: - Volta_engraver(); - VIRTUAL_COPY_CONS(Translator); + TRANSLATOR_DECLARATIONS (Volta_engraver); protected: - virtual void start_translation_timestep (); virtual void acknowledge_grob (Grob_info); - virtual void do_removal_processing (); + virtual void finalize (); virtual void stop_translation_timestep (); - void deprecated_process_music (); - virtual void create_grobs (); - + virtual void process_music (); + Moment started_mom_; - Spanner *volta_span_p_; - Spanner *end_volta_span_p_; + Spanner *volta_span_; + Spanner *end_volta_span_; + SCM staff_; + SCM start_string_; - bool first_b_; + bool staff_eligible (); }; -ADD_THIS_TRANSLATOR(Volta_engraver); - Volta_engraver::Volta_engraver () { - first_b_ = true; - volta_span_p_ = 0; - end_volta_span_p_ = 0; + staff_ = SCM_EOL; + volta_span_ = 0; + end_volta_span_ = 0; } -void -Volta_engraver::create_grobs () +/* + TODO: this logic should be rewritten, it is buggy. + + One of the problems is that we can't determine wether or not to + print the volta bracket during the first step, since that requires + acknowledging the staff. +*/ +bool +Volta_engraver::staff_eligible () { - if (first_b_) + SCM doit = get_property ("voltaOnThisStaff"); + if (scm_is_bool (doit)) { - deprecated_process_music (); - first_b_ = false; + return to_boolean (doit); } + + if (!unsmob_grob (staff_)) + return false; + + /* + TODO: this does weird things when you open a piece with a + volta spanner. + */ + SCM staffs = get_property ("stavesFound"); + + /* Only put a volta on the top staff. + Maybe this is a bit convoluted, and we should have a single + volta engraver in score context or somesuch. */ + if (!scm_is_pair (staffs)) + { + programming_error ("volta engraver can't find staffs"); + return false; + } + else if (scm_car (scm_last_pair (staffs)) != staff_) + return false; + return true; } - + void -Volta_engraver::deprecated_process_music () +Volta_engraver::process_music () { - if (volta_span_p_) - return; SCM cs = get_property ("repeatCommands"); - SCM str = SCM_EOL; + if (!staff_eligible ()) + return; + bool end = false; - while (gh_pair_p (cs)) + start_string_ = SCM_EOL; + while (scm_is_pair (cs)) { - SCM c = gh_car (cs); + SCM c = scm_car (cs); - if (gh_pair_p (c) && gh_car (c) == ly_symbol2scm ("volta")) + if (scm_is_pair (c) + && scm_car (c) == ly_symbol2scm ("volta") + && scm_is_pair (scm_cdr (c))) { - if (gh_cadr (c) == SCM_BOOL_F) + if (scm_cadr (c) == SCM_BOOL_F) end = true; else - str = gh_cadr (c); + start_string_ = scm_cadr (c); } - - cs = gh_cdr (cs); - } - SCM l (get_property ("voltaSpannerDuration")); - Moment now = now_mom (); - - bool early_stop = volta_span_p_ && unsmob_moment (l) - &&*unsmob_moment (l) <= now - started_mom_; - - if (end && !volta_span_p_) - { - warning (_("No volta spanner to end")); // fixme: be more verbose. + cs = scm_cdr (cs); } - else if (end || early_stop) + + if (volta_span_) { - end_volta_span_p_ = volta_span_p_; - volta_span_p_ =0; + SCM l (get_property ("voltaSpannerDuration")); + Moment now = now_mom (); - /* - maybe do typeset_grob () directly? - */ + bool early_stop = unsmob_moment (l) + && *unsmob_moment (l) <= now - started_mom_; - if (!gh_string_p (str)) - end_volta_span_p_->set_grob_property ("last-volta", SCM_BOOL_T); + end = end || early_stop; } - if (gh_string_p (str)) + if (end && !volta_span_) + /* fixme: be more verbose. */ + warning (_ ("can't end volta spanner")); + else if (end) { - started_mom_ = now; - if (volta_span_p_) - { - warning (_ ("Already have a volta spanner. Stopping that one prematurely.")); + end_volta_span_ = volta_span_; + volta_span_ = 0; + } - if (end_volta_span_p_) - { - warning (_("Also have a stopped spanner. Giving up.")); + if (volta_span_ + && (scm_is_string (start_string_) || scm_is_pair (start_string_))) + { + warning (_ ("already have a volta spanner, ending that one prematurely")); - return ; + if (end_volta_span_) + { + warning (_ ("also already have an ended spanner")); + warning (_ ("giving up")); + return; + } - } + end_volta_span_ = volta_span_; + volta_span_ = 0; + } - end_volta_span_p_ = volta_span_p_; - volta_span_p_ = 0; - } + if (!volta_span_ + && (scm_is_string (start_string_) || scm_is_pair (start_string_))) + { + started_mom_ = now_mom (); - volta_span_p_ = new Spanner (get_property ("VoltaBracket")); - Volta_spanner::set_interface (volta_span_p_); - announce_grob (volta_span_p_,0); - volta_span_p_->set_grob_property ("text", str); + volta_span_ = make_spanner ("VoltaBracket", SCM_EOL); + + volta_span_->set_property ("text", start_string_); } } void Volta_engraver::acknowledge_grob (Grob_info i) { - if (Item* item = dynamic_cast (i.elem_l_)) + if (Item *item = dynamic_cast (i.grob ())) { if (Note_column::has_interface (item)) { - if (volta_span_p_) - Volta_spanner::add_column (volta_span_p_,item); - if (end_volta_span_p_) - Volta_spanner::add_column (end_volta_span_p_,item); + if (volta_span_) + Volta_bracket_interface::add_column (volta_span_, item); } - if (Bar::has_interface (item)) + if (Bar_line::has_interface (item)) { - if (volta_span_p_) - Volta_spanner::add_bar (volta_span_p_, item); - if (end_volta_span_p_) - Volta_spanner::add_bar(end_volta_span_p_ , item); + if (volta_span_) + Volta_bracket_interface::add_bar (volta_span_, item); + if (end_volta_span_) + Volta_bracket_interface::add_bar (end_volta_span_, item); } } -} - -void -Volta_engraver::do_removal_processing () -{ - if (volta_span_p_) - { - typeset_grob(volta_span_p_); - } - if (end_volta_span_p_) + else if (Staff_symbol::has_interface (i.grob ())) { - typeset_grob (end_volta_span_p_); + /* + We only want to know about a single staff: then we add to the + support. */ + if (staff_ != SCM_EOL) + staff_ = SCM_UNDEFINED; + + if (staff_ != SCM_UNDEFINED) + staff_ = i.grob ()->self_scm (); } } void -Volta_engraver::start_translation_timestep () +Volta_engraver::finalize () { - first_b_ = true; } -void +void Volta_engraver::stop_translation_timestep () { - if (end_volta_span_p_) + if (volta_span_ && !staff_eligible ()) + { + /* + THIS IS A KLUDGE. + + we need to do this here, because STAFF_ is not initialized yet + in the 1st call of process_music () + */ + + volta_span_->suicide (); + volta_span_ = 0; + } + + if (end_volta_span_ && !end_volta_span_->get_bound (RIGHT)) + { + Grob *cc = unsmob_grob (get_property ("currentCommandColumn")); + Item *ci = dynamic_cast (cc); + end_volta_span_->set_bound (RIGHT, ci); + } + + end_volta_span_ = 0; + + if (volta_span_ && !volta_span_->get_bound (LEFT)) { - Side_position::add_staff_support (end_volta_span_p_); - - typeset_grob (end_volta_span_p_ ); - end_volta_span_p_ =0; + Grob *cc = unsmob_grob (get_property ("currentCommandColumn")); + Item *ci = dynamic_cast (cc); + volta_span_->set_bound (LEFT, ci); } } /* TODO: should attach volta to paper-column if no bar is found. - */ +*/ + +ADD_TRANSLATOR (Volta_engraver, + /* descr */ "Make volta brackets.", + /* creats*/ "VoltaBracket", + /* accepts */ "", + /* acks */ "bar-line-interface staff-symbol-interface note-column-interface", + /* reads */ "repeatCommands voltaSpannerDuration stavesFound", + /* write */ "");