X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftie-column.cc;h=c3ff0c50e672958908557893ff24fcfc71871870;hb=8fc0065379238f46977a22a90559a25833b5a75b;hp=eba1c4d8f02bd0793457d1e3ac987c69b647bbf3;hpb=fa891b75e895f16fc3871531e244abe78f9d93ff;p=lilypond.git diff --git a/lily/tie-column.cc b/lily/tie-column.cc index eba1c4d8f0..c3ff0c50e6 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -3,44 +3,57 @@ source file of the GNU LilyPond music typesetter - (c) 2000 Han-Wen Nienhuys + (c) 2000--2004 Han-Wen Nienhuys */ +#include "spanner.hh" #include "tie-column.hh" #include "group-interface.hh" #include "tie.hh" #include "directional-element-interface.hh" -#include "note-head.hh" +#include "rhythmic-head.hh" + + + + -Tie_column::Tie_column () -{ - set_elt_property ("ties", SCM_EOL); - set_empty (X_AXIS); - set_empty (Y_AXIS); - set_elt_property ("transparent", SCM_BOOL_T); -} +/* + tie dir depends on what Tie_column does. +*/ +/* + TODO: this doesn't follow standard pattern. Regularize. + */ void -Tie_column::add_tie (Tie *s) +Tie_column::add_tie (Grob*me,Grob *s) { - Group_interface g (this, "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")) { - set_bound (LEFT, s->head (LEFT)); - set_bound (RIGHT, s->head (RIGHT)); + dynamic_cast (me)->set_bound (LEFT, Tie::head (s,LEFT)); + dynamic_cast (me)->set_bound (RIGHT, Tie::head (s,RIGHT)); } - - group (this, "ties").add_element (s); - s->add_dependency (this); + 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 (Tie* const & s1, - Tie* const & s2) +tie_compare (Grob* const & s1, + Grob* const & s2) { - return sign (s1->position_f () - s2->position_f()); + return sign (Tie::get_position (s1) - Tie::get_position (s2)); } /* @@ -51,48 +64,145 @@ tie_compare (Tie* const & s1, direction of the rest is determined by their staff position. Ross forgets about the tie that is *on* the middle staff line. We - assume it goes UP. (TODO: make this settable) */ + assume it goes UP. (TODO: make me settable) */ void -Tie_column::set_directions () +Tie_column::old_directions (Grob*me) { - Link_array s = - Group_interface__extract_elements (this, (Tie*)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 (this).get (); + if (!ties.size ()) + return ; + Direction d = get_grob_direction (me); if (d) { - for (int i = s.size (); i--;) - directional_element (s[i]).set (d); + for (int i = ties.size (); i--;) + { + Grob * t = ties[i]; + set_grob_direction (t, d); + } return; } - if (s.size () == 1) + if (ties.size () == 1) { - directional_element (s[0]).set (s[0]->get_default_dir ()); + Grob * t = ties[0]; + set_grob_direction (t,Tie::get_default_dir (t)); return; } - s.sort (tie_compare); - directional_element (s[0]).set (DOWN); - s.del (0); - directional_element (s.pop ()).set (UP); - - for (int i=s.size(); i--; ) + ties.sort (tie_compare); + set_grob_direction (ties[0], DOWN); + ties.del (0); + + set_grob_direction (ties.pop (), UP); + for (int i=ties.size (); i--;) { - Real p = s[i]->position_f (); + Grob * t = ties[i]; + Real p = Tie::get_position (t); Direction d = (Direction) sign (p); if (!d) d = UP; - - directional_element (s[i]).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::do_post_processing () +Tie_column::werner_directions (Grob *me) { - set_directions (); + 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,1); +SCM +Tie_column::after_line_breaking (SCM 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"); +