From: hanwen Date: Mon, 19 Jan 2004 13:45:36 +0000 (+0000) Subject: * lily/tie-column.cc (werner_directions): new function X-Git-Tag: release/2.1.13~9 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=f160249bd764cd7e6670dd922ca1a9897184ab4d;p=lilypond.git * lily/tie-column.cc (werner_directions): new function * lily/tie.cc (set_direction): call Tie_column::set_direction () * lily/axis-group-engraver.cc (process_acknowledged_grobs): give empty objects group spanner as parent --- diff --git a/ChangeLog b/ChangeLog index 87d8afc3fa..0d6fdd2e16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2004-01-19 Han-Wen Nienhuys + * lily/tie-column.cc (werner_directions): new function + + * lily/tie.cc (set_direction): call Tie_column::set_direction () + + * lily/axis-group-engraver.cc (process_acknowledged_grobs): give + empty objects group spanner as parent + * lily/tuplet-bracket.cc (calc_position_and_height): check musical slope against graphical slope. diff --git a/lily/axis-group-engraver.cc b/lily/axis-group-engraver.cc index 94a873bc9c..0cff96e946 100644 --- a/lily/axis-group-engraver.cc +++ b/lily/axis-group-engraver.cc @@ -113,9 +113,18 @@ Axis_group_engraver::process_acknowledged_grobs () { Grob *par = elts_[i]->get_parent (Y_AXIS); - if ((!par || !Axis_group_interface::has_interface (par)) - && ! elts_[i]->empty_b (Y_AXIS)) - add_element (elts_[i]); + if (!par || !Axis_group_interface::has_interface (par)) + if (elts_[i]->empty_b (Y_AXIS)) + { + /* + We have to do _something_, otherwise staff objects will + end up with System as parent. + + */ + elts_[i]->set_parent (staffline_, Y_AXIS); + } + else + add_element (elts_[i]); } elts_.clear (); } diff --git a/lily/include/tie-column.hh b/lily/include/tie-column.hh index 5b2ec8e61d..10c26e8dab 100644 --- a/lily/include/tie-column.hh +++ b/lily/include/tie-column.hh @@ -19,8 +19,10 @@ class Tie_column public: static bool has_interface (Grob*); static void add_tie (Grob*me,Grob*); - DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM )); + DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM)); static void set_directions (Grob*me); + static void old_directions (Grob*me); + static void werner_directions (Grob*me); }; #endif /* TIE_COLUMN_HH */ diff --git a/lily/include/tie.hh b/lily/include/tie.hh index 79c036b0b9..3489c157d5 100644 --- a/lily/include/tie.hh +++ b/lily/include/tie.hh @@ -20,6 +20,7 @@ public: static void set_head (Grob*,Direction, Grob*head); static void set_interface (Grob*); static bool has_interface (Grob*); + static void set_direction (Grob*); static Grob * head (Grob*,Direction) ; static Real get_position (Grob*) ; DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM )); diff --git a/lily/tie-column.cc b/lily/tie-column.cc index 0f43e88515..0b76bbb362 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -26,17 +26,29 @@ void Tie_column::add_tie (Grob*me,Grob *s) { - if (! Pointer_group_interface ::count (me, "ties")) + 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)); } - + 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 (Grob* const & s1, Grob* const & s2) @@ -54,7 +66,7 @@ tie_compare (Grob* 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 (Grob*me) +Tie_column::old_directions (Grob*me) { Link_array ties = Pointer_group_interface__extract_grobs (me, (Grob*)0, "ties"); @@ -103,11 +115,88 @@ Tie_column::set_directions (Grob*me) } +/* + +% . 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]; + 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) { - set_directions (unsmob_grob (smob)); + werner_directions (unsmob_grob (smob)); return SCM_UNSPECIFIED; } diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index cdc2bf0fb3..b3da14d39a 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -53,7 +53,6 @@ protected: virtual void acknowledge_grob (Grob_info); virtual bool try_music (Music*); virtual void process_music (); - virtual void process_acknowledged_grobs (); void typeset_tie (Grob*); public: TRANSLATOR_DECLARATIONS(Tie_engraver); @@ -117,20 +116,16 @@ Tie_engraver::acknowledge_grob (Grob_info i) announce_grob(p, last_event_->self_scm()); } } - } -} -void -Tie_engraver::process_acknowledged_grobs () -{ - if (ties_.size () > 1 && !tie_column_) - { - tie_column_ = new Spanner (get_property ("TieColumn")); - - for (int i = ties_.size (); i--;) - Tie_column::add_tie (tie_column_,ties_ [i]); + if (ties_.size () && ! tie_column_) + { + tie_column_ = new Spanner (get_property ("TieColumn")); + announce_grob(tie_column_, SCM_EOL); + } - announce_grob(tie_column_, SCM_EOL); + if (tie_column_) + for (int i = ties_.size (); i--;) + Tie_column::add_tie (tie_column_,ties_ [i]); } } diff --git a/lily/tie.cc b/lily/tie.cc index 85d838f02d..bd569c4f87 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -22,6 +22,7 @@ #include "bezier-bow.hh" #include "stem.hh" #include "note-head.hh" +#include "tie-column.hh" /* tie: Connect two noteheads. @@ -102,6 +103,19 @@ Tie::get_default_dir (Grob*me) return UP; } + +void +Tie::set_direction (Grob*me) +{ + if (!get_grob_direction (me)) + { + if (Tie_column::has_interface (me->get_parent (Y_AXIS))) + Tie_column::set_directions (me->get_parent (Y_AXIS)); + else + set_grob_direction (me, Tie::get_default_dir (me)); + } +} + /* TODO: we should also use thickness for computing the clearance between head and tie. Very thick ties will now touch the note head. @@ -123,9 +137,8 @@ Tie::get_control_points (SCM smob) return SCM_UNSPECIFIED; } - - if (!get_grob_direction (me)) - set_grob_direction (me, Tie::get_default_dir (me)); + set_direction (me); + Direction dir = get_grob_direction (me); Real staff_space = Staff_symbol_referencer::staff_space (me); diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index d963bf5a7c..f9d50fdf77 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1124,8 +1124,8 @@ (TieColumn . ( (after-line-breaking-callback . ,Tie_column::after_line_breaking) - (X-extent-callback . ()) - (Yoo-extent-callback . ()) + (X-extent-callback . #f) + (Y-extent-callback . #f) (meta . ((interfaces . (tie-column-interface spanner-interface)))) ))