]> git.donarmstrong.com Git - lilypond.git/blob - lily/score-grav.cc
96192d66f99a5d51772b8d8ebc52225fc6c875f9
[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     {
105         for (int i=0; i <announce_info_arr_.size(); i++)
106             /*
107               TODO
108
109               More subtle spacing
110              */
111             if (announce_info_arr_[i].req_l_) 
112               {
113                 Musical_req *m = announce_info_arr_[i].req_l_->musical();
114                 if (m && m->rhythmic()) 
115                   {
116                     musical_column_l_->add_duration (m->duration());
117                   }
118               }
119         Engraver_group_engraver::do_announces();
120     }
121 }
122
123
124 void
125 Score_engraver::typeset_element (Score_elem *elem_p)
126 {
127   if  ( elem_p->item() && elem_p->item ()->breakable_b_) 
128     {
129         nobreak_item_p_arr_.push (elem_p->item());
130     }
131   else
132         musical_item_p_arr_.push (elem_p);
133 }
134
135 void
136 Score_engraver::typeset_all()
137 {
138   PCol * c= get_staff_info().command_pcol_l ();
139   Paper_score *ps_l = score_l_->pscore_p_;
140
141   for  (int i =0; i < nobreak_item_p_arr_.size(); i++) 
142     {
143         ps_l->typeset_item (nobreak_item_p_arr_[i], c);
144
145         // should get rid of this.. .
146         scoreline_l_->add_dependency (nobreak_item_p_arr_[i]);
147     }
148   nobreak_item_p_arr_.clear();
149   
150   for (int i=0; i < musical_item_p_arr_.size(); i++) 
151     {
152         PCol* m = get_staff_info().musical_pcol_l ();
153         Score_elem *elem_p = musical_item_p_arr_[i];
154
155         scoreline_l_->add (elem_p);
156         if (elem_p->spanner()) 
157           {
158             ps_l->typeset_unbroken_spanner (elem_p->spanner());
159           }
160         else if (elem_p->item()) 
161           {
162             ps_l->typeset_item (elem_p->item(), m);
163           }
164         else
165             assert (false);
166     }
167   musical_item_p_arr_.clear();
168 }
169
170
171 void
172 Score_engraver::do_pre_move_processing()
173 {
174   if ( !disallow_break_b_)
175     {
176         get_staff_info().command_pcol_l ()->set_breakable ();
177         breaks_i_ ++;
178         if ( ! (breaks_i_%8))
179             *mlog << "[" << breaks_i_ << "]" << flush;
180     }
181   // this generates all items.
182   Engraver_group_engraver::do_pre_move_processing();
183   
184   typeset_all();
185 }
186
187 void
188 Score_engraver::set_columns (Score_column *new_command_l, 
189                             Score_column *new_musical_l)
190 {
191   if ( command_column_l_ && command_column_l_->used_b())
192         score_l_->pscore_p_->add (command_column_l_);
193   else 
194     {
195         delete command_column_l_ ;
196         command_column_l_ =0;
197     }
198   if (new_command_l) 
199     {
200         command_column_l_ = new_command_l;
201         command_column_l_->musical_b_ = false;
202     }
203   if ( musical_column_l_ && musical_column_l_->used_b())
204         score_l_->pscore_p_->add (musical_column_l_);
205   else 
206     {
207         delete musical_column_l_;
208         musical_column_l_ = 0;
209     }
210   
211   if (new_musical_l) 
212     {
213         musical_column_l_ = new_musical_l;
214         musical_column_l_->musical_b_ = true;
215     }
216 }
217
218
219 Staff_info
220 Score_engraver::get_staff_info()const
221 {
222   Staff_info inf;
223
224   inf.command_l_ = command_column_l_;
225   inf.musical_l_ = musical_column_l_;
226   return inf;
227 }
228
229 Paper_def*
230 Score_engraver::paper()const
231 {
232   return score_l_->paper_p_;
233 }
234
235
236
237 bool
238 Score_engraver::do_try_request (Request*r)
239 {
240   bool gotcha = Engraver_group_engraver::do_try_request (r);  
241   if ( !gotcha && r->command() && r->command ()->disallowbreak ())
242             disallow_break_b_ = true;
243   return gotcha;
244 }
245
246 IMPLEMENT_IS_TYPE_B1(Score_engraver,Engraver_group_engraver);
247 ADD_THIS_ENGRAVER(Score_engraver);
248