]> git.donarmstrong.com Git - lilypond.git/blob - lily/beam-grav.cc
release: 0.1.13
[lilypond.git] / lily / beam-grav.cc
1 /*
2   beam-grav.cc -- implement Beam_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8 #include "duration-convert.hh"
9 #include "time-description.hh"
10 #include "beam-grav.hh"
11 #include "stem.hh"
12 #include "beam.hh"
13 #include "musical-request.hh"
14 #include "grouping.hh"
15 #include "text-spanner.hh"
16 #include "text-def.hh"
17
18 Beam_engraver::Beam_engraver()
19 {
20   span_reqs_drul_[LEFT] = span_reqs_drul_[RIGHT] =0;
21   beam_p_ =0;
22   current_grouping_p_ =0;
23 }
24
25 bool
26 Beam_engraver::do_try_request(Request*r)
27 {
28   Musical_req* mus_l = r->musical();
29   if (!mus_l)
30     return false;
31   
32   Beam_req * b = mus_l->beam();
33
34   if (!b)
35     return false;
36     
37   if (bool (beam_p_) == bool (b->spantype == Span_req::START))
38     return false;
39   
40   Direction d = (!beam_p_) ? LEFT : RIGHT;
41   if (span_reqs_drul_[d] && !span_reqs_drul_[d]->equal_b (mus_l))
42     return false;
43   
44   span_reqs_drul_[d] = b;
45   return true;
46 }
47
48 void
49 Beam_engraver::do_process_requests()
50 {
51   if ( !beam_p_ && span_reqs_drul_[LEFT]) {
52     current_grouping_p_ = new Rhythmic_grouping;
53     beam_p_ = new Beam;
54     if (span_reqs_drul_[LEFT]->nplet) 
55       {
56         Text_spanner* t = new Text_spanner();
57         Text_def *defp = new Text_def;
58         t->set_support (beam_p_);
59         defp->align_i_ = 0;
60         defp->text_str_ = span_reqs_drul_[LEFT]->nplet;
61         defp->style_str_="italic";
62         t->spec_p_  = defp;
63         announce_element (Score_elem_info (t,0));
64         typeset_element (t);
65       }
66     announce_element (Score_elem_info (beam_p_, span_reqs_drul_[LEFT]));
67   }
68 }
69
70 void
71 Beam_engraver::do_pre_move_processing()
72 {
73   if (beam_p_ && span_reqs_drul_[RIGHT]) {
74     Rhythmic_grouping const * rg_C = get_staff_info().rhythmic_C_;
75     rg_C->extend (current_grouping_p_->interval());
76     beam_p_->set_grouping (*rg_C, *current_grouping_p_);
77     typeset_element (beam_p_);
78     beam_p_ = 0;
79
80     delete current_grouping_p_;
81     current_grouping_p_ = 0;
82
83     span_reqs_drul_[RIGHT] =
84       span_reqs_drul_[LEFT] = 0;
85   }
86 }
87
88 void
89 Beam_engraver::do_removal_processing()
90 {
91   if (beam_p_) 
92     {
93       span_reqs_drul_[LEFT]->warning ("unterminated beam");
94       typeset_element (beam_p_);
95       beam_p_ =0;
96     }
97 }
98
99
100 void
101 Beam_engraver::acknowledge_element (Score_elem_info i)
102 {
103   if (!beam_p_ || !i.elem_l_->is_type_b (Stem::static_name ()))
104     return;
105
106   Stem* s = (Stem*)i.elem_l_->item();
107   Rhythmic_req *rhythmic_req = i.req_l_->musical ()->rhythmic ();
108   if (rhythmic_req->duration_.durlog_i_<= 2) 
109     {
110       rhythmic_req->warning ("Stem doesn't fit in Beam");
111       return;
112     }
113   
114   /*
115     TODO: do something sensible if it doesn't fit in the beam.
116    */
117   current_grouping_p_->add_child (get_staff_info().time_C_->whole_in_measure_,
118                                   rhythmic_req->duration ());
119   /* 
120    TODO
121    should change repr. of flags too.
122    */
123   s->flag_i_ = Duration_convert::type2_i (rhythmic_req->duration_.durlog_i_);
124   beam_p_->add (s);
125
126     
127 IMPLEMENT_IS_TYPE_B1(Beam_engraver, Engraver);
128 ADD_THIS_TRANSLATOR(Beam_engraver);