lilypond-1.3.17
[lilypond.git] / lily / score-elem.cc
blob929838a185a36b812db9170b96a236d1690f16ad
1 /*
2 score-elem.cc -- implement Score_elem
4 source file of the GNU LilyPond music typesetter
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 #include "molecule.hh"
23 Score_elem::Score_elem()
25 transparent_b_ = false;
26 pscore_l_=0;
27 status_i_ = 0;
30 Score_elem::Score_elem (Score_elem const&s)
31 : Directed_graph_node (s), Graphical_element (s)
33 /* called from derived ctor, so most info points to the same deps
34 as (Directed_graph_node&)s. Nobody points to us, so don't copy
35 dependents.
37 copy_edges_out (s);
38 transparent_b_ = s.transparent_b_;
39 status_i_ = s.status_i_;
40 pscore_l_ = s.pscore_l_;
43 Score_elem::~Score_elem()
45 assert (status_i_ >=0);
46 status_i_ = -1;
49 Score_elem*
50 Score_elem::dependency (int i) const
52 return (Score_elem*) get_out_edge_arr ()[i];
55 int
56 Score_elem::dependency_size () const
58 return get_out_edge_arr ().size ();
61 Score_elem*
62 Score_elem::dependent (int i) const
64 return (Score_elem*) get_in_edge_arr()[i];
67 int
68 Score_elem::dependent_size() const
70 return get_in_edge_arr().size ();
75 Interval
76 Score_elem::do_width() const
78 Interval r;
80 Molecule*m = brew_molecule_p();
81 r = m->extent().x ();
82 delete m;
84 return r;
87 Interval
88 Score_elem::do_height() const
90 Interval r;
91 Molecule*m = brew_molecule_p();
92 r = m->extent().y ();
93 delete m;
94 return r;
99 STANDARD METHS
101 void
102 Score_elem::print() const
104 #ifndef NPRINT
105 DOUT << name() << "{\n";
106 DOUT << "dets: " << dependent_size() << "dependencies: " <<
107 dependency_size();
109 Graphical_element::print ();
110 do_print();
112 DOUT << "}\n";
113 #endif
117 Paper_def*
118 Score_elem::paper() const
120 assert (pscore_l_);
121 return pscore_l_->paper_l_;
125 void
126 Score_elem::add_processing()
128 if (status_i_)
129 return;
130 status_i_ ++;
131 do_add_processing();
135 void
136 Score_elem::calcalute_dependencies (int final, int busy,
137 Score_elem_method_pointer funcptr)
139 if (status_i_ >= final)
140 return;
142 assert (status_i_!= busy);
143 status_i_= busy;
145 for (int i=0; i < dependency_size(); i++)
146 dependency (i)->calcalute_dependencies (final, busy, funcptr);
148 Link_array<Score_elem> extra (get_extra_dependencies());
149 for (int i=0; i < extra.size(); i++)
150 extra[i]->calcalute_dependencies (final, busy, funcptr);
152 invalidate_cache (X_AXIS);
153 invalidate_cache (Y_AXIS);
154 (this->*funcptr)();
155 status_i_= final;
158 void
159 Score_elem::do_brew_molecule ()
161 if (transparent_b_)
162 return;
163 Molecule *output= brew_molecule_p ();
164 pscore_l_->outputter_l_->output_molecule (output, absolute_offset ());
169 VIRTUAL STUBS
173 void
174 Score_elem::do_break_processing()
176 handle_broken_dependencies();
179 void
180 Score_elem::do_post_processing()
184 void
185 Score_elem::do_breakable_col_processing()
187 handle_prebroken_dependencies();
190 void
191 Score_elem::do_pre_processing()
195 void
196 Score_elem::do_space_processing ()
200 void
201 Score_elem::do_add_processing()
205 void
206 Score_elem::do_substitute_dependency (Score_elem*,Score_elem*)
209 void
210 Score_elem::do_substitute_dependent (Score_elem*,Score_elem*)
214 void
215 Score_elem::do_unlink()
219 void
220 Score_elem::do_junk_links()
224 IMPLEMENT_IS_TYPE_B1(Score_elem, Graphical_element);
226 Molecule*
227 Score_elem::brew_molecule_p() const
229 Atom a (paper()->lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))));
230 return new Molecule (a);
234 Line_of_score *
235 Score_elem::line_l() const
237 return 0;
242 DEPENDENCIES
246 void
247 Score_elem::remove_dependency (Score_elem*e)
249 remove_edge_out (e);
250 substitute_dependency (e, 0);
253 void
254 Score_elem::add_dependency (Score_elem*e)
256 Directed_graph_node::add (e);
258 void
259 Score_elem::substitute_dependency (Score_elem* old, Score_elem* new_l)
261 do_substitute_dependency (old,new_l);
262 old->do_substitute_dependent (this, 0);
265 void
266 Score_elem::handle_broken_dependencies()
268 Line_of_score *line = line_l();
269 if (!line)
270 return;
272 Link_array<Score_elem> remove_us_arr;
273 for (int i=0; i < dependency_size(); i++)
275 Score_elem * elt = dependency (i);
276 if (elt->line_l() != line)
278 if (elt->spanner())
280 Spanner * sp = elt->spanner();
281 Spanner * broken = sp->find_broken_piece (line);
282 substitute_dependency (sp, broken);
284 add_dependency (broken);
286 else if (elt->item())
288 Item * my_item = elt->item()->find_prebroken_piece (line);
290 substitute_dependency (elt, my_item);
291 if (my_item)
292 add_dependency (my_item);
294 remove_us_arr.push (elt);
298 remove_us_arr.default_sort();
299 remove_us_arr.uniq();
300 for (int i=0; i <remove_us_arr.size(); i++)
301 remove_dependency (remove_us_arr[i]);
305 This sux.
307 unlike with spanners, the number of items can increase
309 span: item1
311 becomes
313 span: item1 item2 item3
315 How to let span (a derived class) know that this happened?
317 void
318 Score_elem::handle_prebroken_dependencies()
320 Link_array<Score_elem> old_arr, new_arr;
322 for (int i=0; i < dependency_size(); i++)
324 Score_elem * elt = dependency (i);
325 Item *it_l = elt->item();
326 if (it_l && it_l->breakable_b_)
327 if (item())
329 Score_elem *new_l = it_l->find_prebroken_piece (item()->break_status_i_);
330 if (new_l != elt)
332 new_arr.push (new_l);
333 old_arr.push (elt);
336 else
338 new_arr.push (it_l->broken_to_drul_[LEFT]);
339 old_arr.push (0);
340 old_arr.push (0);
341 new_arr.push (it_l->broken_to_drul_[RIGHT]);
345 for (int i=0; i < old_arr.size(); i++)
346 if (old_arr[i])
347 substitute_dependency (old_arr[i], new_arr[i]);
351 void
352 Score_elem::junk_links ()
354 Directed_graph_node::junk_links();
355 Graphical_element::junk_links ();
356 do_junk_links();
359 void
360 Score_elem::unlink()
362 do_unlink();
363 while (dependency_size())
365 do_substitute_dependency (dependency (0),0);
366 remove_edge_out_idx (0);
368 while (dependent_size())
370 dependent (0)->remove_dependency (this);
372 for (int j=0; j < 2; j++)
373 if (axis_group_l_a_[j])
374 axis_group_l_a_[j]->remove_element (this);
378 Link_array<Score_elem>
379 Score_elem::get_extra_dependencies() const
381 Link_array<Score_elem> empty;
382 return empty;
385 bool
386 Score_elem::linked_b() const
388 return get_extra_dependencies().size() ||
389 dependency_size();