2 beam-engraver.cc -- implement Beam_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "timing-engraver.hh"
11 #include "engraver-group-engraver.hh"
12 #include "beam-engraver.hh"
13 #include "musical-request.hh"
17 #include "timing-translator.hh"
19 #include "score-engraver.hh"
21 ADD_THIS_TRANSLATOR (Beam_engraver);
23 Beam_engraver::Beam_engraver ()
27 finished_beam_info_p_=0;
29 reqs_drul_[LEFT] = reqs_drul_[RIGHT] =0;
34 Beam_engraver::do_try_music (Music *m)
36 if (Span_req * c = dynamic_cast<Span_req*>(m))
38 if (c->span_type_str_ != "beam")
41 Direction d =c->span_dir_;
43 if (d == STOP && !beam_p_)
45 m->warning (_ ("no beam to end"));
56 Beam_engraver::do_process_requests ()
61 reqs_drul_[STOP]->warning (_("no beam to end"));
63 finished_beam_p_ = beam_p_;
64 finished_beam_info_p_ = beam_info_p_;
73 Score_engraver * e = 0;
74 Translator * t = daddy_grav_l ();
75 for (; !e && t; t = t->daddy_trans_l_)
77 e = dynamic_cast<Score_engraver*> (t);
81 programming_error ("No score engraver!");
86 if (reqs_drul_[START])
90 reqs_drul_[START]->warning (_ ("Already have a beam"));
94 prev_start_req_ = reqs_drul_[START];
97 Translator * t = daddy_grav_l ()->get_simple_translator ("Timing_engraver");
98 Timing_engraver *timer = dynamic_cast<Timing_engraver*> (t);
99 beam_start_location_ = (t) ? timer->measure_position () : Moment (0);
100 beam_start_mom_ = now_mom();
101 beam_info_p_ = new Beaming_info_list;
104 /* urg, must copy to Auto_beam_engraver too */
106 announce_element (Score_element_info (beam_p_, reqs_drul_[START]));
111 Beam_engraver::typeset_beam ()
113 if (finished_beam_p_)
115 finished_beam_info_p_->beamify ();
117 finished_beam_p_->set_beaming (finished_beam_info_p_);
118 typeset_element (finished_beam_p_);
119 delete finished_beam_info_p_;
120 finished_beam_info_p_ =0;
121 finished_beam_p_ = 0;
123 reqs_drul_[STOP] = 0;
128 Beam_engraver::do_post_move_processing ()
130 reqs_drul_ [START] =0;
134 Beam_engraver::do_pre_move_processing ()
140 Beam_engraver::do_removal_processing ()
145 prev_start_req_->warning (_ ("unfinished beam"));
146 finished_beam_p_ = beam_p_;
147 finished_beam_info_p_ = beam_info_p_;
153 Beam_engraver::acknowledge_element (Score_element_info info)
157 Stem* stem_l = dynamic_cast<Stem *> (info.elem_l_);
158 if (!stem_l || stem_l->beam_l ())
162 bool stem_grace = stem_l->get_elt_property ("grace") == SCM_BOOL_T;
164 SCM wg =get_property ("weAreGraceContext",0);
165 bool wgb= to_boolean (wg);
167 if (wgb!= stem_grace)
170 Rhythmic_req *rhythmic_req = dynamic_cast <Rhythmic_req *> (info.req_l_);
173 String s = _ ("Stem must have Rhythmic structure");
175 info.req_l_->warning (s);
182 if (rhythmic_req->duration_.durlog_i_<= 2)
184 rhythmic_req->warning (_ ("Stem doesn't fit in beam"));
185 prev_start_req_->warning (_ ("Beam was started here"));
189 stem_l->set_elt_property ("duration-log",
190 gh_int2scm (rhythmic_req->duration_.durlog_i_));
191 Moment stem_location = now_mom () - beam_start_mom_ + beam_start_location_;
192 beam_info_p_->add_stem (stem_location, rhythmic_req->duration_.durlog_i_ - 2);
193 beam_p_->add_stem (stem_l);