X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftie-column.cc;h=c3ff0c50e672958908557893ff24fcfc71871870;hb=83c0409957c5ff1f35ef918455a7156fd550fa61;hp=346fa9992e0af2d23d664a84686408729c8d0380;hpb=fd1bf2a820fe005734e06e5424183823eed95cda;p=lilypond.git diff --git a/lily/tie-column.cc b/lily/tie-column.cc index 346fa9992e..c3ff0c50e6 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 2000 Han-Wen Nienhuys + (c) 2000--2004 Han-Wen Nienhuys */ @@ -16,40 +16,44 @@ -void -Tie_column::set_interface (Score_element*me) -{ - me->set_interface (ly_symbol2scm ("tie-column")); - me->set_extent_callback (0, X_AXIS); - me->set_extent_callback (0, Y_AXIS); -} -bool -Tie_column::has_interface (Score_element*me) -{ - return me->has_interface (ly_symbol2scm ("tie-column")); -} + +/* + tie dir depends on what Tie_column does. +*/ +/* + TODO: this doesn't follow standard pattern. Regularize. + */ void -Tie_column::add_tie (Score_element*me,Score_element *s) +Tie_column::add_tie (Grob*me,Grob *s) { - Pointer_group_interface g (me, "ties"); - if (!g.count ()) + if (s->get_parent (Y_AXIS) + && Tie_column::has_interface (s->get_parent (Y_AXIS))) + return ; + + if (! Pointer_group_interface::count (me, "ties")) { dynamic_cast (me)->set_bound (LEFT, Tie::head (s,LEFT)); dynamic_cast (me)->set_bound (RIGHT, Tie::head (s,RIGHT)); } - - Pointer_group_interface (me, "ties").add_element (s); + s->set_parent (me, Y_AXIS); + Pointer_group_interface::add_grob (me, ly_symbol2scm ("ties"), s); s->add_dependency (me); } +void +Tie_column::set_directions (Grob*me) +{ + werner_directions (me); +} + int -tie_compare (Score_element* const & s1, - Score_element* const & s2) +tie_compare (Grob* const & s1, + Grob* const & s2) { - return sign (Tie::position_f (s1) - Tie::position_f(s2)); + return sign (Tie::get_position (s1) - Tie::get_position (s2)); } /* @@ -62,55 +66,143 @@ tie_compare (Score_element* const & s1, Ross forgets about the tie that is *on* the middle staff line. We assume it goes UP. (TODO: make me settable) */ void -Tie_column::set_directions (Score_element*me) +Tie_column::old_directions (Grob*me) { - Link_array ties = - Pointer_group_interface__extract_elements (me, (Score_element*)0, "ties"); + Link_array ties = + Pointer_group_interface__extract_grobs (me, (Grob*)0, "ties"); + for (int i = ties.size (); i--;) + if (get_grob_direction (ties[i])) + ties.del (i); - Direction d = Directional_element_interface (me).get (); + if (!ties.size ()) + return ; + Direction d = get_grob_direction (me); if (d) { for (int i = ties.size (); i--;) { - Score_element * t = ties[i]; - Directional_element_interface (t).set (d); + Grob * t = ties[i]; + set_grob_direction (t, d); } return; } if (ties.size () == 1) { - Score_element * t = ties[0]; - Directional_element_interface (t).set (Tie::get_default_dir (t)); + Grob * t = ties[0]; + set_grob_direction (t,Tie::get_default_dir (t)); return; } ties.sort (tie_compare); - Directional_element_interface tie0(ties[0]); - tie0.set (DOWN); + set_grob_direction (ties[0], DOWN); ties.del (0); - Directional_element_interface tietop(ties.pop ()); - tietop.set (UP); - - for (int i=ties.size(); i--; ) + set_grob_direction (ties.pop (), UP); + for (int i=ties.size (); i--;) { - Score_element * t = ties[i]; - Real p = Tie::position_f (t); + Grob * t = ties[i]; + Real p = Tie::get_position (t); Direction d = (Direction) sign (p); if (!d) d = UP; - Directional_element_interface (t).set (d); + set_grob_direction (t, d); + } + +} + +/* + +% . The algorithm to choose the direction of the ties doesn't work +% properly. I suggest the following for applying ties sequentially +% from top to bottom: +% +% + The topmost tie is always `up'. +% +% + If there is a vertical gap to the last note above larger than +% or equal to a fifth (or sixth?), the tie is `up', otherwise it +% is `down'. +% +% + The bottommost tie is always `down'. + + */ +void +Tie_column::werner_directions (Grob *me) +{ + Link_array ties = + Pointer_group_interface__extract_grobs (me, (Grob*)0, "ties"); + + if (!ties.size ()) + return ; + + ties.sort (tie_compare); + + Direction d = get_grob_direction (me); + if (d) + { + for (int i = ties.size (); i--;) + { + Grob * t = ties[i]; + if (!get_grob_direction (t)) + set_grob_direction (t, d); + } + return ; + } + + if (ties.size () == 1) + { + Grob * t = ties[0]; + if (t->is_live () + && !get_grob_direction (t)) + set_grob_direction (t,Tie::get_default_dir (t)); + return ; } + + Real last_down_pos = 10000; + if (!get_grob_direction (ties[0])) + set_grob_direction (ties[0], DOWN); + for (int i = ties.size (); i--;) + { + Grob *t = ties[i]; + + Direction d = get_grob_direction (t); + Real p = Tie::get_position (t); + if (!d) + { + if (last_down_pos - p > 5) + { + d = UP; + } + else + { + d = DOWN; + } + + set_grob_direction (t, d); + } + + if (d == DOWN) + last_down_pos = p; + } + + return ; } -MAKE_SCHEME_CALLBACK(Tie_column,after_line_breaking); + +MAKE_SCHEME_CALLBACK (Tie_column,after_line_breaking,1); SCM Tie_column::after_line_breaking (SCM smob) { - set_directions (unsmob_element (smob)); + werner_directions (unsmob_grob (smob)); return SCM_UNSPECIFIED; } + + + +ADD_INTERFACE (Tie_column,"tie-column-interface", + "Object that sets directions of multiple ties in a tied chord", + "direction"); +