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
182 Molecule*m = brew_molecule_p();
183 r = m->extent().x ();
187 r = output->extent().x ();
192 Score_elem::width() const
194 return extent (X_AXIS);
198 Score_elem::extent (Axis a)const
204 r = (a == X_AXIS)? do_width(): do_height ();
207 if (!r.empty_b()) // float exception on DEC Alpha
214 Score_elem::do_height() const
219 Molecule*m = brew_molecule_p();
220 r = m->extent().y ();
224 r = output->extent().y ();
229 Score_elem::height() const
231 return extent (Y_AXIS);
238 Score_elem::print()const
241 DOUT << name() << "{\n";
242 DOUT << "dets: " << dependent_size() << "dependencies: " <<
244 if (offset_.x() || offset_.y ())
245 DOUT << "offset (" << offset_.x() << ", " << offset_.y () <<")";
256 Score_elem::Score_elem()
258 transparent_b_ = empty_b_ = false;
259 axis_group_l_a_[0] = axis_group_l_a_[1] =0;
261 offset_ = Offset (0,0);
268 Score_elem::paper() const
271 return pscore_l_->paper_l_;
275 Score_elem::add_processing()
277 if (status_ >= VIRGIN)
284 Score_elem::pre_processing()
286 if (status_ >= PRECALCED)
289 assert (status_ != PRECALCING); // cyclic dependency
290 status_ = PRECALCING;
292 for (int i=0; i < dependency_size(); i++)
293 dependency (i)->pre_processing();
295 Link_array<Score_elem> extra (get_extra_dependencies());
296 for (int i=0; i < extra.size(); i++)
297 extra[i]->pre_processing();
304 Score_elem::breakable_col_processing()
306 if (status_ >= PREBROKEN)
309 if (status_== PREBREAKING)
314 status_ = PREBREAKING;
316 for (int i=0; i < dependency_size(); i++)
317 dependency (i)->breakable_col_processing();
319 Link_array<Score_elem> extra (get_extra_dependencies());
320 for (int i=0; i < extra.size(); i++)
321 extra[i]->breakable_col_processing();
324 do_breakable_col_processing();
329 Score_elem::break_processing()
331 if (status_ >= BROKEN)
334 if (status_ == BREAKING)
341 for (int i=0; i < dependency_size(); i++)
342 dependency (i)->break_processing();
344 Link_array<Score_elem> extra (get_extra_dependencies());
345 for (int i=0; i < extra.size(); i++)
346 extra[i]->break_processing();
350 do_break_processing();
356 Score_elem::do_break_processing()
358 handle_broken_dependencies();
363 Score_elem::post_processing()
365 if (status_ >= POSTCALCED)
367 assert (status_ != POSTCALCING);// cyclic dependency
371 for (int i=0; i < dependency_size(); i++)
372 dependency (i)->post_processing();
374 Link_array<Score_elem> extra (get_extra_dependencies());
375 for (int i=0; i < extra.size(); i++)
376 extra[i]->post_processing();
379 do_post_processing();
384 Score_elem::status()const
390 Score_elem::molecule_processing()
392 if (status_ >= OUTPUT)
394 status_ = OUTPUT; // do it only once.
396 for (int i=0; i < dependency_size(); i++)
397 dependency (i)->molecule_processing();
399 Link_array<Score_elem> extra (get_extra_dependencies());
400 for (int i=0; i < extra.size(); i++)
401 extra[i]->molecule_processing();
406 output= brew_molecule_p();
415 Score_elem::do_post_processing()
420 Score_elem::do_breakable_col_processing()
422 handle_prebroken_dependencies();
426 Score_elem::do_pre_processing()
431 Score_elem::do_add_processing()
436 Score_elem::do_substitute_dependency (Score_elem*,Score_elem*)
440 Score_elem::do_substitute_dependent (Score_elem*,Score_elem*)
445 Score_elem::do_unlink()
448 IMPLEMENT_IS_TYPE_B(Score_elem);
451 Score_elem::brew_molecule_p()const
453 Atom a (paper()->lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))));
454 return new Molecule (a);
459 Score_elem::line_l()const
471 Score_elem::remove_dependency (Score_elem*e)
474 substitute_dependency (e, 0);
478 Score_elem::add_dependency (Score_elem*e)
480 Directed_graph_node::add (e);
483 Score_elem::substitute_dependency (Score_elem* old, Score_elem* new_l)
485 do_substitute_dependency (old,new_l);
486 old->do_substitute_dependent (this, 0);
490 Score_elem::junk_dependencies()
492 while ( dependency_size())
494 remove_edge_out (dependency (0));
499 Score_elem::handle_broken_dependencies()
501 Line_of_score *line = line_l();
505 Link_array<Score_elem> remove_us_arr;
506 for (int i=0; i < dependency_size(); i++)
508 Score_elem * elt = dependency (i);
509 if (elt->line_l() != line)
513 Spanner * sp = elt->spanner();
514 Spanner * broken = sp->find_broken_piece (line);
515 substitute_dependency (sp, broken);
517 add_dependency (broken);
519 else if (elt->item() && elt->item ()->pcol_l_->breakpoint_b ()
520 && elt->item()->break_status_i () == 0)
522 Item * my_item = elt->item()->find_prebroken_piece (line);
523 substitute_dependency (elt, my_item);
525 add_dependency (my_item);
527 remove_us_arr.push (elt);
531 remove_us_arr.default_sort();
532 remove_us_arr.uniq();
533 for (int i=0; i <remove_us_arr.size(); i++)
534 remove_dependency (remove_us_arr[i]);
542 unlike with spanners, the number of items can increase
548 span: item1 item2 item3
550 How to let span (a derived class) know that this happened?
553 Score_elem::handle_prebroken_dependencies()
555 Link_array<Score_elem> old_arr, new_arr;
557 for (int i=0; i < dependency_size(); i++)
559 Score_elem * elt = dependency (i);
560 Item *it_l = elt->item();
561 if (it_l && it_l->breakable_b_)
564 Score_elem *new_l = it_l->find_prebroken_piece (item()->pcol_l_);
567 new_arr.push (new_l);
572 new_arr.push (it_l->broken_to_a_[0]);
575 new_arr.push (it_l->broken_to_a_[1]);
579 for (int i=0; i < old_arr.size(); i++)
581 substitute_dependency (old_arr[i], new_arr[i]);
590 Score_elem::unlink_all()
592 for (int i=0; i < dependency_size(); i++)
593 dependency (i)->unlink_all();
594 Link_array<Score_elem> extra (get_extra_dependencies());
595 for (int i=0; i < extra.size(); i++)
596 extra[i]->unlink_all();
599 axis_group_l_a_[0] = axis_group_l_a_[1] =0;
606 while ( dependency_size())
608 do_substitute_dependency (dependency (0),0);
609 remove_edge_out_idx (0);
611 while ( dependent_size())
613 dependent (0)->remove_dependency (this);
615 for (int j=0; j < 2; j++)
616 if ( axis_group_l_a_[j])
617 axis_group_l_a_[j]->remove_element (this);
622 Score_elem::OK()const
625 for (int i=0; i < dependency_size(); i++)
627 dependency (i)->OK();
632 Link_array<Score_elem>
633 Score_elem::get_extra_dependencies()const
635 Link_array<Score_elem> empty;