]> git.donarmstrong.com Git - lilypond.git/blob - lily/score-elem.cc
partial: 0.1.65.jcn
[lilypond.git] / lily / score-elem.cc
1 /*
2   score-elem.cc -- implement Score_elem
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1998 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8 #include "outputter.hh"
9 #include "p-score.hh"
10 #include "paper-def.hh"
11 #include "lookup.hh"
12 #include "molecule.hh"
13 #include "score-elem.hh"
14 #include "debug.hh"
15 #include "tex.hh"
16 #include "dimen.hh"
17 #include "spanner.hh"
18 #include "scoreline.hh"
19 #include "item.hh"
20 #include "p-col.hh"
21
22 Score_elem::Score_elem()
23 {
24   transparent_b_ = false;
25   pscore_l_=0;
26   status_i_ = 0;
27 }
28
29 Score_elem::Score_elem (Score_elem const&s)
30   :  Directed_graph_node (s), Graphical_element (s)
31 {
32   /* called from derived ctor, so most info points to the same deps
33      as (Directed_graph_node&)s. Nobody points to us, so don't copy
34      dependents.      
35    */
36   copy_edges_out (s);
37   transparent_b_ = s.transparent_b_;
38   status_i_ = s.status_i_;
39   pscore_l_ = s.pscore_l_;
40 }
41
42 Score_elem::~Score_elem()
43 {
44   assert (status_i_ >=0);
45   status_i_ = -1;
46 }
47
48 Score_elem*
49 Score_elem::dependency (int i) const
50 {
51   return (Score_elem*) get_out_edge_arr ()[i];
52 }
53
54 int
55 Score_elem::dependency_size () const
56 {
57   return get_out_edge_arr ().size ();
58 }
59
60 Score_elem*
61 Score_elem::dependent (int i) const
62 {
63   return (Score_elem*) get_in_edge_arr()[i];
64 }
65
66 int
67 Score_elem::dependent_size() const
68 {
69   return get_in_edge_arr().size ();
70 }
71
72
73
74 Interval
75 Score_elem::do_width() const 
76 {
77   Interval r;
78
79   Molecule*m = brew_molecule_p();
80   r = m->extent().x ();
81   delete m;
82   
83   return r;
84 }
85
86 Interval
87 Score_elem::do_height() const 
88 {
89   Interval r;
90   Molecule*m = brew_molecule_p();
91   r = m->extent().y ();
92   delete m;
93   return r;
94 }
95
96
97 /*
98   STANDARD METHS
99  */
100 void
101 Score_elem::print() const
102 {
103 #ifndef NPRINT
104   DOUT << name() << "{\n";
105   DOUT << "dets: " << dependent_size() << "dependencies: " << 
106     dependency_size();
107  
108   Graphical_element::print ();
109   do_print();
110   
111   DOUT <<  "}\n";
112 #endif
113 }
114
115
116 Paper_def*
117 Score_elem::paper()  const
118 {
119   assert (pscore_l_);
120   return pscore_l_->paper_l_;
121 }
122
123
124 void
125 Score_elem::add_processing()
126 {
127   if (status_i_)
128     return;
129   status_i_ ++;
130   do_add_processing();
131 }
132
133
134 void
135 Score_elem::calcalute_dependencies (int final, int busy,
136                                     Score_elem_method_pointer funcptr)
137 {
138   if (status_i_ >= final)
139     return;
140
141   assert (status_i_!= busy);
142   status_i_= busy;
143
144   for (int i=0; i < dependency_size(); i++)
145     dependency (i)->calcalute_dependencies (final, busy, funcptr);
146
147   Link_array<Score_elem> extra (get_extra_dependencies());
148   for (int i=0; i < extra.size(); i++)
149     extra[i]->calcalute_dependencies (final, busy, funcptr);
150   
151   invalidate_cache (X_AXIS);
152   invalidate_cache (Y_AXIS);
153   (this->*funcptr)();
154   status_i_= final;
155 }
156
157 void
158 Score_elem::do_brew_molecule () 
159 {
160   if (transparent_b_)
161     return ;
162   Molecule *output= brew_molecule_p ();
163   pscore_l_->outputter_l_->output_molecule (output, absolute_offset ());
164 }
165
166 /*
167   
168   VIRTUAL STUBS
169
170  */
171
172 void
173 Score_elem::do_break_processing()
174 {
175   handle_broken_dependencies();
176 }
177
178 void
179 Score_elem::do_post_processing()
180 {
181 }
182
183 void
184 Score_elem::do_breakable_col_processing()
185 {
186   handle_prebroken_dependencies();
187 }
188
189 void
190 Score_elem::do_pre_processing()
191 {
192 }
193
194 void
195 Score_elem::do_space_processing ()
196 {
197 }
198
199 void
200 Score_elem::do_add_processing()
201 {
202 }
203
204 void
205 Score_elem::do_substitute_dependency (Score_elem*,Score_elem*)
206 {
207 }
208 void
209 Score_elem::do_substitute_dependent (Score_elem*,Score_elem*)
210 {
211 }
212
213 void
214 Score_elem::do_unlink()
215 {
216 }
217
218 void
219 Score_elem::do_junk_links()
220 {
221 }
222
223 IMPLEMENT_IS_TYPE_B1(Score_elem, Graphical_element);
224
225 Molecule*
226 Score_elem::brew_molecule_p() const
227 {
228   Atom a (paper()->lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))));
229   return new Molecule (a);
230 }
231
232
233 Line_of_score *
234 Score_elem::line_l() const
235 {
236   return 0;
237 }
238
239 /*
240   
241   DEPENDENCIES
242
243   */
244
245 void
246 Score_elem::remove_dependency (Score_elem*e)
247 {
248   remove_edge_out (e);
249   substitute_dependency (e, 0);
250 }
251
252 void
253 Score_elem::add_dependency (Score_elem*e)
254 {
255   Directed_graph_node::add (e);
256 }
257 void
258 Score_elem::substitute_dependency (Score_elem* old, Score_elem* new_l)
259 {
260   do_substitute_dependency (old,new_l);
261   old->do_substitute_dependent (this, 0);
262 }
263
264 void
265 Score_elem::handle_broken_dependencies()
266 {
267   Line_of_score *line  = line_l();
268   if (!line)
269     return;
270
271   Link_array<Score_elem> remove_us_arr;
272   for (int i=0; i < dependency_size(); i++) 
273     {
274       Score_elem * elt = dependency (i);
275       if (elt->line_l() != line)
276         {
277           if (elt->spanner()) 
278             {
279               Spanner * sp = elt->spanner();
280               Spanner * broken = sp->find_broken_piece (line);
281               substitute_dependency (sp, broken);
282
283               add_dependency (broken);
284             }
285           else if (elt->item())
286             {
287               Item * my_item = elt->item()->find_prebroken_piece (line);
288                 
289               substitute_dependency (elt, my_item);
290               if (my_item)
291                 add_dependency (my_item);
292             }
293           remove_us_arr.push (elt);
294         }
295     }
296
297   remove_us_arr.default_sort();
298   remove_us_arr.uniq();
299   for (int i=0;  i <remove_us_arr.size(); i++)
300     remove_dependency (remove_us_arr[i]);
301 }
302
303 /*
304   This sux.
305
306   unlike with spanners, the number of items can increase
307
308   span: item1
309
310   becomes
311
312   span: item1 item2 item3
313
314   How to let span (a derived class) know that this happened?
315  */
316 void
317 Score_elem::handle_prebroken_dependencies()
318 {
319   Link_array<Score_elem> old_arr, new_arr;
320   
321   for (int i=0; i < dependency_size(); i++) 
322     {
323       Score_elem * elt = dependency (i);
324       Item *it_l = elt->item();
325       if (it_l && it_l->breakable_b_)
326         if (item()) 
327           {
328             Score_elem *new_l = it_l->find_prebroken_piece (item()->break_status_i_);
329             if (new_l != elt) 
330               {
331                 new_arr.push (new_l);
332                 old_arr.push (elt);
333               }
334           }
335         else 
336           {
337             new_arr.push (it_l->broken_to_drul_[LEFT]);
338             old_arr.push (0);
339             old_arr.push (0);           
340             new_arr.push (it_l->broken_to_drul_[RIGHT]);                
341           }
342     }
343   
344   for (int i=0;  i < old_arr.size(); i++)
345     if (old_arr[i])
346       substitute_dependency (old_arr[i], new_arr[i]);
347 }
348
349
350 void
351 Score_elem::junk_links ()
352 {
353   Directed_graph_node::junk_links();
354   Graphical_element::junk_links ();
355   do_junk_links();
356 }
357
358 void
359 Score_elem::unlink()
360 {
361   do_unlink();
362   while (dependency_size()) 
363     {
364       do_substitute_dependency (dependency (0),0);
365       remove_edge_out_idx (0);
366     }
367   while  (dependent_size()) 
368     {
369       dependent (0)->remove_dependency (this);
370     }
371   for (int j=0; j < 2; j++)
372     if (axis_group_l_a_[j])
373       axis_group_l_a_[j]->remove_element (this);
374 }
375
376
377 Link_array<Score_elem>
378 Score_elem::get_extra_dependencies() const
379 {
380   Link_array<Score_elem> empty;
381   return empty;
382 }
383
384 bool
385 Score_elem::linked_b() const
386 {
387   return get_extra_dependencies().size() || 
388     dependency_size();
389 }
390
391