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>
10 #include "paper-def.hh"
12 #include "molecule.hh"
13 #include "score-elem.hh"
18 #include "scoreline.hh"
23 Score_elem::dependency(int i)const
25 return (Score_elem*) get_out_edge_arr()[i];
29 Score_elem::dependency_size() const
31 return get_out_edge_arr().size();
35 Score_elem::dependent(int i) const
37 return (Score_elem*) get_in_edge_arr()[i];
41 Score_elem::dependent_size() const
43 return get_in_edge_arr().size();
48 Score_elem::TeX_string() const
50 assert( status > POSTCALCED);
53 String s("\\placebox{%}{%}{%}");
55 a.push(print_dimen(offset_.y));
56 a.push(print_dimen(offset_.x));
57 a.push( output->TeX_string());
58 return substitute_args(s, a);
62 Score_elem::Score_elem(Score_elem const&s)
64 transparent_b_ = s.transparent_b_;
65 empty_b_ = s.empty_b_;
66 /* called from derived ctor, so most info points to the same deps
67 as (Directed_graph_node&)s. Nobody points to us, so don't copy
71 x_group_element_i_ = 0;
72 y_group_element_i_ = 0;
76 pscore_l_ = s.pscore_l_;
77 offset_ = Offset(0,0);
80 Score_elem::~Score_elem()
82 // some paranoia to prevent weird segv's
83 assert(status < DELETED);
87 assert(!x_group_element_i_ && !y_group_element_i_);
91 Score_elem::translate_x(Real x)
99 Score_elem::translate_y(Real y)
106 Score_elem::translate(Offset O)
113 Score_elem::do_width() const
118 Molecule*m = brew_molecule_p();
122 r = output->extent().x;
127 Score_elem::width() const
129 Interval r=(empty_b_)?Interval(0,0):do_width();
131 if (!r.empty_b()) // float exception on DEC Alpha
138 Score_elem::do_height() const
142 Molecule*m = brew_molecule_p();
146 r = output->extent().y;
151 Score_elem::height() const
153 Interval r=(empty_b_)?Interval(0,0): do_height();
163 Score_elem::print()const
166 mtor << name() << "{\n";
167 mtor << "dets: " << dependent_size() << "dependencies: " <<
168 dependency_size() << "\n";
179 Score_elem::Score_elem()
181 transparent_b_ = empty_b_ = false;
182 x_group_element_i_ = 0;
183 y_group_element_i_ =0;
185 offset_ = Offset(0,0);
192 Score_elem::paper() const
195 return pscore_l_->paper_l_;
199 Score_elem::add_processing()
201 if (status >= VIRGIN)
208 Score_elem::pre_processing()
210 if (status >= PRECALCED )
213 assert(status != PRECALCING); // cyclic dependency
216 for (int i=0; i < dependency_size(); i++)
217 dependency(i)->pre_processing();
225 Score_elem::breakable_col_processing()
227 if (status >= PREBROKEN )
230 assert(status != PREBREAKING); // cyclic dependency
231 status = PREBREAKING;
233 for (int i=0; i < dependency_size(); i++)
234 dependency(i)->breakable_col_processing();
237 do_breakable_col_processing();
242 Score_elem::break_processing()
244 if (status >= BROKEN )
247 assert(status != BREAKING); // cyclic dependency
250 for (int i=0; i < dependency_size(); i++)
251 dependency(i)->break_processing();
254 do_break_processing();
259 Score_elem::do_break_processing()
261 handle_broken_dependencies();
266 Score_elem::post_processing()
268 if (status >= POSTCALCED)
270 assert(status != POSTCALCING);// cyclic dependency
274 for (int i=0; i < dependency_size(); i++)
275 dependency(i)->post_processing();
276 do_post_processing();
281 Score_elem::molecule_processing()
283 if (status >= OUTPUT)
285 status = OUTPUT; // do it only once.
287 for (int i=0; i < dependency_size(); i++)
288 dependency(i)->molecule_processing();
292 output= brew_molecule_p();
296 Score_elem::do_post_processing()
301 Score_elem::do_breakable_col_processing()
303 handle_prebroken_dependencies();
307 Score_elem::do_pre_processing()
312 Score_elem::do_add_processing()
318 Score_elem::do_substitute_dependency(Score_elem*,Score_elem*)
323 IMPLEMENT_STATIC_NAME(Score_elem);
324 IMPLEMENT_IS_TYPE_B(Score_elem);
327 Score_elem::brew_molecule_p()const
329 Atom a(paper()->lookup_l()->fill(Box(Interval(0,0), Interval(0,0))));
330 return new Molecule (a);
333 Score_elem::offset() const
339 Score_elem::line_l()const
344 /********************
349 Score_elem::remove_dependency(Score_elem*e)
352 do_substitute_dependency(e, 0);
356 Score_elem::add_dependency(Score_elem*e)
358 Directed_graph_node::add(e);
363 Score_elem::handle_broken_dependencies()
365 Line_of_score *line = line_l();
369 Link_array<Score_elem> remove_us_arr;
370 for (int i=0; i < dependency_size(); i++) {
371 Score_elem * elt = dependency(i);
372 if (elt->line_l() != line){
373 if (elt->spanner()) {
374 Spanner * sp = elt->spanner();
375 Spanner * broken = sp->find_broken_piece(line);
376 do_substitute_dependency(sp, broken);
377 add_dependency(broken);
378 } else if (elt->item() && elt->item()->pcol_l_->breakpoint_b()
379 && elt->item()->break_status_i() == 0) {
380 Item * my_item = elt->item()->find_prebroken_piece(line);
381 do_substitute_dependency( elt, my_item);
383 add_dependency( my_item);
385 remove_us_arr.push(elt);
390 remove_us_arr.default_sort();
391 remove_us_arr.uniq();
392 for (int i=0; i <remove_us_arr.size(); i++)
393 remove_dependency(remove_us_arr[i]);
395 /* Reset this. If we are a (broken) copy of a spanner, then
396 break_processing() was not called on us (and we are not breaking). */
404 unlike with spanners, the number of items can increase
410 span: item1 item2 item3
412 How to let span (a derived class) know that this happened?
415 Score_elem::handle_prebroken_dependencies()
417 Link_array<Score_elem> remove_us_arr;
418 for (int i=0; i < dependency_size(); i++) {
419 Score_elem * elt = dependency(i);
420 Item *it_l = elt->item();
421 if (it_l && it_l->pcol_l_->breakable_b())
423 Score_elem *new_l = it_l->find_prebroken_piece(item()->pcol_l_);
425 do_substitute_dependency( elt, new_l);
426 remove_us_arr.push(elt);
428 add_dependency(new_l);
431 add_dependency(it_l->broken_to_a_[0]);
432 add_dependency(it_l->broken_to_a_[1]);
437 remove_us_arr.default_sort();
438 remove_us_arr.uniq();
439 for (int i=0; i <remove_us_arr.size(); i++)
440 remove_dependency(remove_us_arr[i]);
443 see comment at handle_broken_dependencies()
445 if (status < PREBROKEN)
452 Score_elem::unlink_all()
454 for (int i=0; i < dependency_size(); i++)
455 dependency(i)->unlink_all();
457 y_group_element_i_ = 0;
458 x_group_element_i_ = 0;
464 while ( dependency_size()) {
465 do_substitute_dependency(dependency(0),0);
466 remove_edge_out_idx(0);
468 while ( dependent_size() ) {
469 dependent(0)->remove_dependency(this);
476 Score_elem::OK()const
479 for (int i=0; i < dependency_size(); i++) {