X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbeam-engraver.cc;h=29c50059745a6ec0127ab27ac8ef1b72ae8d3c42;hb=c5402461ab1d1cdbaa684b0e55d4851f0e28e37a;hp=b1ec28d01d134207ce929601cda2bac7d82d2d29;hpb=615a9212789c2cb2994748c023d0e19f3a83a0fd;p=lilypond.git diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index b1ec28d01d..29c5005974 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -1,135 +1,282 @@ -/* - beam-grav.cc -- implement Beam_engraver - +/* + beam-engraver.cc -- implement Beam_engraver + source file of the GNU LilyPond music typesetter - - (c) 1997--1998 Han-Wen Nienhuys -*/ -#include "duration-convert.hh" -#include "time-description.hh" -#include "beam-engraver.hh" -#include "stem.hh" -#include "beam.hh" + + (c) 1998--2000 Han-Wen Nienhuys + + */ +#include "engraver-group-engraver.hh" +#include "engraver.hh" #include "musical-request.hh" -#include "grouping.hh" -#include "p-col.hh" +#include "beam.hh" +#include "stem.hh" #include "warn.hh" +#include "beaming.hh" +#include "score-engraver.hh" +#include "rest.hh" +#include "drul-array.hh" +#include "item.hh" +#include "spanner.hh" + +class Beam_engraver : public Engraver +{ + Drul_array reqs_drul_; + + Spanner *finished_beam_p_; + Spanner *beam_p_; + Span_req * prev_start_req_; + + Beaming_info_list * beam_info_p_; + Beaming_info_list * finished_beam_info_p_; + + /// location within measure where beam started. + Moment beam_start_location_; -Beam_engraver::Beam_engraver() + /// moment (global time) where beam started. + Moment beam_start_mom_; + + void typeset_beam (); + void set_melisma (bool); +protected: + virtual void do_pre_move_processing (); + virtual void do_post_move_processing (); + virtual void do_removal_processing (); + virtual void acknowledge_element (Score_element_info); + virtual bool do_try_music (Music*); + virtual void do_process_music (); +public: + Beam_engraver (); + VIRTUAL_COPY_CONS (Translator); +}; + + +Beam_engraver::Beam_engraver () { - span_reqs_drul_[LEFT] = span_reqs_drul_[RIGHT] =0; - beam_p_ =0; - current_grouping_p_ =0; + beam_p_ = 0; + finished_beam_p_ =0; + finished_beam_info_p_=0; + beam_info_p_ =0; + reqs_drul_[LEFT] = reqs_drul_[RIGHT] =0; + prev_start_req_ =0; } bool -Beam_engraver::do_try_music (Music*r) +Beam_engraver::do_try_music (Music *m) { - Beam_req* b = dynamic_cast (r); - if (!b) - return false; + if (Span_req * c = dynamic_cast(m)) + { + if (c->span_type_str_ == "abort") + { + reqs_drul_[START] = 0; + reqs_drul_[STOP] = 0; + if (beam_p_) + beam_p_->suicide (); + beam_p_ = 0; + } + else if (c->span_type_str_ == "beam") + { + + Direction d =c->span_dir_; - if (bool (beam_p_) == bool (b->spantype == Span_req::START)) - return false; + if (d == STOP && !beam_p_) + { + m->origin ()->warning (_ ("can't find start of beam")); + return false; + } - Direction d = (!beam_p_) ? LEFT : RIGHT; - if (span_reqs_drul_[d] && !span_reqs_drul_[d]->equal_b (b)) - return false; + if(d == STOP) + { + SCM m = get_property ("automaticMelismata"); + SCM b = get_property("noAutoBeaming"); + if (to_boolean (m) && to_boolean(b)) + { + set_melisma (false); + } + } - span_reqs_drul_[d] = b; - return true; + reqs_drul_[d ] = c; + return true; + } + } + return false; } void -Beam_engraver::do_process_requests() +Beam_engraver::set_melisma (bool m) { - if (beam_p_ || !span_reqs_drul_[LEFT]) - return; - - current_grouping_p_ = new Rhythmic_grouping; - beam_p_ = new Beam; - - Scalar prop = get_property ("beamslopedamping"); - if (prop.isnum_b ()) - beam_p_->damping_i_ = prop; - - prop = get_property ("beamquantisation"); - if (prop.isnum_b ()) - beam_p_->quantisation_ = (Beam::Quantisation)(int)prop; - - announce_element (Score_element_info (beam_p_, span_reqs_drul_[LEFT])); + daddy_trans_l_->set_property ("beamMelismaBusy", m ? SCM_BOOL_T :SCM_BOOL_F); } + void -Beam_engraver::do_pre_move_processing() +Beam_engraver::do_process_music () { - if (!beam_p_ || !span_reqs_drul_[RIGHT]) - return; + if (reqs_drul_[STOP]) + { + if (!beam_p_) + reqs_drul_[STOP]->origin ()->warning (_("can't find start of beam")); + prev_start_req_ =0; + finished_beam_p_ = beam_p_; + finished_beam_info_p_ = beam_info_p_; - Rhythmic_grouping const * rg_C = get_staff_info().rhythmic_C_; - rg_C->extend (current_grouping_p_->interval()); - beam_p_->set_grouping (*rg_C, *current_grouping_p_); - typeset_element (beam_p_); - beam_p_ = 0; + beam_info_p_ =0; + beam_p_ = 0; + } + + + if (beam_p_ && !to_boolean (get_property ("weAreGraceContext"))) + { + Score_engraver * e = 0; + Translator * t = daddy_grav_l (); + for (; !e && t; t = t->daddy_trans_l_) + { + e = dynamic_cast (t); + } + + if (!e) + programming_error ("No score engraver!"); + else + e->forbid_breaks (); + } + + if (reqs_drul_[START]) + { + if (beam_p_) + { + reqs_drul_[START]->origin ()->warning (_ ("already have a beam")); + return; + } - delete current_grouping_p_; - current_grouping_p_ = 0; + prev_start_req_ = reqs_drul_[START]; + beam_p_ = new Spanner (get_property ("Beam")); + Beam::set_interface (beam_p_); + + SCM smp = get_property ("measurePosition"); + Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0); - span_reqs_drul_[RIGHT] = span_reqs_drul_[LEFT] = 0; + beam_start_location_ = mp; + beam_start_mom_ = now_mom(); + beam_info_p_ = new Beaming_info_list; + + + /* urg, must copy to Auto_beam_engraver too */ + + announce_element (beam_p_, reqs_drul_[START]); + } } void -Beam_engraver::do_removal_processing() +Beam_engraver::typeset_beam () { - if (beam_p_) + if (finished_beam_p_) { - span_reqs_drul_[LEFT]->warning (_("unterminated beam")); - typeset_element (beam_p_); - beam_p_ =0; + finished_beam_info_p_->beamify (); + + Beam::set_beaming (finished_beam_p_, finished_beam_info_p_); + typeset_element (finished_beam_p_); + delete finished_beam_info_p_; + finished_beam_info_p_ =0; + finished_beam_p_ = 0; + + reqs_drul_[STOP] = 0; } } +void +Beam_engraver::do_post_move_processing () +{ + reqs_drul_ [START] =0; + if(beam_p_) { + SCM m = get_property ("automaticMelismata"); + SCM b = get_property("noAutoBeaming"); + if (to_boolean (m) && to_boolean(b)) { + set_melisma (true); + } + } +} void -Beam_engraver::acknowledge_element (Score_element_info i) +Beam_engraver::do_pre_move_processing () { - Stem* s = dynamic_cast (i.elem_l_); - if (!beam_p_ || !s) - return; + typeset_beam (); +} - if (!dynamic_cast (i.req_l_)) +void +Beam_engraver::do_removal_processing () +{ + typeset_beam (); + if (beam_p_) { - ::warning ( _("Stem must have Rhythmic structure.")); - return; + prev_start_req_->origin ()->warning (_ ("unterminated beam")); +#if 0 + finished_beam_p_ = beam_p_; + finished_beam_info_p_ = beam_info_p_; + typeset_beam (); +#else + beam_p_->suicide (); + delete beam_info_p_; +#endif } +} - Rhythmic_req *rhythmic_req = dynamic_cast (i.req_l_); - if (rhythmic_req->duration_.durlog_i_<= 2) +void +Beam_engraver::acknowledge_element (Score_element_info info) +{ + if (beam_p_) { - rhythmic_req->warning (_ ("stem doesn't fit in beam")); - return; - } + if (Rest::has_interface (info.elem_l_)) + { + info.elem_l_->add_offset_callback (Beam::rest_collision_callback_proc, Y_AXIS); + } + else if (Stem::has_interface (info.elem_l_)) + { + Item *stem_l = dynamic_cast (info.elem_l_); + if (Stem::beam_l (stem_l)) + return; - /* - TODO: do something sensible if it doesn't fit in the beam. - */ - Moment start = get_staff_info().time_C_->whole_in_measure_; + bool stem_grace = stem_l->get_elt_property ("grace") == SCM_BOOL_T; - if (!current_grouping_p_->child_fit_b (start)) - { - String s (_("please fix me") + ": " - + _f ("stem at %s doesn't fit in beam", now_moment ().str ())); - if (i.req_l_) - i.req_l_->warning(s); - else - warning (s); - } - else - { - current_grouping_p_->add_child (start, rhythmic_req->duration ()); - s->flag_i_ = rhythmic_req->duration_.durlog_i_; - beam_p_->add_stem (s); + SCM wg =get_property ("weAreGraceContext"); + bool wgb= to_boolean (wg); + + if (wgb!= stem_grace) + return; + + Rhythmic_req *rhythmic_req = dynamic_cast (info.req_l_); + if (!rhythmic_req) + { + String s = _ ("stem must have Rhythmic structure"); + if (info.req_l_) + info.req_l_->origin ()->warning (s); + else + ::warning (s); + + return; + } + + if (rhythmic_req->duration_.durlog_i_<= 2) + { + rhythmic_req->origin ()->warning (_ ("stem doesn't fit in beam")); + prev_start_req_->origin ()->warning (_ ("beam was started here")); + /* + don't return, since + + [r4 c8] can just as well be modern notation. + */ + } + + stem_l->set_elt_property ("duration-log", + gh_int2scm (rhythmic_req->duration_.durlog_i_)); + Moment stem_location = now_mom () - beam_start_mom_ + beam_start_location_; + beam_info_p_->add_stem (stem_location, + (rhythmic_req->duration_.durlog_i_ - 2) >? 1); + Beam::add_stem (beam_p_, stem_l); + } } } + + ADD_THIS_TRANSLATOR(Beam_engraver); +