]> git.donarmstrong.com Git - lilypond.git/blob - lily/beam-grav.cc
release: 0.1.11
[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     {
105       Stem * s = (Stem*)i.elem_l_->item();
106       Rhythmic_req *rhythmic_req = i.req_l_->musical ()->rhythmic ();
107       if (rhythmic_req->duration_.durlog_i_<= 2) 
108         {
109           rhythmic_req->warning ("Stem doesn't fit in Beam");
110           return ;
111         }
112         
113       /*
114         TODO: do something sensible if it doesn't fit in the beam.
115        */
116       current_grouping_p_->add_child (get_staff_info().time_C_->whole_in_measure_,
117                                       rhythmic_req->duration());
118       /* 
119          TODO
120          should change rep. of flags too.k
121        */
122       s->flag_i_ = Duration_convert::type2_i
123         (rhythmic_req->duration_.durlog_i_);    
124       s->print_flag_b_ = false;
125       beam_p_->add (s);
126     }
127
128         
129 IMPLEMENT_IS_TYPE_B1(Beam_engraver, Engraver);
130 ADD_THIS_ENGRAVER(Beam_engraver);