]> git.donarmstrong.com Git - lilypond.git/blob - lily/score-grav.cc
release: 0.1.7
[lilypond.git] / lily / score-grav.cc
1 /*
2   score-grav.cc -- implement Score_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "super-elem.hh"
10 #include "scoreline.hh"
11 #include "debug.hh"
12 #include "score-elem.hh"
13 #include "bar.hh"               // needed for Bar::static_name
14 #include "score-grav.hh"
15 #include "p-col.hh"
16 #include "p-score.hh"
17 #include "score.hh"
18 #include "musical-request.hh"
19 #include "score-column.hh"
20 #include "command-request.hh"
21
22
23 void
24 Score_engraver::set_score(Score *s)
25 {
26     Global_translator::set_score(s);
27     scoreline_l_ = s->pscore_p_->super_elem_l_->line_of_score_l_;
28 }
29
30 Score_engraver::Score_engraver()
31 {
32     disallow_break_b_ = false;
33     scoreline_l_ =0;
34     command_column_l_ =0;
35     musical_column_l_ =0;
36     breaks_i_ =0;
37 }
38
39  
40 void
41 Score_engraver::prepare(Moment w)
42 {
43     set_columns(new Score_column(w),  new Score_column(w));
44     
45     
46     disallow_break_b_ = false;
47     post_move_processing();
48 }
49
50 void
51 Score_engraver::finish()
52 {
53     if ( (breaks_i_%8))
54             *mlog << "[" << breaks_i_ << "]" << flush;
55    
56     check_removal();
57     removal_processing();
58 }
59
60 void
61 Score_engraver::do_creation_processing()
62 {
63     scoreline_l_->left_col_l_ = get_staff_info().command_pcol_l();
64     scoreline_l_->left_col_l_ ->set_breakable();
65     Engraver_group_engraver::do_creation_processing();
66 }
67
68 void
69 Score_engraver::do_removal_processing()
70 {
71     Engraver_group_engraver::do_removal_processing();
72     scoreline_l_->right_col_l_ = get_staff_info().command_pcol_l();
73     scoreline_l_->right_col_l_ ->set_breakable();
74     typeset_all();
75     set_columns(0,0);
76 }
77
78 void
79 Score_engraver::process()
80 {
81         process_requests();
82         do_announces();
83         pre_move_processing();
84         check_removal();
85 }
86
87 void
88 Score_engraver::announce_element(Score_elem_info info)
89 {
90     announce_info_arr_.push(info);
91     info.origin_grav_l_arr_.push(this);
92         
93 }
94 void
95 Score_engraver::do_announces()
96 {
97     /* All elements are propagated to the top upon announcement. If
98       something was created during one run of
99       Engraver_group_engraver::do_announces, then
100       announce_info_arr_.size() will be nonzero again
101
102       */
103     while (announce_info_arr_.size()) {
104         for (int i=0; i <announce_info_arr_.size(); i++)
105             /*
106               TODO
107
108               More subtle spacing
109              */
110             if (announce_info_arr_[i].req_l_) {
111                 Musical_req *m = announce_info_arr_[i].req_l_->musical();
112                 if (m && m->rhythmic()) {
113                     musical_column_l_->add_duration( m->duration());
114                 }
115             }
116         Engraver_group_engraver::do_announces();
117     }
118 }
119
120
121 void
122 Score_engraver::typeset_element(Score_elem *elem_p)
123 {
124     if  ( elem_p->item() && elem_p->item()->breakable_b_ ) {
125         nobreak_item_p_arr_.push(elem_p->item());
126     } else
127         musical_item_p_arr_.push(elem_p);
128 }
129
130 void
131 Score_engraver::typeset_all()
132 {
133     PCol * c= get_staff_info().command_pcol_l();
134     Paper_score *ps_l = score_l_->pscore_p_;
135
136     for  (int i =0; i < nobreak_item_p_arr_.size(); i++) {
137         ps_l->typeset_item(nobreak_item_p_arr_[i], c);
138
139         // should get rid of this.. .
140         scoreline_l_->add_dependency(nobreak_item_p_arr_[i]);
141     }
142     nobreak_item_p_arr_.clear();
143     
144     for (int i=0; i < musical_item_p_arr_.size(); i++) {
145         PCol* m = get_staff_info().musical_pcol_l();
146         Score_elem *elem_p = musical_item_p_arr_[i];
147
148         scoreline_l_->add(elem_p);
149         if (elem_p->spanner()) {
150             ps_l->typeset_unbroken_spanner(elem_p->spanner());
151         } else if (elem_p->item()) {
152             ps_l->typeset_item(elem_p->item(), m);
153         } else
154             assert(false);
155     }
156     musical_item_p_arr_.clear();
157 }
158
159
160 void
161 Score_engraver::do_pre_move_processing()
162 {
163     if ( !disallow_break_b_ ){ 
164         get_staff_info().command_pcol_l()->set_breakable();
165         breaks_i_ ++;
166         if ( ! (breaks_i_%8))
167             *mlog << "[" << breaks_i_ << "]" << flush;
168     }
169     // this generates all items.
170     Engraver_group_engraver::do_pre_move_processing();
171     
172     typeset_all();
173 }
174
175 void
176 Score_engraver::set_columns(Score_column *new_command_l, 
177                             Score_column *new_musical_l)
178 {
179     if ( command_column_l_ && command_column_l_->used_b() )
180         score_l_->pscore_p_->add(command_column_l_);
181     else {
182         delete command_column_l_ ;
183         command_column_l_ =0;
184     }
185     if (new_command_l) {
186         command_column_l_ = new_command_l;
187         command_column_l_->musical_b_ = false;
188     }
189     if ( musical_column_l_ && musical_column_l_->used_b())
190         score_l_->pscore_p_->add (musical_column_l_);
191     else {
192         delete musical_column_l_;
193         musical_column_l_ = 0;
194     }
195     
196     if (new_musical_l) {
197         musical_column_l_ = new_musical_l;
198         musical_column_l_->musical_b_ = true;
199     }
200 }
201
202
203 Staff_info
204 Score_engraver::get_staff_info()const
205 {
206     Staff_info inf;
207
208     inf.command_l_ = command_column_l_;
209     inf.musical_l_ = musical_column_l_;
210     return inf;
211 }
212
213 Paper_def*
214 Score_engraver::paper()const
215 {
216     return score_l_->paper_p_;
217 }
218
219
220
221 bool
222 Score_engraver::do_try_request(Request*r)
223 {
224     bool gotcha = Engraver_group_engraver::do_try_request(r);  
225     if ( !gotcha && r->command() && r->command()->disallowbreak())
226             disallow_break_b_ = true;
227     return gotcha;
228 }
229
230 IMPLEMENT_IS_TYPE_B1(Score_engraver,Engraver_group_engraver);
231 ADD_THIS_ENGRAVER(Score_engraver);
232