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 ();
49 Score_elem::make_TeX_string (Offset o)const
51 String s ("\\placebox{%}{%}{%}");
53 a.push (print_dimen (o.y()));
54 a.push (print_dimen (o.x()));
55 String t = output->TeX_string();
62 r = String ("\n%start: ") + name() + "\n";
63 r += substitute_args (s, a);
67 Score_elem::do_TeX_output_str () const
69 return make_TeX_string(absolute_offset());
72 Score_elem::Score_elem (Score_elem const&s)
74 /* called from derived ctor, so most info points to the same deps
75 as (Directed_graph_node&)s. Nobody points to us, so don't copy
79 transparent_b_ = s.transparent_b_;
80 empty_b_ = s.empty_b_;
81 axis_group_l_a_[0] = axis_group_l_a_[1] =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);
102 Score_elem::absolute_coordinate (Axis a) const
105 for (Axis_group_element * axis_group_l = axis_group_l_a_[a];
106 axis_group_l; axis_group_l = axis_group_l->axis_group_l_a_[a])
108 r += axis_group_l->offset_[a];
114 Score_elem::absolute_offset() const
116 return Offset (absolute_coordinate (X_AXIS), absolute_coordinate (Y_AXIS));
120 Score_elem::translate (Real y, Axis a)
126 Score_elem::relative_coordinate (Axis_group_element*e, Axis a) const
129 for (Axis_group_element * axis_group_l = axis_group_l_a_[a];
131 axis_group_l = axis_group_l->axis_group_l_a_[a])
132 r += axis_group_l->offset_[a];
138 Score_elem::common_group (Score_elem const* s, Axis a) const
140 Link_array<Axis_group_element> my_groups;
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 my_groups.push (axis_group_l);
146 Axis_group_element* common_l=0;
147 for (Axis_group_element * axis_group_l = s->axis_group_l_a_[a];
148 !common_l && axis_group_l;
149 axis_group_l = axis_group_l->axis_group_l_a_[a])
150 common_l = my_groups.find_l (axis_group_l);
158 Score_elem::translate (Offset O)
164 Score_elem::do_width() const
170 Molecule*m = brew_molecule_p();
171 r = m->extent().x ();
175 r = output->extent().x ();
180 Score_elem::width() const
182 return extent (X_AXIS);
186 Score_elem::extent (Axis a) const
192 r = (a == X_AXIS)? do_width(): do_height ();
195 if (!r.empty_b()) // float exception on DEC Alpha
202 Score_elem::do_height() const
207 Molecule*m = brew_molecule_p();
208 r = m->extent().y ();
212 r = output->extent().y ();
217 Score_elem::height() const
219 return extent (Y_AXIS);
226 Score_elem::print() const
229 DOUT << name() << "{\n";
230 DOUT << "dets: " << dependent_size() << "dependencies: " <<
232 if (offset_.x() || offset_.y ())
233 DOUT << "offset (" << offset_.x() << ", " << offset_.y () <<")";
244 Score_elem::Score_elem()
246 transparent_b_ = empty_b_ = false;
247 axis_group_l_a_[0] = axis_group_l_a_[1] =0;
249 offset_ = Offset (0,0);
256 Score_elem::paper() const
259 return pscore_l_->paper_l_;
263 Score_elem::add_processing()
265 if (status_ >= VIRGIN)
272 Score_elem::pre_processing()
274 if (status_ >= PRECALCED)
277 assert (status_ != PRECALCING); // cyclic dependency
278 status_ = PRECALCING;
280 for (int i=0; i < dependency_size(); i++)
281 dependency (i)->pre_processing();
283 Link_array<Score_elem> extra (get_extra_dependencies());
284 for (int i=0; i < extra.size(); i++)
285 extra[i]->pre_processing();
292 Score_elem::breakable_col_processing()
294 if (status_ >= PREBROKEN)
297 if (status_== PREBREAKING)
302 status_ = PREBREAKING;
304 for (int i=0; i < dependency_size(); i++)
305 dependency (i)->breakable_col_processing();
307 Link_array<Score_elem> extra (get_extra_dependencies());
308 for (int i=0; i < extra.size(); i++)
309 extra[i]->breakable_col_processing();
312 do_breakable_col_processing();
317 Score_elem::break_processing()
319 if (status_ >= BROKEN)
322 if (status_ == BREAKING)
329 for (int i=0; i < dependency_size(); i++)
330 dependency (i)->break_processing();
332 Link_array<Score_elem> extra (get_extra_dependencies());
333 for (int i=0; i < extra.size(); i++)
334 extra[i]->break_processing();
338 do_break_processing();
344 Score_elem::do_break_processing()
346 handle_broken_dependencies();
351 Score_elem::post_processing()
353 if (status_ >= POSTCALCED)
355 assert (status_ != POSTCALCING);// cyclic dependency
359 for (int i=0; i < dependency_size(); i++)
360 dependency (i)->post_processing();
362 Link_array<Score_elem> extra (get_extra_dependencies());
363 for (int i=0; i < extra.size(); i++)
364 extra[i]->post_processing();
367 do_post_processing();
372 Score_elem::status() const
378 Score_elem::molecule_processing()
380 if (status_ >= BREWED)
382 status_ = BREWED; // do it only once.
384 for (int i=0; i < dependency_size(); i++)
385 dependency (i)->molecule_processing();
387 Link_array<Score_elem> extra (get_extra_dependencies());
388 for (int i=0; i < extra.size(); i++)
389 extra[i]->molecule_processing();
394 output= brew_molecule_p();
398 Score_elem::TeX_output_str() const
401 if (status_ >= TEXOUTPUT)
404 ((Score_elem*)this)->status_ = TEXOUTPUT;
406 for (int i=0; i < dependency_size(); i++)
407 s += dependency (i)->TeX_output_str();
409 Link_array<Score_elem> extra (get_extra_dependencies());
410 for (int i=0; i < extra.size(); i++)
411 s += extra[i]->TeX_output_str ();
414 s+= do_TeX_output_str();
425 Score_elem::do_post_processing()
430 Score_elem::do_breakable_col_processing()
432 handle_prebroken_dependencies();
436 Score_elem::do_pre_processing()
441 Score_elem::do_add_processing()
446 Score_elem::do_substitute_dependency (Score_elem*,Score_elem*)
450 Score_elem::do_substitute_dependent (Score_elem*,Score_elem*)
455 Score_elem::do_unlink()
460 Score_elem::do_junk_links()
464 IMPLEMENT_IS_TYPE_B(Score_elem);
467 Score_elem::brew_molecule_p() const
469 Atom a (paper()->lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))));
470 return new Molecule (a);
475 Score_elem::line_l() const
487 Score_elem::remove_dependency (Score_elem*e)
490 substitute_dependency (e, 0);
494 Score_elem::add_dependency (Score_elem*e)
496 Directed_graph_node::add (e);
499 Score_elem::substitute_dependency (Score_elem* old, Score_elem* new_l)
501 do_substitute_dependency (old,new_l);
502 old->do_substitute_dependent (this, 0);
506 Score_elem::handle_broken_dependencies()
508 Line_of_score *line = line_l();
512 Link_array<Score_elem> remove_us_arr;
513 for (int i=0; i < dependency_size(); i++)
515 Score_elem * elt = dependency (i);
516 if (elt->line_l() != line)
520 Spanner * sp = elt->spanner();
521 Spanner * broken = sp->find_broken_piece (line);
522 substitute_dependency (sp, broken);
524 add_dependency (broken);
526 else if (elt->item())
528 Item * my_item = elt->item()->find_prebroken_piece (line);
530 substitute_dependency (elt, my_item);
532 add_dependency (my_item);
534 remove_us_arr.push (elt);
538 remove_us_arr.default_sort();
539 remove_us_arr.uniq();
540 for (int i=0; i <remove_us_arr.size(); i++)
541 remove_dependency (remove_us_arr[i]);
549 unlike with spanners, the number of items can increase
555 span: item1 item2 item3
557 How to let span (a derived class) know that this happened?
560 Score_elem::handle_prebroken_dependencies()
562 Link_array<Score_elem> old_arr, new_arr;
564 for (int i=0; i < dependency_size(); i++)
566 Score_elem * elt = dependency (i);
567 Item *it_l = elt->item();
568 if (it_l && it_l->breakable_b_)
571 Score_elem *new_l = it_l->find_prebroken_piece (item()->break_status_i_);
574 new_arr.push (new_l);
580 new_arr.push (it_l->broken_to_drul_[LEFT]);
583 new_arr.push (it_l->broken_to_drul_[RIGHT]);
587 for (int i=0; i < old_arr.size(); i++)
589 substitute_dependency (old_arr[i], new_arr[i]);
598 Score_elem::unlink_all()
600 for (int i=0; i < dependency_size(); i++)
601 dependency (i)->unlink_all();
602 Link_array<Score_elem> extra (get_extra_dependencies());
603 for (int i=0; i < extra.size(); i++)
604 extra[i]->unlink_all();
607 axis_group_l_a_[X_AXIS] = axis_group_l_a_[Y_AXIS] =0;
615 while (dependency_size())
617 do_substitute_dependency (dependency (0),0);
618 remove_edge_out_idx (0);
620 while (dependent_size())
622 dependent (0)->remove_dependency (this);
624 for (int j=0; j < 2; j++)
625 if (axis_group_l_a_[j])
626 axis_group_l_a_[j]->remove_element (this);
631 Score_elem::OK() const
634 for (int i=0; i < dependency_size(); i++)
636 dependency (i)->OK();
641 Link_array<Score_elem>
642 Score_elem::get_extra_dependencies() const
644 Link_array<Score_elem> empty;
649 Score_elem::linked_b() const
651 return get_extra_dependencies().size() ||