]> git.donarmstrong.com Git - lilypond.git/blob - src/groupregs.cc
release: 0.0.27
[lilypond.git] / src / groupregs.cc
1 #include "script.hh"
2 #include "request.hh"
3 #include "beam.hh"
4 #include "stem.hh"
5 #include "register.hh"
6 #include "grouping.hh"
7 #include "complexwalker.hh"
8 #include "debug.hh"
9 #include "complexstaff.hh"
10 #include "textspanner.hh"
11 #include "textitem.hh"
12
13 Stem_beam_register::Stem_beam_register(Complex_walker*w)
14     :Request_register(w)
15 {
16     do_post_move_process();
17     current_grouping = 0;
18     beam_p_ = 0;
19     set_dir(0);
20     start_req_l_ = 0;
21 }
22
23 bool
24 Stem_beam_register::try_request(Request*req_l)
25 {
26     if ( req_l->beam() ) {
27         if (bool(beam_p_ ) == bool(req_l->beam()->spantype == Span_req::START))
28             return false;
29         
30         if (beam_req_l_ && Beam_req::compare(*beam_req_l_ , *req_l->beam()))
31             return false;
32         
33         beam_req_l_ = req_l->beam();
34         return true;
35     }
36     
37     if ( req_l->stem() ) {
38         if (current_grouping && !current_grouping->child_fit_query(
39             walk_l_->col()->tdescription_->whole_in_measure))
40             return false;
41
42         if (stem_req_l_ && Stem_req::compare(*stem_req_l_, *req_l->stem()))
43             return false;
44
45         stem_req_l_ = req_l->stem();
46         return true;
47     }
48     return false;
49 }
50
51 void
52 Stem_beam_register::process_request()
53 {
54     if (beam_req_l_) {
55         if (beam_req_l_->spantype == Span_req::STOP) {
56             end_beam_b_ = true;
57             start_req_l_ = 0;
58         } else {
59             beam_p_ = new Beam;
60             start_req_l_ = beam_req_l_;
61 //          walk_l_->announce_element(Staff_elem_info(beam_p_, ))
62             current_grouping = new Rhythmic_grouping;
63             if (beam_req_l_->nplet) {
64                 Text_spanner* t = new Text_spanner();
65                 t->set_support(beam_p_);
66                 t->spec.align_i_ = 0;
67                 t->spec.text_str_ = beam_req_l_->nplet;
68                 walk_l_->typeset_element(t);
69             }
70              
71         }
72     }
73
74     if (stem_req_l_) {
75         stem_p_ = new Stem(4);
76         if (current_grouping)
77             current_grouping->add_child(
78                 walk_l_->col()->tdescription_->whole_in_measure,
79                 stem_req_l_->duration());
80
81         stem_p_->flag = stem_req_l_->balltype;
82
83         if (beam_p_) {
84             if (stem_req_l_->balltype<= 4)
85                 warning( "stem doesn't fit in Beam.",
86                          stem_req_l_->defined_ch_c_l_m);
87             else
88                 beam_p_->add(stem_p_);
89             stem_p_->print_flag = false;
90         } else {
91             stem_p_->print_flag = true;
92         }
93         
94         walk_l_->announce_element(Staff_elem_info(stem_p_,
95                                                   stem_req_l_,  this));
96     }
97 }
98
99 void
100 Stem_beam_register::acknowledge_element(Staff_elem_info info)
101 {
102     if (!stem_p_)
103         return;
104
105     if (info.elem_p_->name() == String("Notehead") &&
106         stem_req_l_->duration() == info.req_l_->rhythmic()->duration())
107         
108         stem_p_->add((Notehead*)info.elem_p_);
109 }
110
111 void
112 Stem_beam_register::do_pre_move_process()
113 {
114     if (stem_p_) {
115         if (default_dir_i_)
116             stem_p_->dir = default_dir_i_;
117         
118         walk_l_->typeset_element(stem_p_);
119         stem_p_ = 0;
120     }
121     if (beam_p_ && end_beam_b_) {
122         walk_l_->default_grouping.extend(current_grouping->interval());
123         beam_p_->set_grouping(walk_l_->default_grouping, *current_grouping);
124         walk_l_->typeset_element(beam_p_);
125         delete current_grouping;
126         current_grouping = 0;
127         beam_p_ = 0;
128     }
129     end_beam_b_ = false;
130 }
131 void
132 Stem_beam_register::do_post_move_process()
133 {
134     stem_p_ = 0;
135     beam_req_l_ = 0;
136     stem_req_l_ = 0;
137     end_beam_b_ = false;
138 }
139
140 Stem_beam_register::~Stem_beam_register()
141 {
142     if (beam_p_)
143         warning("unterminated beam", start_req_l_->defined_ch_c_l_m);
144 }
145
146 void
147 Stem_beam_register::set_dir(int i)
148 {
149     default_dir_i_ = i;
150 }
151 /****************/
152
153 Script_register::Script_register(Complex_walker*w)
154     : Request_register(w)
155 {
156     script_p_ = 0;
157 }
158
159 bool
160 Script_register::try_request(Request *r_l)
161 {
162     if (!r_l->script())
163         return false ;
164
165     if (accepted_req_arr_.size()
166         && Script_req::compare(
167             *accepted_req_arr_[0]->script(), *r_l->script()))
168         
169         return false;
170
171     accepted_req_arr_.push(r_l);
172     
173     return true;
174 }
175 void
176 Script_register::process_request()
177 {
178     if (accepted_req_arr_.size() ) {
179         script_p_ = new Script(accepted_req_arr_[0]->script(), 10);
180         walk_l_->announce_element(
181             Staff_elem_info(script_p_, accepted_req_arr_[0], this));
182     }
183 }
184
185 void
186 Script_register::acknowledge_element(Staff_elem_info info)
187 {
188     if (!script_p_)
189         return;
190     if (info.elem_p_->name() == String("Stem"))
191         script_p_->set_stem((Stem*)info.elem_p_);
192     else if (info.req_l_->rhythmic())
193         script_p_->set_support(info.elem_p_->item());
194 }
195
196 void
197 Script_register::do_pre_move_process()
198 {
199     if (script_p_){
200         walk_l_->typeset_element(script_p_);
201         script_p_ = 0;
202     }
203 }
204 /******************/
205
206
207 Text_register::Text_register(Complex_walker*w)
208     : Request_register(w)
209 {
210     text_p_ = 0;
211 }
212
213 bool
214 Text_register::try_request(Request*req_l)
215 {
216     if (!req_l->text())
217         return false;
218     if (accepted_req_arr_.size() &&
219         Text_req::compare(*req_l->text(), *accepted_req_arr_[0]->text()))
220
221         return false;
222
223     accepted_req_arr_.push(req_l);
224     return true;
225 }
226
227 void
228 Text_register::process_request()
229 {
230     
231     if (accepted_req_arr_.size()) {
232         text_p_ = new Text_item(accepted_req_arr_[0]->text(), 10);
233         walk_l_->announce_element(Staff_elem_info(text_p_,
234                                                   accepted_req_arr_[0], this));
235     }
236 }
237 void
238 Text_register::do_pre_move_process()
239 {
240     if (text_p_) {
241         walk_l_->typeset_element(text_p_);
242         text_p_ = 0;
243     }
244 }