lilypond-0.1.57
[lilypond.git] / lily / score-elem.cc
blobe81d7e0563e8609d7f44b034afdaafa493b5ab77
1 /*
2 score-elem.cc -- implement Score_elem
4 source file of the GNU LilyPond music typesetter
6 (c) 1997 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"
22 Score_elem::Score_elem()
24 transparent_b_ = false;
25 pscore_l_=0;
26 status_i_ = 0;
29 Score_elem::Score_elem (Score_elem const&s)
30 : Directed_graph_node (s), Graphical_element (s)
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.
36 copy_edges_out (s);
37 transparent_b_ = s.transparent_b_;
38 status_i_ = s.status_i_;
39 pscore_l_ = s.pscore_l_;
42 Score_elem::~Score_elem()
44 assert (status_i_ >=0);
45 status_i_ = -1;
48 Score_elem*
49 Score_elem::dependency (int i) const
51 return (Score_elem*) get_out_edge_arr ()[i];
54 int
55 Score_elem::dependency_size () const
57 return get_out_edge_arr ().size ();
60 Score_elem*
61 Score_elem::dependent (int i) const
63 return (Score_elem*) get_in_edge_arr()[i];
66 int
67 Score_elem::dependent_size() const
69 return get_in_edge_arr().size ();
74 Interval
75 Score_elem::do_width() const
77 Interval r;
79 Molecule*m = brew_molecule_p();
80 r = m->extent().x ();
81 delete m;
83 return r;
86 Interval
87 Score_elem::do_height() const
89 Interval r;
90 Molecule*m = brew_molecule_p();
91 r = m->extent().y ();
92 delete m;
93 return r;
98 STANDARD METHS
100 void
101 Score_elem::print() const
103 #ifndef NPRINT
104 DOUT << name() << "{\n";
105 DOUT << "dets: " << dependent_size() << "dependencies: " <<
106 dependency_size();
108 Graphical_element::print ();
109 do_print();
111 DOUT << "}\n";
112 #endif
116 Paper_def*
117 Score_elem::paper() const
119 assert (pscore_l_);
120 return pscore_l_->paper_l_;
124 void
125 Score_elem::add_processing()
127 if (status_i_)
128 return;
129 status_i_ ++;
130 do_add_processing();
134 void
135 Score_elem::calcalute_dependencies (int final, int busy,
136 Score_elem_method_pointer funcptr)
138 if (status_i_ >= final)
139 return;
141 assert (status_i_!= busy);
142 status_i_= busy;
144 for (int i=0; i < dependency_size(); i++)
145 dependency (i)->calcalute_dependencies (final, busy, funcptr);
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);
151 invalidate_cache (X_AXIS);
152 invalidate_cache (Y_AXIS);
153 (this->*funcptr)();
154 status_i_= final;
157 void
158 Score_elem::do_brew_molecule ()
160 if (transparent_b_)
161 return ;
162 Molecule *output= brew_molecule_p ();
163 pscore_l_->outputter_l_->output_molecule (output, absolute_offset ());
168 VIRTUAL STUBS
172 void
173 Score_elem::do_break_processing()
175 handle_broken_dependencies();
178 void
179 Score_elem::do_post_processing()
183 void
184 Score_elem::do_breakable_col_processing()
186 handle_prebroken_dependencies();
189 void
190 Score_elem::do_pre_processing()
194 void
195 Score_elem::do_space_processing ()
199 void
200 Score_elem::do_add_processing()
204 void
205 Score_elem::do_substitute_dependency (Score_elem*,Score_elem*)
208 void
209 Score_elem::do_substitute_dependent (Score_elem*,Score_elem*)
213 void
214 Score_elem::do_unlink()
218 void
219 Score_elem::do_junk_links()
223 IMPLEMENT_IS_TYPE_B1(Score_elem, Graphical_element);
225 Molecule*
226 Score_elem::brew_molecule_p() const
228 Atom a (paper()->lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))));
229 return new Molecule (a);
233 Line_of_score *
234 Score_elem::line_l() const
236 return 0;
241 DEPENDENCIES
245 void
246 Score_elem::remove_dependency (Score_elem*e)
248 remove_edge_out (e);
249 substitute_dependency (e, 0);
252 void
253 Score_elem::add_dependency (Score_elem*e)
255 Directed_graph_node::add (e);
257 void
258 Score_elem::substitute_dependency (Score_elem* old, Score_elem* new_l)
260 do_substitute_dependency (old,new_l);
261 old->do_substitute_dependent (this, 0);
264 void
265 Score_elem::handle_broken_dependencies()
267 Line_of_score *line = line_l();
268 if (!line)
269 return;
271 Link_array<Score_elem> remove_us_arr;
272 for (int i=0; i < dependency_size(); i++)
274 Score_elem * elt = dependency (i);
275 if (elt->line_l() != line)
277 if (elt->spanner())
279 Spanner * sp = elt->spanner();
280 Spanner * broken = sp->find_broken_piece (line);
281 substitute_dependency (sp, broken);
283 add_dependency (broken);
285 else if (elt->item())
287 Item * my_item = elt->item()->find_prebroken_piece (line);
289 substitute_dependency (elt, my_item);
290 if (my_item)
291 add_dependency (my_item);
293 remove_us_arr.push (elt);
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]);
304 This sux.
306 unlike with spanners, the number of items can increase
308 span: item1
310 becomes
312 span: item1 item2 item3
314 How to let span (a derived class) know that this happened?
316 void
317 Score_elem::handle_prebroken_dependencies()
319 Link_array<Score_elem> old_arr, new_arr;
321 for (int i=0; i < dependency_size(); i++)
323 Score_elem * elt = dependency (i);
324 Item *it_l = elt->item();
325 if (it_l && it_l->breakable_b_)
326 if (item())
328 Score_elem *new_l = it_l->find_prebroken_piece (item()->break_status_i_);
329 if (new_l != elt)
331 new_arr.push (new_l);
332 old_arr.push (elt);
335 else
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]);
344 for (int i=0; i < old_arr.size(); i++)
345 if (old_arr[i])
346 substitute_dependency (old_arr[i], new_arr[i]);
350 void
351 Score_elem::junk_links ()
353 Directed_graph_node::junk_links();
354 Graphical_element::junk_links ();
355 do_junk_links();
358 void
359 Score_elem::unlink()
361 do_unlink();
362 while (dependency_size())
364 do_substitute_dependency (dependency (0),0);
365 remove_edge_out_idx (0);
367 while (dependent_size())
369 dependent (0)->remove_dependency (this);
371 for (int j=0; j < 2; j++)
372 if (axis_group_l_a_[j])
373 axis_group_l_a_[j]->remove_element (this);
377 Link_array<Score_elem>
378 Score_elem::get_extra_dependencies() const
380 Link_array<Score_elem> empty;
381 return empty;
384 bool
385 Score_elem::linked_b() const
387 return get_extra_dependencies().size() ||
388 dependency_size();