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 String t = output->TeX_string();
64 r = String("\n%start: ") + name() + "\n";
65 r += substitute_args(s, a);;
71 Score_elem::Score_elem(Score_elem const&s)
73 transparent_b_ = s.transparent_b_;
74 empty_b_ = s.empty_b_;
75 /* called from derived ctor, so most info points to the same deps
76 as (Directed_graph_node&)s. Nobody points to us, so don't copy
80 x_group_element_i_ = 0;
81 y_group_element_i_ = 0;
85 pscore_l_ = s.pscore_l_;
86 offset_ = Offset(0,0);
89 Score_elem::~Score_elem()
91 // some paranoia to prevent weird segv's
92 assert(status_ < DELETED);
96 assert(!x_group_element_i_ && !y_group_element_i_);
100 Score_elem::translate_x(Real x)
108 Score_elem::translate_y(Real y)
115 Score_elem::translate(Offset O)
122 Score_elem::do_width() const
127 Molecule*m = brew_molecule_p();
131 r = output->extent().x;
136 Score_elem::width() const
138 Interval r=(empty_b_)?Interval(0,0):do_width();
140 if (!r.empty_b()) // float exception on DEC Alpha
147 Score_elem::do_height() const
151 Molecule*m = brew_molecule_p();
155 r = output->extent().y;
160 Score_elem::height() const
162 Interval r=(empty_b_)?Interval(0,0): do_height();
172 Score_elem::print()const
175 mtor << name() << "{\n";
176 mtor << "dets: " << dependent_size() << "dependencies: " <<
178 if (offset_.x || offset_.y)
179 mtor << "offset (" << offset_.x << ", " << offset_.y <<")";
192 Score_elem::Score_elem()
194 transparent_b_ = empty_b_ = false;
195 x_group_element_i_ = 0;
196 y_group_element_i_ =0;
198 offset_ = Offset(0,0);
205 Score_elem::paper() const
208 return pscore_l_->paper_l_;
212 Score_elem::add_processing()
214 if (status_ >= VIRGIN)
221 Score_elem::pre_processing()
223 if (status_ >= PRECALCED )
226 assert(status_ != PRECALCING); // cyclic dependency
227 status_ = PRECALCING;
229 for (int i=0; i < dependency_size(); i++)
230 dependency(i)->pre_processing();
238 Score_elem::breakable_col_processing()
240 if (status_ >= PREBROKEN )
243 assert(status_ != PREBREAKING); // cyclic dependency
244 status_ = PREBREAKING;
246 for (int i=0; i < dependency_size(); i++)
247 dependency(i)->breakable_col_processing();
250 do_breakable_col_processing();
255 Score_elem::break_processing()
257 if (status_ >= BROKEN )
260 assert(status_ != BREAKING); // cyclic dependency
263 for (int i=0; i < dependency_size(); i++)
264 dependency(i)->break_processing();
267 do_break_processing();
272 Score_elem::do_break_processing()
274 handle_broken_dependencies();
279 Score_elem::post_processing()
281 if (status_ >= POSTCALCED)
283 assert(status_ != POSTCALCING);// cyclic dependency
287 for (int i=0; i < dependency_size(); i++)
288 dependency(i)->post_processing();
289 do_post_processing();
294 Score_elem::status()const
300 Score_elem::molecule_processing()
302 if (status_ >= OUTPUT)
304 status_ = OUTPUT; // do it only once.
306 for (int i=0; i < dependency_size(); i++)
307 dependency(i)->molecule_processing();
311 output= brew_molecule_p();
315 Score_elem::do_post_processing()
320 Score_elem::do_breakable_col_processing()
322 handle_prebroken_dependencies();
326 Score_elem::do_pre_processing()
331 Score_elem::do_add_processing()
337 Score_elem::do_substitute_dependency(Score_elem*,Score_elem*)
341 Score_elem::do_substitute_dependent(Score_elem*,Score_elem*)
346 IMPLEMENT_STATIC_NAME(Score_elem);
347 IMPLEMENT_IS_TYPE_B(Score_elem);
350 Score_elem::brew_molecule_p()const
352 Atom a(paper()->lookup_l()->fill(Box(Interval(0,0), Interval(0,0))));
353 return new Molecule (a);
356 Score_elem::offset() const
362 Score_elem::line_l()const
372 Score_elem::remove_dependency(Score_elem*e)
375 substitute_dependency(e, 0);
379 Score_elem::add_dependency(Score_elem*e)
381 Directed_graph_node::add(e);
384 Score_elem::substitute_dependency(Score_elem* old, Score_elem* new_l)
386 do_substitute_dependency(old,new_l);
387 old->do_substitute_dependent(this, 0);
391 Score_elem::handle_broken_dependencies()
393 Line_of_score *line = line_l();
397 Link_array<Score_elem> remove_us_arr;
398 for (int i=0; i < dependency_size(); i++) {
399 Score_elem * elt = dependency(i);
400 if (elt->line_l() != line){
401 if (elt->spanner()) {
402 Spanner * sp = elt->spanner();
403 Spanner * broken = sp->find_broken_piece(line);
404 substitute_dependency(sp, broken);
406 add_dependency(broken);
407 } else if (elt->item() && elt->item()->pcol_l_->breakpoint_b()
408 && elt->item()->break_status_i() == 0) {
409 Item * my_item = elt->item()->find_prebroken_piece(line);
410 substitute_dependency( elt, my_item);
412 add_dependency( my_item);
414 remove_us_arr.push(elt);
419 remove_us_arr.default_sort();
420 remove_us_arr.uniq();
421 for (int i=0; i <remove_us_arr.size(); i++)
422 remove_dependency(remove_us_arr[i]);
424 /* Reset this. If we are a (broken) copy of a spanner, then
425 break_processing() was not called on us (and we are not breaking). */
426 if (status_ < BROKEN)
433 unlike with spanners, the number of items can increase
439 span: item1 item2 item3
441 How to let span (a derived class) know that this happened?
444 Score_elem::handle_prebroken_dependencies()
446 Link_array<Score_elem> remove_us_arr;
447 for (int i=0; i < dependency_size(); i++) {
448 Score_elem * elt = dependency(i);
449 Item *it_l = elt->item();
450 if (it_l && it_l->pcol_l_->breakable_b())
452 Score_elem *new_l = it_l->find_prebroken_piece(item()->pcol_l_);
454 do_substitute_dependency( elt, new_l);
455 remove_us_arr.push(elt);
457 add_dependency(new_l);
460 add_dependency(it_l->broken_to_a_[0]);
461 add_dependency(it_l->broken_to_a_[1]);
466 remove_us_arr.default_sort();
467 remove_us_arr.uniq();
468 for (int i=0; i <remove_us_arr.size(); i++)
469 remove_dependency(remove_us_arr[i]);
472 see comment at handle_broken_dependencies()
474 if (status_ < PREBROKEN)
481 Score_elem::unlink_all()
483 for (int i=0; i < dependency_size(); i++)
484 dependency(i)->unlink_all();
486 y_group_element_i_ = 0;
487 x_group_element_i_ = 0;
493 while ( dependency_size()) {
494 do_substitute_dependency(dependency(0),0);
495 remove_edge_out_idx(0);
497 while ( dependent_size() ) {
498 dependent(0)->remove_dependency(this);
505 Score_elem::OK()const
508 for (int i=0; i < dependency_size(); i++) {