X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Fdynamic-engraver.cc;h=2a7ca06770857746fce991c63a6c9406b5dafe3e;hb=103b4daf1ba90415029388126ce9f742b9cf62db;hp=7c643490dd245e51f491bf2fb3081d417c2de758;hpb=c52973e438ce3490d688860bb71849a7b3c26fef;p=lilypond.git diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index 7c643490dd..2a7ca06770 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -7,22 +7,15 @@ */ #include "debug.hh" #include "dimensions.hh" -#include "dimension-cache.hh" #include "crescendo.hh" #include "musical-request.hh" -#include "lookup.hh" -#include "paper-def.hh" #include "paper-column.hh" -#include "staff-symbol.hh" #include "note-column.hh" #include "item.hh" #include "side-position-interface.hh" #include "engraver.hh" -#include "stem.hh" -#include "note-head.hh" #include "group-interface.hh" #include "directional-element-interface.hh" -#include "staff-symbol-referencer.hh" #include "translator-group.hh" #include "axis-group-interface.hh" @@ -30,77 +23,37 @@ /* TODO: - * direction of text-dynamic-request if not equalt to direction - of line-spanner - - * FIXME: this has gotten a bit too hairy. - */ - -class Dynamic_line_spanner : public Spanner -{ -public: - Dynamic_line_spanner (SCM); - VIRTUAL_COPY_CONS(Score_element); - void add_column (Note_column*); - void add_element (Score_element*); -}; - -Dynamic_line_spanner::Dynamic_line_spanner (SCM s) - : Spanner (s) -{ - Side_position_interface (this).set_axis (Y_AXIS); - Axis_group_interface (this).set_interface (); - Axis_group_interface (this).set_axes (X_AXIS, Y_AXIS); -} - -void -Dynamic_line_spanner::add_column (Note_column* n) -{ - if (!get_bound (LEFT)) - set_bound (LEFT, n); - else - set_bound (RIGHT, n); - - add_dependency (n); -} - - -void -Dynamic_line_spanner::add_element (Score_element* e) -{ - e->set_parent (this, Y_AXIS); - Axis_group_interface (this).add_element (e); -} + * direction of text-dynamic-request if not equal to direction of + line-spanner +*/ /** print text & hairpin dynamics. */ class Dynamic_engraver : public Engraver { - Item * text_p_; - Crescendo * finished_cresc_p_; - Crescendo * cresc_p_; + Item * script_p_; + Spanner * finished_cresc_p_; + Spanner * cresc_p_; - Text_script_req* text_req_l_; - Span_req * span_start_req_l_; - Drul_array span_req_l_drul_; + Dynamic_script_req* script_req_l_; + + Span_req * current_cresc_req_; + Drul_array accepted_spanreqs_drul_; - Dynamic_line_spanner* line_spanner_; - Dynamic_line_spanner* finished_line_spanner_; - Moment last_request_mom_; + Spanner* line_spanner_; + Spanner* finished_line_spanner_; - Array pending_column_arr_; + Link_array pending_column_arr_; Link_array pending_element_arr_; - void typeset_all (); + void typeset_all (); public: VIRTUAL_COPY_CONS(Translator); Dynamic_engraver (); protected: - void announce_element (Score_element_info); - virtual void do_removal_processing (); virtual void acknowledge_element (Score_element_info); virtual bool do_try_music (Music *req_l); @@ -111,54 +64,54 @@ protected: ADD_THIS_TRANSLATOR (Dynamic_engraver); -void -Dynamic_engraver::announce_element (Score_element_info i) -{ - Group_interface (i.elem_l_, "interfaces").add_thing (ly_symbol2scm ("dynamic")); - - Engraver::announce_element (i); -} - Dynamic_engraver::Dynamic_engraver () { - text_p_ = 0; + script_p_ = 0; finished_cresc_p_ = 0; line_spanner_ = 0; finished_line_spanner_ = 0; - span_start_req_l_ = 0; + current_cresc_req_ = 0; cresc_p_ =0; - text_req_l_ = 0; - span_req_l_drul_[START] = 0; - span_req_l_drul_[STOP] = 0; + script_req_l_ = 0; + accepted_spanreqs_drul_[START] = 0; + accepted_spanreqs_drul_[STOP] = 0; } void Dynamic_engraver::do_post_move_processing () { - text_req_l_ = 0; - span_req_l_drul_[START] = 0; - span_req_l_drul_[STOP] = 0; + script_req_l_ = 0; + accepted_spanreqs_drul_[START] = 0; + accepted_spanreqs_drul_[STOP] = 0; } bool Dynamic_engraver::do_try_music (Music * m) { - if (Text_script_req* d = dynamic_cast (m)) + if (Dynamic_script_req* d = dynamic_cast (m)) { - if (d->style_str_ == "dynamic") - { - text_req_l_ = d; - return true; - } + script_req_l_ = d; + return true; } else if (Span_req* s = dynamic_cast (m)) { - if ((s->span_type_str_ == "crescendo" + if (s->span_type_str_ == "abort") + { + accepted_spanreqs_drul_[LEFT] = 0; + accepted_spanreqs_drul_[RIGHT] = 0; + if (line_spanner_) + line_spanner_->suicide (); + line_spanner_ = 0; + if (cresc_p_) + cresc_p_->suicide (); + cresc_p_ = 0; + } + else if ((s->span_type_str_ == "crescendo" || s->span_type_str_ == "decrescendo")) { - span_req_l_drul_[s->span_dir_] = s; + accepted_spanreqs_drul_[s->span_dir_] = s; return true; } } @@ -168,39 +121,41 @@ Dynamic_engraver::do_try_music (Music * m) void Dynamic_engraver::do_process_music () { - if ((span_req_l_drul_[START] || span_req_l_drul_[STOP] || text_req_l_) - && !line_spanner_ - && pending_element_arr_.size ()) + if (accepted_spanreqs_drul_[START] || accepted_spanreqs_drul_[STOP] || script_req_l_) + { - line_spanner_ = new Dynamic_line_spanner (get_property ("basicDynamicLineSpannerProperties")); - for (int i = 0; i < pending_column_arr_.size (); i++) - line_spanner_->add_column (pending_column_arr_[i]); - pending_column_arr_.clear (); - announce_element (Score_element_info - (line_spanner_, - text_req_l_ ? text_req_l_ : span_req_l_drul_[START])); + if (!line_spanner_) + { + line_spanner_ = new Spanner (get_property ("DynamicLineSpanner")); - } + Side_position::set_axis (line_spanner_, Y_AXIS); + Axis_group_interface::set_interface (line_spanner_); + Axis_group_interface::set_axes (line_spanner_, Y_AXIS, Y_AXIS); - if (line_spanner_ && pending_element_arr_.size ()) - { - for (int i = 0; i < pending_element_arr_.size (); i++) - line_spanner_->add_element (pending_element_arr_[i]); - pending_element_arr_.clear (); + Request * rq = accepted_spanreqs_drul_[START]; + if (script_req_l_) rq = script_req_l_ ; + announce_element (line_spanner_, rq); + + + } } /* - TODO: This should be optionised: - * break when group of dynamic requests ends - * break now (only if no cresc. in progress) - * continue through piece */ - if (span_req_l_drul_[START] || span_req_l_drul_[STOP] || text_req_l_) + finish side position alignment if the (de)cresc ends here, and + there are no new dynamics. + + */ + else if (accepted_spanreqs_drul_[STOP] + && !accepted_spanreqs_drul_[START] && !script_req_l_) { - last_request_mom_ = now_mom (); + finished_line_spanner_ = line_spanner_; + line_spanner_ = 0; } - else - { - /* + + /* + todo: resurrect dynamic{direction, padding,minimumspace} + */ + /* During a (de)crescendo, pending request will not be cleared, and a line-spanner will always be created, as \< \! are already two requests. @@ -208,7 +163,7 @@ Dynamic_engraver::do_process_music () Maybe always creating a line-spanner for a (de)crescendo (see below) is not a good idea: - a\< b\p \!c + a\< b\p \!c the \p will be centred on the line-spanner, and thus clash with the hairpin. When axis-group code is in place, the \p @@ -216,152 +171,105 @@ Dynamic_engraver::do_process_music () Urg, but line-spanner must always have at least same duration as (de)crecsendo, b.o. line-breaking. - */ - if (now_mom () > last_request_mom_ && !span_start_req_l_) - { - for (int i = 0; i < pending_element_arr_.size (); i++) - { - Score_element* e = pending_element_arr_[i]; - Side_position_interface (e).set_axis (Y_AXIS); - Side_position_interface (e).add_staff_support (); - - /* - UGH UGH - */ - Direction d = directional_element (e).get (); - if (!d) - { - SCM s = get_property ("dynamicDirection"); - if (!isdir_b (s)) - s = get_property ("verticalDirection"); - if (isdir_b (s)) - d = to_dir (s); - directional_element (e).set (d); - } - - SCM s = get_property ("dynamicPadding"); - if (gh_number_p (s)) - e->set_elt_property ("padding", s); - s = get_property ("dynamicMinimumSpace"); - if (gh_number_p (s)) - e->set_elt_property ("minimum-space", s); - } - pending_element_arr_.clear (); - if (line_spanner_) - { - for (int i = 0; i < pending_column_arr_.size (); i++) - line_spanner_->add_column (pending_column_arr_[i]); - pending_column_arr_.clear (); - finished_line_spanner_ = line_spanner_; - line_spanner_ = 0; - } - } - } + */ - if (text_req_l_) + + + /* + maybe we should leave dynamic texts to the text-engraver and + simply acknowledge them? + */ + if (script_req_l_) { - String loud = text_req_l_->text_str_; + script_p_ = new Item (get_property ("DynamicText")); + script_p_->set_elt_property ("text", script_req_l_->text_); + if (Direction d = script_req_l_->get_direction ()) + Directional_element_interface::set (line_spanner_, d); - text_p_ = new Item (get_property ("basicDynamicTextProperties")); - text_p_->set_elt_property ("text", ly_str02scm (loud.ch_C ())); - if (Direction d=text_req_l_->get_direction ()) - directional_element (text_p_).set (d); - pending_element_arr_.push (text_p_); + Axis_group_interface::add_element (line_spanner_, script_p_); - text_p_->add_offset_callback (Side_position_interface::aligned_on_self, - Y_AXIS); - announce_element (Score_element_info (text_p_, text_req_l_)); + announce_element (script_p_, script_req_l_); } - if (span_req_l_drul_[STOP]) + if (accepted_spanreqs_drul_[STOP]) { if (!cresc_p_) { - span_req_l_drul_[STOP]->warning + accepted_spanreqs_drul_[STOP]->origin ()->warning (_ ("can't find start of (de)crescendo")); } else { assert (!finished_cresc_p_); - cresc_p_->set_bound (RIGHT, get_staff_info ().musical_pcol_l ()); + Score_element* cc = unsmob_element (get_property ("currentMusicalColumn")); + + cresc_p_->set_bound (RIGHT, cc); + finished_cresc_p_ = cresc_p_; cresc_p_ = 0; - span_start_req_l_ = 0; + current_cresc_req_ = 0; } } - if (span_req_l_drul_[START]) + if (accepted_spanreqs_drul_[START]) { - if (span_start_req_l_) + if (current_cresc_req_) { - span_req_l_drul_[START]->warning - (span_start_req_l_->span_dir_ == 1 - ? - _ ("already have a crescendo") + accepted_spanreqs_drul_[START]->origin ()->warning + (current_cresc_req_->span_dir_ == 1 + ? _ ("already have a crescendo") : _ ("already have a decrescendo")); } else { - span_start_req_l_ = span_req_l_drul_[START]; - cresc_p_ = new Crescendo (get_property ("basicCrescendoProperties")); - cresc_p_->set_elt_property - ("grow-direction", - gh_int2scm ((span_req_l_drul_[START]->span_type_str_ == "crescendo") - ? BIGGER : SMALLER)); - - SCM s = get_property ((span_req_l_drul_[START]->span_type_str_ + "Text").ch_C()); - if (gh_string_p (s)) - { - cresc_p_->set_elt_property ("start-text", s); - daddy_trans_l_->set_property (span_req_l_drul_[START]->span_type_str_ - + "Text", SCM_UNDEFINED); - } - - s = get_property ((span_req_l_drul_[START]->span_type_str_ + "Spanner").ch_C()); - + current_cresc_req_ = accepted_spanreqs_drul_[START]; /* TODO: Use symbols. */ - if (gh_string_p (s)) //&& ly_scm2string (s) != "hairpin") + SCM s = get_property ((accepted_spanreqs_drul_[START]->span_type_str_ + "Spanner").ch_C()); + + if (!gh_string_p (s) || ly_scm2string (s) == "hairpin") + { + cresc_p_ = new Spanner (get_property ("Crescendo")); + cresc_p_->set_elt_property ("grow-direction", + gh_int2scm ((accepted_spanreqs_drul_[START]->span_type_str_ == "crescendo") + ? BIGGER : SMALLER)); + + } + /* + This is a convenient (and legacy) interface to TextSpanners + for use in (de)crescendi. + Hmm. + */ + else { - cresc_p_->set_elt_property ("spanner", s); - daddy_trans_l_->set_property (span_req_l_drul_[START]->span_type_str_ + cresc_p_ = new Spanner (get_property ("TextSpanner")); + cresc_p_->set_elt_property ("type", s); + daddy_trans_l_->set_property (accepted_spanreqs_drul_[START]->span_type_str_ + "Spanner", SCM_UNDEFINED); + s = get_property ((accepted_spanreqs_drul_[START]->span_type_str_ + "Text").ch_C()); + if (gh_string_p (s)) + { + cresc_p_->set_elt_property ("edge-text", + gh_cons (s, ly_str02scm (""))); + daddy_trans_l_->set_property (accepted_spanreqs_drul_[START]->span_type_str_ + + "Text", SCM_UNDEFINED); + } } + + Score_element *cc = unsmob_element (get_property ("currentMusicalColumn")); + cresc_p_->set_bound (LEFT, cc); - cresc_p_->set_bound (LEFT, get_staff_info ().musical_pcol_l ()); - - - /* - We know how wide the text is, if we can be sure that the - text already has relevant pointers into the paperdef, - and it has its font-size property set. - - Since font-size may be set by a context higher up, we - can not be sure of the size. - - - We shouldn't try to do this stuff here, the Item should - do it when the score is finished. We could maybe - set a callback to have the Item do the alignment if - it is not a special symbol, like Crescendo. - */ - - - if (text_p_) + if (script_p_) { - index_set_cell (cresc_p_->get_elt_property ("dynamic-drul"), - LEFT, SCM_BOOL_T); - if (finished_cresc_p_) - index_set_cell (finished_cresc_p_->get_elt_property ("dynamic-drul"), - RIGHT, SCM_BOOL_T); + Side_position::set_direction (script_p_, LEFT); + Side_position::set_axis (script_p_, X_AXIS); + Side_position::add_support (script_p_, cresc_p_); } - pending_element_arr_.push (cresc_p_); - cresc_p_->set_elt_property ("self-alignment-Y", gh_int2scm (0)); - cresc_p_->add_offset_callback - (Side_position_interface::aligned_on_self, Y_AXIS); - announce_element (Score_element_info (cresc_p_, span_req_l_drul_[START])); + + Axis_group_interface::add_element (line_spanner_, cresc_p_); + announce_element (cresc_p_, accepted_spanreqs_drul_[START]); } } } @@ -375,18 +283,18 @@ Dynamic_engraver::do_pre_move_processing () void Dynamic_engraver::do_removal_processing () { - if (cresc_p_) - { - typeset_element (cresc_p_ ); - span_start_req_l_->warning (_ ("unterminated (de)crescendo")); - cresc_p_ =0; - } typeset_all (); if (line_spanner_) { - Side_position_interface (line_spanner_).add_staff_support (); - typeset_element (line_spanner_); - line_spanner_ = 0; + finished_line_spanner_ = line_spanner_; + typeset_all (); + } + + if (cresc_p_) + { + current_cresc_req_->origin ()->warning (_ ("unterminated (de)crescendo")); + cresc_p_->suicide (); + cresc_p_ = 0; } } @@ -399,14 +307,15 @@ Dynamic_engraver::typeset_all () finished_cresc_p_ =0; } - if (text_p_) + if (script_p_) { - typeset_element (text_p_); - text_p_ = 0; + typeset_element (script_p_); + script_p_ = 0; } if (finished_line_spanner_) { - Side_position_interface (finished_line_spanner_).add_staff_support (); + Side_position::add_staff_support (finished_line_spanner_); + extend_spanner_over_elements (finished_line_spanner_); typeset_element (finished_line_spanner_); finished_line_spanner_ = 0; } @@ -415,16 +324,12 @@ Dynamic_engraver::typeset_all () void Dynamic_engraver::acknowledge_element (Score_element_info i) { - if (Note_column* n = dynamic_cast (i.elem_l_)) + if (Note_column::has_interface (i.elem_l_)) { if (line_spanner_) { - Side_position_interface (line_spanner_).add_support (n); - line_spanner_->add_column (n); - } - else - { - pending_column_arr_.push (n); + Side_position::add_support (line_spanner_,i.elem_l_); + add_bound_item (line_spanner_,dynamic_cast(i.elem_l_)); } } }