]> git.donarmstrong.com Git - lilypond.git/blob - lily/score-grav.cc
release: 0.0.73pre
[lilypond.git] / lily / score-grav.cc
1 /*
2   score-reg.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 #include "super-elem.hh"
9 #include "scoreline.hh"
10 #include "debug.hh"
11 #include "score-elem.hh"
12 #include "bar.hh"               // needed for Bar::static_name
13 #include "staffline.hh"
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
21
22 void
23 Score_engraver::set_score(Score *s)
24 {
25     Global_translator::set_score(s);
26     scoreline_l_ = s->pscore_p_->super_elem_l_->line_of_score_l_;
27 }
28
29 Score_engraver::Score_engraver()
30 {
31     scoreline_l_ =0;
32     command_column_l_ =0;
33     musical_column_l_ =0;
34 }
35
36  
37 void
38 Score_engraver::prepare(Moment w)
39 {
40     Score_column* c1 = new Score_column(w);
41     Score_column* c2 = new Score_column(w);
42     
43     c1->musical_b_ = false;
44     c2->musical_b_ = true;
45     
46     score_l_->cols_.bottom().add(c1);
47     score_l_->cols_.bottom().add(c2);
48     set_cols(c1,c2);
49
50
51     post_move_processing();
52 }
53 void
54 Score_engraver::finish()
55 {
56     check_removal();
57     do_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::set_cols(Score_column*c1,Score_column*c2)
70 {
71     command_column_l_ = c1;
72     musical_column_l_ = c2;
73 }
74
75 void
76 Score_engraver::do_removal_processing()
77 {
78     Engraver_group_engraver::do_removal_processing();
79     scoreline_l_->right_col_l_ = get_staff_info().command_pcol_l();
80     scoreline_l_->right_col_l_ ->set_breakable();
81     typeset_all();
82 }
83
84 void
85 Score_engraver::process()
86 {
87         process_requests();
88         do_announces();
89         pre_move_processing();
90         check_removal();
91 }
92
93 void
94 Score_engraver::announce_element(Score_elem_info info)
95 {
96     info.origin_grav_l_arr_.push(this);
97     if (info.elem_l_->name() == Bar::static_name()) {
98         get_staff_info().command_pcol_l()->set_breakable();
99     } 
100         
101     announce_info_arr_.push(info);
102 }
103 void
104 Score_engraver::do_announces()
105 {
106     /* All elements are propagated to the top upon announcement. If
107       something was created during one run of
108       Engraver_group_engraver::do_announces, then
109       announce_info_arr_.size() will be nonzero again
110
111       */
112     while (announce_info_arr_.size()) {
113         for (int i=0; i <announce_info_arr_.size(); i++)
114             /*
115               TODO
116
117               More subtle spacing
118              */
119             if (announce_info_arr_[i].req_l_) {
120                 Musical_req *m = announce_info_arr_[i].req_l_->musical();
121                 if (m&&m->rhythmic()) {
122                     musical_column_l_->add_duration( m->duration());
123                 }
124             }
125         Engraver_group_engraver::do_announces();
126     }
127 }
128
129
130 void
131 Score_engraver::typeset_element(Score_elem *elem_p)
132 {
133     musical_item_p_arr_.push(elem_p);
134 }
135
136 void
137 Score_engraver::typeset_breakable_item(Item * nobreak_p)
138 {
139     if (nobreak_p) {
140         nobreak_item_p_arr_.push(nobreak_p);
141     }
142 }
143
144 void
145 Score_engraver::typeset_all()
146 {
147     PCol * c= get_staff_info().command_pcol_l();
148     PScore *ps_l = score_l_->pscore_p_;
149
150     for  (int i =0; i < nobreak_item_p_arr_.size(); i++) {
151         ps_l->typeset_item(nobreak_item_p_arr_[i], c, 0);
152         scoreline_l_->add_dependency(nobreak_item_p_arr_[i]);
153     }
154     nobreak_item_p_arr_.set_size(0);
155     
156     for (int i=0; i < musical_item_p_arr_.size(); i++) {
157         PCol* m = get_staff_info().musical_pcol_l();
158         Score_elem *elem_p = musical_item_p_arr_[i];
159
160         scoreline_l_->add(elem_p);
161         if (elem_p->spanner()) {
162             ps_l->typeset_unbroken_spanner(elem_p->spanner());
163         } else if (elem_p->item()) {
164             ps_l->typeset_item(elem_p->item(), m, 0);
165         } else
166             assert(false);
167     }
168     musical_item_p_arr_.set_size(0);
169 }
170
171
172 void
173 Score_engraver::do_pre_move_processing()
174 {
175     // this generates all items.
176     Engraver_group_engraver::do_pre_move_processing();
177     
178     typeset_all();
179 }
180
181
182 Staff_info
183 Score_engraver::get_staff_info()const
184 {
185     Staff_info inf;
186
187     inf.command_l_ = command_column_l_;
188     inf.musical_l_ = musical_column_l_;
189     return inf;
190 }
191
192 Paper_def*
193 Score_engraver::paper()const
194 {
195     return score_l_->paper_p_;
196 }
197
198
199
200 bool
201 Score_engraver::do_try_request(Request*r)
202 {
203     bool gotcha = false;  
204     for ( int i =0; !gotcha && i < nongroup_l_arr_.size() ; i++)
205         gotcha = nongroup_l_arr_[i]->try_request(r);
206   
207     return gotcha;
208 }
209
210 IMPLEMENT_IS_TYPE_B1(Score_engraver,Engraver_group_engraver);
211 IMPLEMENT_STATIC_NAME(Score_engraver);
212 ADD_THIS_ENGRAVER(Score_engraver);
213