X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fdot-column.cc;h=3b33e6e198f4d8fcfbfc5faf0a20e64f4abc0fa7;hb=b2023e711e576d58da3c51a4b3fd5d327a0fe013;hp=ccf4d1f9123e85d5f7ab54dd96bd2af2b639eb47;hpb=8aad615ea7bb31f49a0c2afc21eea5ff5de20437;p=lilypond.git diff --git a/lily/dot-column.cc b/lily/dot-column.cc index ccf4d1f912..3b33e6e198 100644 --- a/lily/dot-column.cc +++ b/lily/dot-column.cc @@ -3,54 +3,149 @@ source file of the GNU LilyPond music typesetter - (c) 1997--1999 Han-Wen Nienhuys + (c) 1997--2002 Han-Wen Nienhuys */ #include "dots.hh" #include "dot-column.hh" #include "rhythmic-head.hh" +#include "group-interface.hh" +#include "staff-symbol-referencer.hh" +#include "directional-element-interface.hh" +#include "side-position-interface.hh" +#include "axis-group-interface.hh" +#include "stem.hh" -void -Dot_column::add_dots (Dots *d) +/* + TODO: let Dot_column communicate with stem via Note_column. + */ + +MAKE_SCHEME_CALLBACK (Dot_column,force_shift_callback,2); +SCM +Dot_column::force_shift_callback (SCM element_smob, SCM axis) { - dot_l_arr_.push (d); - add_dependency (d); - add_element (d); + Grob *me = unsmob_grob (element_smob); + Axis a = (Axis) gh_scm2int (axis); + assert (a == Y_AXIS); + me = me->get_parent (X_AXIS); + SCM l = me->get_grob_property ("dots"); + do_shifts (l); + return gh_double2scm (0.0); } -void -Dot_column::add_head (Rhythmic_head *r) +MAKE_SCHEME_CALLBACK(Dot_column,side_position, 2); +SCM +Dot_column::side_position (SCM element_smob, SCM axis) { - if (!r->dots_l_) - return ; - - head_l_arr_.push (r); - add_dependency (r); - add_dots (r->dots_l_); + Grob *me = unsmob_grob (element_smob); + Axis a = (Axis) gh_scm2int (axis); + assert (a == X_AXIS); + + Grob * stem = unsmob_grob (me->get_grob_property ("stem")); + if (stem + && !Stem::get_beam (stem) + && Stem::duration_log (stem) > 2 + && !Stem::invisible_b (stem) + ) + { + /* + trigger stem end & direction calculation. + + This will add the stem to the support if a flag collision happens. + */ + Stem::stem_end_position (stem); + } + return Side_position_interface::aligned_side (element_smob, axis); } -void -Dot_column::do_substitute_dependency (Score_element*o,Score_element*n) + +/* + Will fuck up in this case. + + X. . + X.X . + |X . + | + | + |X . + | + | + + + Should be smarter. + */ +SCM +Dot_column::do_shifts (SCM l) { - Item *oi =dynamic_cast (o); + Link_array dots; + while (gh_pair_p (l)) + { + dots.push (unsmob_grob (ly_car (l))); + l = ly_cdr (l); + } - if (oi && dynamic_cast (oi)) - head_l_arr_.substitute (dynamic_cast (oi), - dynamic_cast(n)); - else if (oi && dynamic_cast (oi)) - dot_l_arr_.substitute (dynamic_cast (oi), - dynamic_cast (n)); + dots.sort (compare_position); + + if (dots.size () < 2) + return SCM_UNSPECIFIED; + Slice s; + s.set_empty (); + + Array taken_posns; + int conflicts = 0; + for (int i=0; i < dots.size (); i++) + { + Real p = Staff_symbol_referencer::get_position (dots[i]); + for (int j=0; j < taken_posns.size (); j++) + { + if (taken_posns[j] == (int) p) + conflicts++; + } + taken_posns.push ((int)p); + s.unite (Slice ((int)p, + (int)p)); + } + + if (!conflicts) + return SCM_UNSPECIFIED; + + int middle = s.center (); + /* + +1 -> off by one + */ + int pos = middle - dots.size () + 1; + if (! (pos % 2)) + pos ++; // center () rounds down. + + for (int i=0; i < dots.size (); pos += 2, i++) + { + Grob * d = dots[i]; + Staff_symbol_referencer::set_position (d,pos); + } + + return SCM_UNSPECIFIED; } + + void -Dot_column::do_pre_processing () +Dot_column::add_head (Grob * me, Grob *rh) { - Interval w; - for (int i=0; i < head_l_arr_.size (); i++) - w.unite (head_l_arr_[i]->extent (X_AXIS)); - - if (!w.empty_b ()) - translate_axis (w[RIGHT] - extent(X_AXIS) [LEFT],X_AXIS); + Grob * d = unsmob_grob (rh->get_grob_property ("dot")); + if (d) + { + Side_position_interface::add_support (me,rh); + + Pointer_group_interface::add_grob (me, ly_symbol2scm ("dots"), d); + d->add_offset_callback (Dot_column::force_shift_callback_proc , Y_AXIS); + Axis_group_interface::add_element (me, d); + } } + + +ADD_INTERFACE (Dot_column, "dot-column-interface", + "Interface that groups dots so they form a column", + "direction stem"); +