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>
12 #include "paper-def.hh"
14 #include "molecule.hh"
15 #include "score-elem.hh"
20 #include "scoreline.hh"
25 Score_elem::dependency(int i)const
27 return (Score_elem*) get_out_edge_arr()[i];
31 Score_elem::dependency_size() const
33 return get_out_edge_arr().size();
37 Score_elem::dependent(int i) const
39 return (Score_elem*) get_in_edge_arr()[i];
43 Score_elem::dependent_size() const
45 return get_in_edge_arr().size();
51 Score_elem::TeX_string_without_offset(Offset o)const
55 String s( "\\placebox{%}{%}{%}");
57 a.push( print_dimen(o.y() ));
58 a.push( print_dimen(o.x() ));
59 String t = output->TeX_string();
66 r = String("\n%start: ") + name() + "\n";
67 r += substitute_args(s, a);;
72 Score_elem::TeX_string() const
74 assert( status_ > POSTCALCED);
75 return TeX_string_without_offset(offset_);
79 Score_elem::copy_dependencies(Score_elem const &s)
81 /* called from derived ctor, so most info points to the same deps
82 as (Directed_graph_node&)s. Nobody points to us, so don't copy
88 Score_elem::Score_elem(Score_elem const&s)
90 transparent_b_ = s.transparent_b_;
91 empty_b_ = s.empty_b_;
92 axis_group_l_a_[0] = axis_group_l_a_[1] =0;
96 pscore_l_ = s.pscore_l_;
97 offset_ = Offset(0,0);
100 Score_elem::~Score_elem()
102 // some paranoia to prevent weird segv's
103 assert(status_ < DELETED);
114 Score_elem::absolute_coordinate(Axis a)const
117 for ( Axis_group_element * axis_group_l = axis_group_l_a_[a];
118 axis_group_l; axis_group_l = axis_group_l->axis_group_l_a_[a])
120 r += axis_group_l->offset_[a];
126 Score_elem::absolute_offset() const
128 return Offset(absolute_coordinate(X_AXIS), absolute_coordinate(Y_AXIS));
132 Score_elem::translate(Real y, Axis a)
138 Score_elem::relative_coordinate(Axis_group_element*e, Axis a)const
141 for ( Axis_group_element * axis_group_l = axis_group_l_a_[a];
143 axis_group_l = axis_group_l->axis_group_l_a_[a])
144 r += axis_group_l->offset_[a];
150 Score_elem::common_group(Score_elem const* s, Axis a)const
152 Link_array<Axis_group_element> my_groups;
153 for ( Axis_group_element * axis_group_l = axis_group_l_a_[a];
155 axis_group_l = axis_group_l->axis_group_l_a_[a])
156 my_groups.push( axis_group_l );
158 Axis_group_element* common_l=0;
159 for ( Axis_group_element * axis_group_l = s->axis_group_l_a_[a];
160 !common_l && axis_group_l;
161 axis_group_l = axis_group_l->axis_group_l_a_[a])
162 common_l = my_groups.find_l( axis_group_l );
170 Score_elem::translate(Offset O)
176 Score_elem::do_width() const
181 Molecule*m = brew_molecule_p();
185 r = output->extent().x();
190 Score_elem::width() const
192 return extent( X_AXIS);
196 Score_elem::extent(Axis a)const
201 r = (a == X_AXIS)? do_width(): do_height();
204 if (!r.empty_b()) // float exception on DEC Alpha
211 Score_elem::do_height() const
215 Molecule*m = brew_molecule_p();
219 r = output->extent().y();
224 Score_elem::height() const
226 return extent(Y_AXIS);
233 Score_elem::print()const
236 mtor << name() << "{\n";
237 mtor << "dets: " << dependent_size() << "dependencies: " <<
239 if (offset_.x() || offset_.y())
240 mtor << "offset (" << offset_.x() << ", " << offset_.y() <<")";
251 Score_elem::Score_elem()
253 transparent_b_ = empty_b_ = false;
254 axis_group_l_a_[0] = axis_group_l_a_[1] =0;
256 offset_ = Offset(0,0);
263 Score_elem::paper() const
266 return pscore_l_->paper_l_;
270 Score_elem::add_processing()
272 if (status_ >= VIRGIN)
279 Score_elem::pre_processing()
281 if (status_ >= PRECALCED )
284 assert(status_ != PRECALCING); // cyclic dependency
285 status_ = PRECALCING;
287 for (int i=0; i < dependency_size(); i++)
288 dependency(i)->pre_processing();
290 Link_array<Score_elem> extra(get_extra_dependencies());
291 for (int i=0; i < extra.size(); i++)
292 extra[i]->pre_processing();
299 Score_elem::breakable_col_processing()
301 if (status_ >= PREBROKEN )
304 if(status_== PREBREAKING) {
308 status_ = PREBREAKING;
310 for (int i=0; i < dependency_size(); i++)
311 dependency(i)->breakable_col_processing();
313 Link_array<Score_elem> extra(get_extra_dependencies());
314 for (int i=0; i < extra.size(); i++)
315 extra[i]->breakable_col_processing();
318 do_breakable_col_processing();
323 Score_elem::break_processing()
325 if (status_ >= BROKEN )
328 if (status_ == BREAKING) {
334 for (int i=0; i < dependency_size(); i++)
335 dependency(i)->break_processing();
337 Link_array<Score_elem> extra(get_extra_dependencies());
338 for (int i=0; i < extra.size(); i++)
339 extra[i]->break_processing();
343 do_break_processing();
349 Score_elem::do_break_processing()
351 handle_broken_dependencies();
356 Score_elem::post_processing()
358 if (status_ >= POSTCALCED)
360 assert(status_ != POSTCALCING);// cyclic dependency
364 for (int i=0; i < dependency_size(); i++)
365 dependency(i)->post_processing();
367 Link_array<Score_elem> extra(get_extra_dependencies());
368 for (int i=0; i < extra.size(); i++)
369 extra[i]->post_processing();
372 do_post_processing();
377 Score_elem::status()const
383 Score_elem::molecule_processing()
385 if (status_ >= OUTPUT)
387 status_ = OUTPUT; // do it only once.
389 for (int i=0; i < dependency_size(); i++)
390 dependency(i)->molecule_processing();
392 Link_array<Score_elem> extra(get_extra_dependencies());
393 for (int i=0; i < extra.size(); i++)
394 extra[i]->molecule_processing();
399 output= brew_molecule_p();
408 Score_elem::do_post_processing()
413 Score_elem::do_breakable_col_processing()
415 handle_prebroken_dependencies();
419 Score_elem::do_pre_processing()
424 Score_elem::do_add_processing()
429 Score_elem::do_substitute_dependency(Score_elem*,Score_elem*)
433 Score_elem::do_substitute_dependent(Score_elem*,Score_elem*)
438 Score_elem::do_unlink()
441 IMPLEMENT_IS_TYPE_B(Score_elem);
444 Score_elem::brew_molecule_p()const
446 Atom a(paper()->lookup_l()->fill(Box(Interval(0,0), Interval(0,0))));
447 return new Molecule (a);
452 Score_elem::line_l()const
464 Score_elem::remove_dependency(Score_elem*e)
467 substitute_dependency(e, 0);
471 Score_elem::add_dependency(Score_elem*e)
473 Directed_graph_node::add(e);
476 Score_elem::substitute_dependency(Score_elem* old, Score_elem* new_l)
478 do_substitute_dependency(old,new_l);
479 old->do_substitute_dependent(this, 0);
483 Score_elem::junk_dependencies()
485 while ( dependency_size() ) {
486 remove_edge_out( dependency( 0 ));
491 Score_elem::handle_broken_dependencies()
493 Line_of_score *line = line_l();
497 Link_array<Score_elem> remove_us_arr;
498 for (int i=0; i < dependency_size(); i++) {
499 Score_elem * elt = dependency(i);
500 if (elt->line_l() != line){
501 if (elt->spanner()) {
502 Spanner * sp = elt->spanner();
503 Spanner * broken = sp->find_broken_piece(line);
504 substitute_dependency(sp, broken);
506 add_dependency(broken);
507 } else if (elt->item() && elt->item()->pcol_l_->breakpoint_b()
508 && elt->item()->break_status_i() == 0) {
509 Item * my_item = elt->item()->find_prebroken_piece(line);
510 substitute_dependency( elt, my_item);
512 add_dependency( my_item);
514 remove_us_arr.push(elt);
518 remove_us_arr.default_sort();
519 remove_us_arr.uniq();
520 for (int i=0; i <remove_us_arr.size(); i++)
521 remove_dependency(remove_us_arr[i]);
529 unlike with spanners, the number of items can increase
535 span: item1 item2 item3
537 How to let span (a derived class) know that this happened?
540 Score_elem::handle_prebroken_dependencies()
542 Link_array<Score_elem> old_arr, new_arr;
544 for (int i=0; i < dependency_size(); i++) {
545 Score_elem * elt = dependency(i);
546 Item *it_l = elt->item();
547 if (it_l && it_l->breakable_b_)
549 Score_elem *new_l = it_l->find_prebroken_piece(item()->pcol_l_);
551 new_arr.push (new_l);
555 new_arr.push(it_l->broken_to_a_[0]);
558 new_arr.push(it_l->broken_to_a_[1]);
562 for (int i=0; i < old_arr.size(); i++)
564 substitute_dependency( old_arr[i], new_arr[i] );
573 Score_elem::unlink_all()
575 for (int i=0; i < dependency_size(); i++)
576 dependency(i)->unlink_all();
577 Link_array<Score_elem> extra(get_extra_dependencies());
578 for (int i=0; i < extra.size(); i++)
579 extra[i]->unlink_all();
582 axis_group_l_a_[0] = axis_group_l_a_[1] =0;
589 while ( dependency_size()) {
590 do_substitute_dependency(dependency(0),0);
591 remove_edge_out_idx(0);
593 while ( dependent_size() ) {
594 dependent(0)->remove_dependency(this);
596 for (int j=0; j < 2; j++)
597 if ( axis_group_l_a_[j])
598 axis_group_l_a_[j]->remove_element(this);
603 Score_elem::OK()const
606 for (int i=0; i < dependency_size(); i++) {
612 Link_array<Score_elem>
613 Score_elem::get_extra_dependencies()const
615 Link_array<Score_elem> empty;