X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fa2-engraver.cc;h=ec3ecf9161f98607f23011340a8a6520fe7f42ef;hb=52aa2e58ed0912a474c94284e5f7a1cc8f9b6612;hp=76b6e6926422b055eacc1f62a3d502aabf1e366d;hpb=038d4f3968d1589e5438538fb8d704f007eb4908;p=lilypond.git diff --git a/lily/a2-engraver.cc b/lily/a2-engraver.cc index 76b6e69264..ec3ecf9161 100644 --- a/lily/a2-engraver.cc +++ b/lily/a2-engraver.cc @@ -3,152 +3,215 @@ source file of the GNU LilyPond music typesetter - (c) 2000 Jan Nieuwenhuizen + (c) 2000--2002 Jan Nieuwenhuizen */ #include "engraver.hh" #include "item.hh" #include "note-head.hh" #include "stem.hh" +#include "slur.hh" #include "translator-group.hh" #include "side-position-interface.hh" #include "directional-element-interface.hh" +#include "multi-measure-rest.hh" +#include "tie.hh" class A2_engraver : public Engraver { -public: - A2_engraver (); - VIRTUAL_COPY_CONS (Translator); - -protected: - virtual void do_process_music (); - virtual void acknowledge_element (Score_element_info); - - virtual void do_pre_move_processing (); + TRANSLATOR_DECLARATIONS(A2_engraver); +protected: + virtual void acknowledge_grob (Grob_info); + virtual void process_acknowledged_grobs (); + virtual void stop_translation_timestep (); private: - Item* text_p_; - enum State { NORMAL, UNISON, SOLO } state_; + Item* text_; + enum State { SOLO, SPLIT_INTERVAL, UNIRHYTHM, UNISILENCE, UNISON } state_; }; -ADD_THIS_TRANSLATOR (A2_engraver); -A2_engraver::A2_engraver () -{ - text_p_ = 0; - state_ = NORMAL; -} -void -A2_engraver::do_process_music () +A2_engraver::A2_engraver () { + text_ = 0; + state_ = UNISILENCE; } - void -A2_engraver::acknowledge_element (Score_element_info i) +A2_engraver::process_acknowledged_grobs () { - if (!text_p_) + if (!to_boolean (get_property ("combineParts"))) + return ; + if (!text_) { SCM unison = get_property ("unison"); SCM solo = get_property ("solo"); + SCM solo_adue = get_property ("soloADue"); - if ((solo == SCM_BOOL_T && state_ != SOLO) - || (unison == SCM_BOOL_T && state_ != UNISON)) + if (solo_adue == SCM_BOOL_T + && ((solo == SCM_BOOL_T && state_ != SOLO) + || (unison == SCM_BOOL_T && state_ != UNISON + && daddy_trans_->id_string_.left_string (3) == "one"))) { - text_p_ = new Item (get_property ("basicTextScriptProperties")); - Side_position::set_axis (text_p_, Y_AXIS); - announce_element (text_p_, 0); + text_ = new Item (get_property ("TextScript")); + Side_position_interface::set_axis (text_, Y_AXIS); + announce_grob(text_, SCM_EOL); - /* - Urg, read prop - */ - SCM text; Direction dir = UP; + SCM text = SCM_EOL; if (solo == SCM_BOOL_T) { state_ = SOLO; - if (daddy_trans_l_->id_str_ == "one") - text = ly_str02scm ("Solo"); + if (daddy_trans_->id_string_.left_string (3) == "one") + { + text = get_property ("soloText"); + } else { - text = ly_str02scm ("Solo II"); + text = get_property ("soloIIText"); dir = DOWN; } } else if (unison == SCM_BOOL_T) { - text = ly_str02scm ("\\`a 2"); state_ = UNISON; + if (daddy_trans_->id_string_.left_string (3) == "one") + text = get_property ("aDueText"); } - Side_position::set_direction (text_p_, dir); - text_p_->set_elt_property ("text", text); - + Side_position_interface::set_direction (text_, dir); + text_->set_grob_property ("text", text); } } -#if 0 } void -A2_engraver::acknowledge_element (Score_element_info i) +A2_engraver::acknowledge_grob (Grob_info i) { -#endif - if (text_p_) + if (!to_boolean (get_property ("combineParts"))) + return ; + + if (text_) { - if (Note_head::has_interface (i.elem_l_)) + if (Note_head::has_interface (i.grob_)) { - Score_element*t = text_p_; - Side_position::add_support (t, i.elem_l_); - if (Side_position::get_axis (t) == X_AXIS - && !t->parent_l (Y_AXIS)) - t->set_parent (i.elem_l_, Y_AXIS); + Grob*t = text_; + Side_position_interface::add_support (t, i.grob_); + if (Side_position_interface::get_axis (t) == X_AXIS + && !t->get_parent (Y_AXIS)) + t->set_parent (i.grob_, Y_AXIS); } - if (Stem::has_interface (i.elem_l_)) + if (Stem::has_interface (i.grob_)) { - Side_position::add_support (text_p_, i.elem_l_); + Side_position_interface::add_support (text_, i.grob_); } } - - if (Stem::has_interface (i.elem_l_)) + SCM unisilence = get_property ("unisilence"); + SCM unison = get_property ("unison"); + SCM unirhythm = get_property ("unirhythm"); + SCM solo = get_property ("solo"); + SCM split_interval = get_property ("split-interval"); + SCM solo_adue = get_property ("soloADue"); + + State previous_state = state_; + if (unisilence == SCM_BOOL_T) + /* + state_ = UNISILENCE; + */ + ; + else if (solo == SCM_BOOL_T) + state_ = SOLO; + else if (unison == SCM_BOOL_T) + state_ = UNISON; + else if (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T) + state_ = SPLIT_INTERVAL; + else if (unirhythm) + state_ = UNIRHYTHM; + + Direction d = CENTER; + if (daddy_trans_->id_string_.left_string (3) == "one") + d = UP; + else if (daddy_trans_->id_string_.left_string (3) == "two") + d = DOWN; + + /* Must only set direction for VoiceCombines, not for StaffCombines: + we can't detect that here, so we use yet another property */ + if (!to_boolean (get_property ("noDirection")) + && (Stem::has_interface (i.grob_) + || Slur::has_interface (i.grob_) + || Tie::has_interface (i.grob_) + /* Usually, dynamics are removed by *_devnull_engravers for + the second voice. On the one hand, we don't want all + dynamics for the first voice to be placed above the + staff. On the other hand, colliding of scripts may be + worse. So, we don't set directions for these when we're + playing solo. */ + || (i.grob_->internal_has_interface (ly_symbol2scm + ("dynamic-interface")) + && state_ != SOLO) + || (i.grob_->internal_has_interface (ly_symbol2scm + ("text-interface")) + && state_ != SOLO) + )) { - Item *stem_l = dynamic_cast (i.elem_l_); - - SCM unirhythm = get_property ("unirhythm"); - SCM unison = get_property ("unison"); - SCM solo = get_property ("solo"); - SCM interval = get_property ("interval"); - - /* - This still needs some work. - */ - if ((unirhythm != SCM_BOOL_T && solo != SCM_BOOL_T) - || (unirhythm == SCM_BOOL_T - && gh_number_p (interval) && gh_scm2int (interval) < 3)) + /* When in solo a due mode, and we have solo, every grob in + other thread gets annihilated, so we don't set dir. + + Maybe that should be optional? */ + if ((solo != SCM_BOOL_T && solo_adue == SCM_BOOL_T) + + /* When not same rhythm, we set dir */ + && (unirhythm != SCM_BOOL_T + /* When both have rests, but previously played something + different, we set dir */ + || ((unisilence == SCM_BOOL_T && previous_state != UNISON)) + /* When same rhythm, and split stems, but not same pitch + or not solo a du mode, we set dir */ + || (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T + && (unison != SCM_BOOL_T || solo_adue != SCM_BOOL_T)))) { - if (daddy_trans_l_->id_str_ == "one") - { - //Directional_element_interface (stem_l).set (UP); - stem_l->set_elt_property ("direction", gh_int2scm (1)); - } - else if (daddy_trans_l_->id_str_ == "two") - { - //Directional_element_interface (stem_l).set (DOWN); - stem_l->set_elt_property ("direction", gh_int2scm (-1)); - } + + /* Blunt axe method: every grob gets a propertysetting. */ + i.grob_->set_grob_property ("direction", gh_int2scm (d)); } } + + /* Should we have separate state variable for being "rest + while other has solo?" */ + if (Multi_measure_rest::has_interface (i.grob_) && d) + if (state_ == UNIRHYTHM + && unisilence != SCM_BOOL_T) + { + i.grob_->set_grob_property ("staff-position", gh_int2scm (d * 6)); + } } void -A2_engraver::do_pre_move_processing () +A2_engraver::stop_translation_timestep () { - if (text_p_) + if (text_) { - Side_position::add_staff_support (text_p_); - typeset_element (text_p_); - text_p_ = 0; + Side_position_interface::add_staff_support (text_); + typeset_grob (text_); + text_ = 0; } } +ENTER_DESCRIPTION(A2_engraver, +/* descr */ "Part combine engraver for orchestral scores. + +The markings @emph{a2}, @emph{Solo} and @emph{Solo II}, are +created by this engraver. It also acts upon instructions of the part +combiner. Another thing that the this engraver, is forcing of stem, +slur and tie directions, always when both threads are not identical; +up for the musicexpr called @code{one}, down for the musicexpr called +@code{two}. + +", +/* creats*/ "TextScript", +/* acks */ "multi-measure-rest-interface +slur-interface stem-interface tie-interface note-head-interface dynamic-interface text-interface" +,/* reads */ "combineParts noDirection soloADue soloText soloIIText aDueText split-interval unison solo unisilence unirhythm", +/* write */ "");