X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fmulti-measure-rest-engraver.cc;h=552865111bdd9c3073a09fd84827b1d196354e3f;hb=7181c77e5d46a271f5f76e99bee7f844611e23e4;hp=e8b23b67b39a2ba516ef6f0ecbbc863334af7c25;hpb=1cf3d59c1559fb9774c4c1c8cae155cfe54a927c;p=lilypond.git diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc index e8b23b67b3..552865111b 100644 --- a/lily/multi-measure-rest-engraver.cc +++ b/lily/multi-measure-rest-engraver.cc @@ -1,82 +1,181 @@ /* multi_measure_rest-engraver.cc -- implement Multi_measure_rest_engraver - (c) 1998 Jan Nieuwenhuizen + (c) 1998--2000 Jan Nieuwenhuizen Han-Wen Nienhuys */ -#include "proto.hh" #include "musical-request.hh" #include "multi-measure-rest.hh" -#include "multi-measure-rest-engraver.hh" -#include "score-column.hh" -#include "time-description.hh" +#include "paper-column.hh" +#include "engraver-group-engraver.hh" +#include "bar.hh" +#include "staff-symbol-referencer.hh" +#include "engraver.hh" +#include "moment.hh" +#include "spanner.hh" + +/** + The name says it all: make multi measure rests + +FIXME? The MM rest engraver must be able to see bar lines, so it won't +work at Voice level. Not a problem in practice, but aesthetically pleasing? + +*/ +class Multi_measure_rest_engraver : public Engraver +{ +public: + VIRTUAL_COPY_CONS(Translator); + Multi_measure_rest_engraver (); + +protected: + virtual void acknowledge_element (Score_element_info i); + virtual void do_process_music (); + virtual bool do_try_music (Music*); + virtual void do_pre_move_processing (); + virtual void do_post_move_processing (); + virtual void do_removal_processing (); +private: + Span_req * new_req_l_; + Span_req * busy_span_req_l_; + Span_req * stop_req_l_; + int start_measure_i_; + Moment start_moment_; + + Spanner *mmrest_p_; + Spanner *lastrest_p_; +}; -IMPLEMENT_IS_TYPE_B1 (Multi_measure_rest_engraver, Engraver); ADD_THIS_TRANSLATOR (Multi_measure_rest_engraver); Multi_measure_rest_engraver::Multi_measure_rest_engraver () { start_measure_i_ = 0; - rest_item_creation_mom_ = rest_req_stop_mom_ =0; - multi_measure_req_l_ = 0; - mmrest_p_ = 0; + mmrest_p_ = lastrest_p_ =0; + new_req_l_ = busy_span_req_l_ = stop_req_l_ =0; +} + +void +Multi_measure_rest_engraver::acknowledge_element (Score_element_info i) +{ + Item * item = dynamic_cast (i.elem_l_); + if (item && Bar::has_interface (item)) + { + if (mmrest_p_) + Multi_measure_rest::add_column (mmrest_p_,item); + if (lastrest_p_) + Multi_measure_rest::add_column (lastrest_p_,item); + } } bool -Multi_measure_rest_engraver::do_try_request (Request* req_l) +Multi_measure_rest_engraver::do_try_music (Music* req_l) { - if (!req_l->access_Musical_req () || !req_l->access_Musical_req ()->access_Multi_measure_rest_req ()) - return false; + if (Span_req * sp = dynamic_cast (req_l)) + { + if (sp->span_type_str_ == "rest") + { + if (sp->span_dir_ == STOP) + { + stop_req_l_ = sp; + } + else if (sp->span_dir_ == START && !new_req_l_) + { + new_req_l_ = sp; + } + return true; + } + } + return false; +} - if (multi_measure_req_l_) - if (!multi_measure_req_l_->equal_b (req_l) - || req_start_mom_ != now_moment ()) - return false; - - multi_measure_req_l_ = req_l->access_Musical_req ()->access_Multi_measure_rest_req (); - req_start_mom_ = now_moment (); - - rest_req_stop_mom_ = req_start_mom_ + multi_measure_req_l_->duration_.length (); - return true; -} void -Multi_measure_rest_engraver::do_process_requests () +Multi_measure_rest_engraver::do_process_music () { - if (multi_measure_req_l_ && !mmrest_p_) + if (new_req_l_ && stop_req_l_) + stop_req_l_ = 0; + + if (new_req_l_) + start_moment_ = now_mom (); + + if (stop_req_l_) { - Time_description const *time = get_staff_info().time_C_; - mmrest_p_ = new Multi_measure_rest; - rest_item_creation_mom_ = time->when_mom (); - announce_element (Score_element_info (mmrest_p_, multi_measure_req_l_)); - start_measure_i_ = time->bars_i_; + busy_span_req_l_ =0; + stop_req_l_ = 0; + } + + if (new_req_l_) + { + busy_span_req_l_ = new_req_l_; + new_req_l_ =0; + } + + if (busy_span_req_l_ && !mmrest_p_) + { + mmrest_p_ = new Spanner (get_property ("basicMultiMeasureRestProperties")); + + Multi_measure_rest::set_interface (mmrest_p_); + Staff_symbol_referencer::set_interface (mmrest_p_); + + announce_element (mmrest_p_, busy_span_req_l_); + start_measure_i_ + = gh_scm2int (get_property ("currentBarNumber")); } } void Multi_measure_rest_engraver::do_pre_move_processing () { - Moment now (now_moment ()); - if (mmrest_p_ && rest_item_creation_mom_ == now) + SCM smp = get_property ("measurePosition"); + Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); + + if (mmrest_p_ && (now_mom () >= start_moment_) + && !mp + && (scm_ilength (mmrest_p_->get_elt_property ("columns")) >= 2)) { typeset_element (mmrest_p_); + /* + must keep mmrest_p_ around to set measures_i_ + */ } + if (lastrest_p_) + { + typeset_element (lastrest_p_); + lastrest_p_ = 0; + } + + if (new_req_l_) + { + busy_span_req_l_ = new_req_l_; + new_req_l_ =0; + } + } void Multi_measure_rest_engraver::do_post_move_processing () { - Time_description const *time = get_staff_info().time_C_; - Moment now (now_moment ()); - if (rest_req_stop_mom_ <= now) - multi_measure_req_l_ = 0; - - if (mmrest_p_ && (!time->whole_in_measure_ || !multi_measure_req_l_)) + SCM smp = get_property ("measurePosition"); + Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); + + if (mmrest_p_ && !mp) { - assert (rest_item_creation_mom_ < now); - mmrest_p_->measures_i_ = time->bars_i_ - start_measure_i_; + lastrest_p_ = mmrest_p_; + int cur = gh_scm2int (get_property ("currentBarNumber")); + lastrest_p_->set_elt_property ("measure-count", + gh_int2scm (cur - start_measure_i_)); mmrest_p_ = 0; } } + + +void +Multi_measure_rest_engraver::do_removal_processing () +{ + if (mmrest_p_) + typeset_element (mmrest_p_); + if (lastrest_p_) + typeset_element (lastrest_p_); +}