CVSROOT: /cvsroot/lilypond Module name: lilypond Branch: Changes by: Han-Wen Nienhuys <[EMAIL PROTECTED]> 05/08/22 14:03:11
Modified files: . : ChangeLog Documentation/topdocs: NEWS.tely flower/include : interval.hh interval.tcc lily : skyline.cc tie-column.cc tie.cc lily/include : skyline.hh tie-column.hh tie.hh python : convertrules.py scm : define-grob-properties.scm Added files: lily : tie-helper.cc Log message: * flower/include/interval.hh (struct Interval_t): * lily/tie.cc (distance): new function (height): new function. (init): new function (Tie_details): new struct. * lily/skyline.cc (skyline_height): new function. * lily/tie-column.cc (set_chord_outlines): new function. (new_directions): read tie-configuration * lily/skyline.cc: fix ASCII art. CVSWeb URLs: http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/ChangeLog.diff?tr1=1.4057&tr2=1.4058&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/Documentation/topdocs/NEWS.tely.diff?tr1=1.74&tr2=1.75&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/flower/include/interval.hh.diff?tr1=1.51&tr2=1.52&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/flower/include/interval.tcc.diff?tr1=1.40&tr2=1.41&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/tie-helper.cc?rev=1.1 http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/skyline.cc.diff?tr1=1.15&tr2=1.16&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/tie-column.cc.diff?tr1=1.51&tr2=1.52&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/tie.cc.diff?tr1=1.150&tr2=1.151&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/include/skyline.hh.diff?tr1=1.7&tr2=1.8&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/include/tie-column.hh.diff?tr1=1.23&tr2=1.24&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/lily/include/tie.hh.diff?tr1=1.55&tr2=1.56&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/python/convertrules.py.diff?tr1=1.12&tr2=1.13&r1=text&r2=text http://savannah.gnu.org/cgi-bin/viewcvs/lilypond/lilypond/scm/define-grob-properties.scm.diff?tr1=1.117&tr2=1.118&r1=text&r2=text Patches: Index: lilypond/ChangeLog diff -u lilypond/ChangeLog:1.4057 lilypond/ChangeLog:1.4058 --- lilypond/ChangeLog:1.4057 Mon Aug 22 12:12:37 2005 +++ lilypond/ChangeLog Mon Aug 22 14:03:10 2005 @@ -1,9 +1,25 @@ +2005-08-22 Han-Wen Nienhuys <[EMAIL PROTECTED]> + + * flower/include/interval.hh (struct Interval_t): + + * lily/tie.cc (distance): new function + (height): new function. + (init): new function + (Tie_details): new struct. + + * lily/skyline.cc (skyline_height): new function. + + * lily/tie-column.cc (set_chord_outlines): new function. + (new_directions): read tie-configuration + + * lily/skyline.cc: fix ASCII art. + 2005-08-22 Mats Bengtsson <[EMAIL PROTECTED]> * python/convertrules.py (string_or_scheme): Fix spelling error 2005-08-22 Han-Wen Nienhuys <[EMAIL PROTECTED]> - + * lily/tie-column.cc (set_directions): set directions only once. (add_configuration): new function. Index: lilypond/Documentation/topdocs/NEWS.tely diff -u lilypond/Documentation/topdocs/NEWS.tely:1.74 lilypond/Documentation/topdocs/NEWS.tely:1.75 --- lilypond/Documentation/topdocs/NEWS.tely:1.74 Sun Aug 21 21:47:15 2005 +++ lilypond/Documentation/topdocs/NEWS.tely Mon Aug 22 14:03:11 2005 @@ -37,6 +37,23 @@ @itemize @bullet @item +Formatting of ties in chords has been improved. Ties no longer collide +with note heads and stems. In addition, it is possible to manually +specify tie formatting + [EMAIL PROTECTED], fragment,raggedright] + <a c d f> ~ <a c d f> + + \override TieColumn #'tie-configuration = + #'((0 . -1) (2 . -1) (5.5 . 1) (7 . 1)) + <b d f g> ~ <b d f g> [EMAIL PROTECTED] lilypond + +This improvement has been sponsored by Bertalan Fodor, Jay Hamilton, +Kieren MacMillan, Steve Doonan, by Trevor Baca, and +Vicente Solsona Dellá. + [EMAIL PROTECTED] Formatting of isolated, single ties has been improved. Now, ties avoid staff lines, flags and dots, without compromising their shape. @@ -49,7 +66,8 @@ @end lilypond This improvement has been sponsored by Bertalan Fodor, Jay Hamilton, -Kieren MacMillan, Steve Doonan, by Trevor Baca, and Vincent SD. +Kieren MacMillan, Steve Doonan, by Trevor Baca, and Vicente Solsona +Dellá. @item Index: lilypond/flower/include/interval.hh diff -u lilypond/flower/include/interval.hh:1.51 lilypond/flower/include/interval.hh:1.52 --- lilypond/flower/include/interval.hh:1.51 Fri Aug 12 00:04:47 2005 +++ lilypond/flower/include/interval.hh Mon Aug 22 14:03:11 2005 @@ -109,7 +109,7 @@ } String to_string () const; - bool contains (T r); + bool contains (T r) const; void negate () { T r = -elem (LEFT); Index: lilypond/flower/include/interval.tcc diff -u lilypond/flower/include/interval.tcc:1.40 lilypond/flower/include/interval.tcc:1.41 --- lilypond/flower/include/interval.tcc:1.40 Sat Aug 13 21:35:23 2005 +++ lilypond/flower/include/interval.tcc Mon Aug 22 14:03:11 2005 @@ -115,7 +115,7 @@ template<class T> bool -Interval_t<T>::contains (T r) +Interval_t<T>::contains (T r) const { return r >= elem (LEFT) && r <= elem (RIGHT); } Index: lilypond/lily/include/skyline.hh diff -u lilypond/lily/include/skyline.hh:1.7 lilypond/lily/include/skyline.hh:1.8 --- lilypond/lily/include/skyline.hh:1.7 Thu Mar 10 14:36:12 2005 +++ lilypond/lily/include/skyline.hh Mon Aug 22 14:03:11 2005 @@ -33,5 +33,9 @@ skyline_meshing_distance (Array<Skyline_entry> const &buildings, Array<Skyline_entry> const &clouds); +Real +skyline_height (Array<Skyline_entry> const &buildings, + Real airplane, Direction sky_dir); + #endif /* SKYLINE_HH */ Index: lilypond/lily/include/tie-column.hh diff -u lilypond/lily/include/tie-column.hh:1.23 lilypond/lily/include/tie-column.hh:1.24 --- lilypond/lily/include/tie-column.hh:1.23 Mon Aug 22 00:58:02 2005 +++ lilypond/lily/include/tie-column.hh Mon Aug 22 14:03:11 2005 @@ -20,7 +20,6 @@ DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM)); DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM)); static void set_directions (Grob *me); - static void werner_directions (Grob *me); static void new_directions (Grob *me); }; Index: lilypond/lily/include/tie.hh diff -u lilypond/lily/include/tie.hh:1.55 lilypond/lily/include/tie.hh:1.56 --- lilypond/lily/include/tie.hh:1.55 Mon Aug 22 00:58:02 2005 +++ lilypond/lily/include/tie.hh Mon Aug 22 14:03:11 2005 @@ -11,20 +11,42 @@ #include "lily-guile.hh" #include "lily-proto.hh" +#include "skyline.hh" + +Interval +get_skyline_attachment (Drul_array< Array < Skyline_entry > > const &skylines, + Real y1); + +struct Tie_details +{ + Real height_limit_; + Real ratio_; + Real staff_space_; + + Tie_details (); + void init (Grob *); +}; + struct Tie_configuration { - int position_; + Real position_; Direction dir_; Interval attachment_x_; Real delta_y_; Tie_configuration (); + void center_tie_vertically (Tie_details const &); + Bezier get_bezier (Tie_details const &) const; + Real height (Tie_details const&) const; static int compare (Tie_configuration const &a, Tie_configuration const &b); + static Real distance (Tie_configuration const &a, + Tie_configuration const &b); }; + INSTANTIATE_COMPARE (Tie_configuration, Tie_configuration::compare); class Tie @@ -35,15 +57,21 @@ static void set_direction (Grob *); static Grob *head (Grob *, Direction); static int get_column_rank (Grob *, Direction); - static Real get_position (Grob *); + static int get_position (Grob *); static Direction get_default_dir (Grob *); - static void get_configuration (Grob *, Grob **, Tie_configuration *); - static void set_control_points (Grob *, Grob **,Tie_configuration const&); + static void get_configuration (Grob *, Grob *, Tie_configuration *, + Drul_array< Array<Skyline_entry> > const *, + Tie_details const & + ); + static void set_control_points (Grob *, Grob *,Tie_configuration const&, + Tie_details const& + ); static void set_default_control_points (Grob *); DECLARE_SCHEME_CALLBACK (print, (SCM)); DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM)); static int compare (Grob *const &s1, Grob *const &s2); + }; Index: lilypond/lily/skyline.cc diff -u lilypond/lily/skyline.cc:1.15 lilypond/lily/skyline.cc:1.16 --- lilypond/lily/skyline.cc:1.15 Fri Aug 12 00:04:45 2005 +++ lilypond/lily/skyline.cc Mon Aug 22 14:03:11 2005 @@ -12,20 +12,18 @@ A skyline is a shape of the form: - ---- - | | - ---------| | - | | - | | - | |______ - --------| |___ - - + * ---- + * | | + * ---------| | + * | | + * | | + * | |______ + * --------| |___ + * This file deals with building such skyline structure, and computing the minimum distance between two opposing skylines. - Invariants for a skyline: skyline[...].width_ forms a partition of the real interval, where @@ -183,3 +181,22 @@ for (int i = 0; i < buildings->size (); i++) buildings->elem_ref (i).height_ += ground; } + +Real +skyline_height (Array<Skyline_entry> const &buildings, + Real airplane, + Direction sky_dir) +{ + Real h = - sky_dir * infinity_f; + + /* + Ugh! linear, should be O(log n). + */ + for (int i = 0; i < buildings.size (); i++) + if (buildings[i].width_.contains (airplane)) + h = sky_dir * max (sky_dir * h, + sky_dir * buildings[i].height_); + + return h; +} + Index: lilypond/lily/tie-column.cc diff -u lilypond/lily/tie-column.cc:1.51 lilypond/lily/tie-column.cc:1.52 --- lilypond/lily/tie-column.cc:1.51 Mon Aug 22 00:58:01 2005 +++ lilypond/lily/tie-column.cc Mon Aug 22 14:03:11 2005 @@ -6,10 +6,13 @@ (c) 2000--2005 Han-Wen Nienhuys <[EMAIL PROTECTED]> */ - #include <math.h> + #include <map> +#include <set> +#include "stem.hh" +#include "skyline.hh" #include "staff-symbol-referencer.hh" #include "warn.hh" #include "tie-column.hh" @@ -55,89 +58,6 @@ return sign (Tie::get_position (s1) - Tie::get_position (s2)); } -/* - Werner: - - . 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) -{ - extract_grob_set (me, "ties", ro_ties); - Link_array<Grob> ties (ro_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); - - /* - Go downward. - */ - Grob *last_tie = 0; - 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_tie - && Tie::get_column_rank (t, LEFT) - < Tie::get_column_rank (last_tie, LEFT)) - d = DOWN; - else if (last_down_pos - p > 5) - d = UP; - else - d = DOWN; - - set_grob_direction (t, d); - } - - if (d == DOWN) - last_down_pos = p; - - last_tie = t; - } - - return; -} - MAKE_SCHEME_CALLBACK (Tie_column, after_line_breaking, 1); SCM Tie_column::after_line_breaking (SCM smob) @@ -169,68 +89,86 @@ return SCM_UNSPECIFIED; } -ADD_INTERFACE (Tie_column, "tie-column-interface", - "Object that sets directions of multiple ties in a tied chord", - "direction " - "positioning-done " - ); - - -bool -config_allowed (map<Tie_configuration, bool> const &allowed, - Tie_configuration conf) -{ - return allowed.find (conf) == allowed.end (); -} - void -add_configuration (map<Tie_configuration, bool> *allowed, - Grob *tie_column, - Tie_configuration new_conf) +set_chord_outlines (Drul_array< Array<Skyline_entry> > *skyline_drul, + Link_array<Grob> ties, + Grob *common) { - bool on_line = Staff_symbol_referencer::on_staffline (tie_column, new_conf.position_); - - if (allowed->find (new_conf) != allowed->end () - && !(*allowed)[new_conf]) - { - programming_error ("Tie configuration not allowed"); - } - + Direction d = LEFT; - if (on_line) + Real staff_space = Staff_symbol_referencer::staff_space (ties[0]); + do { - Tie_configuration forbidden; + Array<Box> boxes; + Interval x_union; - forbidden.dir_ = -new_conf.dir_ ; - forbidden.position_ = new_conf.position_; - (*allowed)[forbidden] = false; + Grob *stem = 0; + for (int i = 0; i < ties.size (); i++) + { + Spanner *tie = dynamic_cast<Spanner*> (ties[i]); - forbidden.position_ += new_conf.dir_; - (*allowed)[forbidden] = false; - forbidden.position_ += new_conf.dir_; - (*allowed)[forbidden] = false; + Grob *head = Tie::head (tie, d); + if (!head) + continue; + + if (!stem) + stem = unsmob_grob (head->get_object ("stem")); + + Real p = Tie::get_position (tie); + Interval y ((p-1) * 0.5 * staff_space, + (p+1) * 0.5 * staff_space); + + Interval x = head->extent (common, X_AXIS); + boxes.push (Box (x, y)); + x_union.unite (x); + } - forbidden.dir_ = new_conf.dir_; - forbidden.position_ = new_conf.position_ + new_conf.dir_; - (*allowed)[forbidden] = false; - } - else - { - Tie_configuration forbidden; - forbidden.dir_ = - new_conf.dir_; - forbidden.position_ = new_conf.position_; + (*skyline_drul)[d] = empty_skyline (-d); + for (int i = 0; i < boxes.size (); i++) + insert_extent_into_skyline (&skyline_drul->elem_ref (d), + boxes[i], Y_AXIS, -d); - - (*allowed)[forbidden] = false; - forbidden.position_ -= new_conf.dir_; - forbidden.dir_ = new_conf.dir_; - (*allowed)[forbidden] = false; + Direction updowndir = DOWN; + do + { + Box b = boxes.boundary (updowndir, 0); + Interval x = b[X_AXIS]; + x[-d] = b[X_AXIS].linear_combination (-d / 2); + if (stem + && !Stem::is_invisible (stem) + && updowndir == get_grob_direction (stem)) + x.unite (robust_relative_extent (stem, common, X_AXIS)); + + (*skyline_drul)[d].boundary (updowndir, 0).height_ = x[-d]; + } + while (flip (&updowndir) != DOWN); - forbidden.position_ += 2* new_conf.dir_; - (*allowed)[forbidden] = false; + for (int i = 0; i < ties.size (); i++) + { + Spanner *tie = dynamic_cast<Spanner*> (ties[i]); + Grob *head = Tie::head (tie, d); + if (!head) + continue; + + Grob *dots = unsmob_grob (head->get_object ("dot")); + if (dots) + { + Interval x = dots->extent (common, X_AXIS); + Real p = Staff_symbol_referencer::get_position (dots); + + Interval y (-1,1); + y *= (staff_space /4); + y.translate ( p * staff_space * .5); + + insert_extent_into_skyline (&skyline_drul->elem_ref (d), + Box (x,y), Y_AXIS, -d); + } + } + } + while (flip (&d) != LEFT); } @@ -249,22 +187,37 @@ } ties.sort (&Tie::compare); + Array<Tie_configuration> tie_configs; for (int i = 0; i < ties.size (); i++) { Tie_configuration conf; conf.dir_ = get_grob_direction (ties[i]); - conf.position_ = (int) rint (Tie::get_position (ties[i])); + conf.position_ = Tie::get_position (ties[i]); tie_configs.push (conf); } - + SCM manual_configs = me->get_property ("tie-configuration"); + bool manual_override = false; + int k = 0; + for (SCM s = manual_configs; + scm_is_pair (s) && k < tie_configs.size(); s = scm_cdr (s)) + { + SCM entry = scm_car (s); + if (!scm_is_pair (entry)) + continue; + + manual_override = true; + tie_configs[k].position_ = robust_scm2double (scm_car (entry), tie_configs[k].position_); + tie_configs[k].dir_ = Direction (robust_scm2int (scm_cdr (entry), tie_configs[k].dir_)); + k ++; + } + if (!tie_configs[0].dir_) tie_configs[0].dir_ = DOWN; if (!tie_configs.top().dir_) tie_configs.top().dir_ = UP; - /* Seconds */ @@ -287,66 +240,107 @@ tie_configs[i].dir_ = (Direction) sign (tie_configs[i].position_); } - Grob *common[NO_AXES] = { - me, me - }; + Grob *common = me; for (int i = 0; i < ties.size (); i++) - for (int a = X_AXIS; a < NO_AXES; a++) - { - Axis ax ((Axis) a); - - common[ax] = dynamic_cast<Spanner*> (ties[i])->get_bound (LEFT)->common_refpoint (common[a], ax); - common[ax] = dynamic_cast<Spanner*> (ties[i])->get_bound (RIGHT)->common_refpoint (common[a], ax); - } - - map<Tie_configuration, bool> allowed; + { + common = dynamic_cast<Spanner*> (ties[i])->get_bound (LEFT)->common_refpoint (common, X_AXIS); + common = dynamic_cast<Spanner*> (ties[i])->get_bound (RIGHT)->common_refpoint (common, X_AXIS); + } - Tie::get_configuration (ties[0], common, &tie_configs.elem_ref (0)); - Tie::get_configuration (ties.top (), common, - &tie_configs.elem_ref (tie_configs.size()-1)); + Drul_array< Array<Skyline_entry> > skylines; + set_chord_outlines (&skylines, ties, common); + + Tie_details details; + details.init (ties[0]); - add_configuration (&allowed, me, tie_configs[0]); - add_configuration (&allowed, me, tie_configs.top()); + /* + Let the ties flow out, according to our single-tie formatting. + */ + if (!manual_override) + { + Tie::get_configuration (ties[0], common, &tie_configs.elem_ref (0), + &skylines, + details + ); + Tie::get_configuration (ties.top (), common, + &tie_configs.elem_ref (tie_configs.size()-1), + &skylines, + details + ); + } - for (int i = 1; i < ties.size(); i++) + /* + Calculate final width and shape of the ties. + */ + Real staff_space = Staff_symbol_referencer::staff_space (ties[0]); + Real gap = robust_scm2double (ties[0]->get_property ("x-gap"), 0.2); + for (int i = 0; i < ties.size(); i++) { + if (!manual_override + && (i == 0 || i == ties.size () -1)) + continue; + Tie_configuration conf = tie_configs[i]; - Tie::get_configuration (ties[i], common, &conf); - if (!config_allowed (allowed, conf)) - { - conf = tie_configs[i]; + conf = tie_configs[i]; + + Real line_dy = 0.0; + bool on_line = Staff_symbol_referencer::on_staffline (ties[0], + int (rint (conf.position_))); + if (on_line) + line_dy = - sign (conf.height (details) - 0.6 * staff_space) + * 0.2 * staff_space * conf.dir_; + + Real y = conf.position_ * staff_space * 0.5 + + line_dy; + conf.attachment_x_ + = get_skyline_attachment (skylines, y); + conf.attachment_x_.intersect (get_skyline_attachment (skylines, + y + conf.dir_ * staff_space * .5)); + + conf.delta_y_ += line_dy; + conf.attachment_x_.widen (-gap); + if (!on_line + && Staff_symbol_referencer::staff_radius (ties[0]) * staff_space > y) + conf.center_tie_vertically (details); + + tie_configs[i] = conf; + } - Direction d = LEFT; - do + /* + Try to shift small ties into available spaces. + */ + if (!manual_override) + { + set<int> positions_taken; + for (int i = 0; i < tie_configs.size (); i++) + positions_taken.insert (int (rint (tie_configs[i].position_))); + + for (int i = 0; i < tie_configs.size (); i++) + { + Tie_configuration * conf = &tie_configs.elem_ref (i); + if (Staff_symbol_referencer::on_staffline (ties[0], int (rint (conf->position_))) + && conf->height (details) < 0.4 * staff_space + && (positions_taken.find (int (rint (conf->position_ + conf->dir_))) + == positions_taken.end ())) { - conf.attachment_x_[d] = d * 1e6; // infty - for (int j = i - 1; j < i + 2; j++) - { - if (j >= 0 && j < ties.size()) - { - Spanner *t = dynamic_cast<Spanner*> (ties[j]); - Interval ext - = robust_relative_extent (t->get_bound (d), - common[X_AXIS], X_AXIS); - conf.attachment_x_[d] - = d * min (d * conf.attachment_x_[d], d * ext[-d]); - } - } + positions_taken.insert (int (rint (conf->position_ + conf->dir_))); + conf->delta_y_ += 0.2 * staff_space * conf->dir_; } - while (flip (&d) != LEFT); - tie_configs[i] = conf; } - else - tie_configs[i] = conf; - - add_configuration (&allowed, me, conf); } - + for (int i = 0; i < ties.size(); i++) { - Tie::set_control_points (ties[i], common, tie_configs[i]); + Tie::set_control_points (ties[i], common, tie_configs[i], + details + ); set_grob_direction (ties[i], tie_configs[i].dir_); } } +ADD_INTERFACE (Tie_column, "tie-column-interface", + "Object that sets directions of multiple ties in a tied chord", + "positioning-done " + "tie-configuration " + ); Index: lilypond/lily/tie.cc diff -u lilypond/lily/tie.cc:1.150 lilypond/lily/tie.cc:1.151 --- lilypond/lily/tie.cc:1.150 Mon Aug 22 00:58:01 2005 +++ lilypond/lily/tie.cc Mon Aug 22 14:03:11 2005 @@ -65,11 +65,11 @@ return Paper_column::get_rank (col); } -Real +int Tie::get_position (Grob *me) { Direction d = head (me, LEFT) ? LEFT : RIGHT; - return Staff_symbol_referencer::get_position (head (me, d)); + return (int) Staff_symbol_referencer::get_position (head (me, d)); } /* @@ -114,10 +114,87 @@ } } +Interval +get_default_attachments (Spanner *me, Grob *common, Real gap, + int *staff_position, + bool *in_between + ) +{ + Real staff_space = Staff_symbol_referencer::staff_space (me); + Direction dir = get_grob_direction (me); + Interval attachments; + Direction d = LEFT; + do + { + attachments[d] + = robust_relative_extent (me->get_bound (d), + common, + X_AXIS)[-d] + - gap * d; + } + while (flip (&d) != LEFT); + + if (attachments.length () < 0.6 * staff_space) + { + /* + Let short ties start over note heads, instead of between. + */ + Drul_array<bool> allow (true, true); + + Direction d = LEFT; + do { + if (Note_head::has_interface (me->get_bound (d))) + { + Grob *stem = unsmob_grob (me->get_bound (d)->get_object ("stem")); + if (get_grob_direction (stem) == dir + && -d == dir) + allow[d] = false; + } + } while (flip (&d) != LEFT); + + if (allow[LEFT] && allow[RIGHT]) + { + *staff_position += dir; + do + { + if (Note_head::has_interface (me->get_bound (d))) + { + Interval extent + = robust_relative_extent (me->get_bound (d), + common, X_AXIS); + + attachments[d] = extent.linear_combination (- 0.5 * d); + *in_between = false; + } + } + while (flip (&d) != LEFT); + } + } + return attachments; +} + +Interval +get_skyline_attachment (Drul_array< Array < Skyline_entry > > const &skylines, + Real y) +{ + Interval attachments; + Direction d = LEFT; + do + { + attachments[d] = skyline_height (skylines[d], y, -d); + } + while (flip (&d) != LEFT); + + return attachments; +} + void -Tie::get_configuration (Grob *me_grob, Grob **common, - Tie_configuration *conf) +Tie::get_configuration (Grob *me_grob, Grob *common, + Tie_configuration *conf, + Drul_array< Array < Skyline_entry > > const *skylines, + Tie_details const &details + ) { Spanner *me = dynamic_cast<Spanner*> (me_grob); if (!head (me, LEFT) && !head (me, RIGHT)) @@ -130,7 +207,7 @@ Direction dir = CENTER; int tie_position = (int) Tie::get_position (me); - int staff_position = conf->position_; + int staff_position = (int) conf->position_; if (conf->dir_) { @@ -143,72 +220,28 @@ dir = get_default_dir (me); } - Real staff_space = Staff_symbol_referencer::staff_space (me); + Real staff_space = details.staff_space_; bool in_between = true; Interval attachments = conf->attachment_x_; + Real gap = robust_scm2double (me->get_property ("x-gap"), 0.2); if (attachments.is_empty()) { - Direction d = LEFT; - Real gap = robust_scm2double (me->get_property ("x-gap"), 0.2); - do + if (!skylines) + attachments = get_default_attachments (me, common, gap, + &staff_position, + &in_between); + else { - attachments[d] - = robust_relative_extent (me->get_bound (d), - common[X_AXIS], - X_AXIS)[-d] - - gap * d; - } - while (flip (&d) != LEFT); - - if (attachments.length () < 0.6 * staff_space) - { - /* - Let short ties start over note heads, instead of between. - */ - Drul_array<bool> allow (true, true); - - Direction d = LEFT; - do { - if (Note_head::has_interface (me->get_bound (d))) - { - Grob *stem = unsmob_grob (me->get_bound (d)->get_object ("stem")); - if (get_grob_direction (stem) == dir - && -d == dir) - allow[d] = false; - } - } while (flip (&d) != LEFT); - - if (allow[LEFT] && allow[RIGHT]) - { - staff_position += dir; - do - { - if (Note_head::has_interface (me->get_bound (d))) - { - Interval extent - = robust_relative_extent (me->get_bound (d), - common[X_AXIS], X_AXIS); - - attachments[d] = extent.linear_combination (- 0.5 * d); - in_between = false; - } - } - while (flip (&d) != LEFT); - } + Real y = staff_space * 0.5 * staff_position; + attachments = get_skyline_attachment (*skylines, y); + attachments.widen (-gap); } } - SCM details = me->get_property ("details"); - - SCM limit - = scm_assq (ly_symbol2scm ("height-limit"), details); - - Real h_inf = robust_scm2double (scm_cdr (limit), 0.75) * staff_space; - Real r_0 = robust_scm2double (scm_cdr (scm_assq (ly_symbol2scm ("ratio"), details)), - .333); Bezier b = slur_shape (attachments.length(), - h_inf, r_0); + details.height_limit_, + details.ratio_); b.scale (1, dir); Offset middle = b.curve_point (0.5); @@ -282,17 +315,13 @@ if (in_space) { - if (fabs (dy) < 0.4 * staff_space) + if (fabs (dy) < 0.45 * staff_space) { /* vertically center in space. */ - Offset middle = b.curve_point (0.5); - Offset edge = b.curve_point (0.0); - - Real center = (edge[Y_AXIS] + middle[Y_AXIS])/2.0; - - conf->delta_y_ = - center; + conf->attachment_x_ = attachments; + conf->center_tie_vertically(details); } else { @@ -314,6 +343,13 @@ conf->dir_ = dir; conf->position_ = staff_position; + + if (skylines) + { + Real y = staff_space * 0.5 * staff_position; + attachments = get_skyline_attachment (*skylines, y); + attachments.widen (-gap); + } conf->attachment_x_ = attachments; } @@ -322,15 +358,9 @@ Tie::set_default_control_points (Grob *me_grob) { Spanner *me = dynamic_cast<Spanner*> (me_grob); - Grob *common[NO_AXES] = { - 0, 0 - }; - for (int a = X_AXIS; a < NO_AXES; a++) - { - Axis ax ((Axis) a); - common[ax] = me->get_bound (LEFT)->common_refpoint (me, ax); - common[ax] = me->get_bound (RIGHT)->common_refpoint (common[a], ax); - } + Grob *common = me; + common = me->get_bound (LEFT)->common_refpoint (common, X_AXIS); + common = me->get_bound (RIGHT)->common_refpoint (common, X_AXIS); Tie_configuration conf; if (!get_grob_direction (me)) @@ -338,33 +368,25 @@ int tie_position = (int) Tie::get_position (me); conf.position_ = tie_position; - - get_configuration (me, common, &conf); - set_control_points (me, common, conf); + Tie_details details; + details.init (me); + get_configuration (me, common, &conf, 0, details); + set_control_points (me, common, conf, details); } void Tie::set_control_points (Grob *me, - Grob **common, - Tie_configuration const &conf) + Grob *common, + Tie_configuration const &conf, + Tie_details const &details + ) { - SCM details = me->get_property ("details"); - SCM limit - = scm_assq (ly_symbol2scm ("height-limit"), details); - - Real staff_space = Staff_symbol_referencer::staff_space (me); - Real h_inf = robust_scm2double (scm_cdr (limit), 0.75) * staff_space; - Real r_0 = robust_scm2double (scm_cdr (scm_assq (ly_symbol2scm ("ratio"), - details)), - .333); - - Bezier b = slur_shape (conf.attachment_x_.length(), - h_inf, r_0); + Bezier b = conf.get_bezier (details); b.scale (1, conf.dir_); b.translate (Offset (conf.attachment_x_[LEFT] - - me->relative_coordinate (common[X_AXIS], X_AXIS), - 0.5 * conf.position_ * staff_space + - me->relative_coordinate (common, X_AXIS), + 0.5 * conf.position_ * details.staff_space_ + conf.delta_y_ )); @@ -437,20 +459,3 @@ "direction " "thickness " "x-gap "); - -int -Tie_configuration::compare (Tie_configuration const &a, - Tie_configuration const &b) -{ - if (a.position_ - b.position_) - return sign (a.position_ - b.position_); - return sign (a.dir_ - b.dir_); -} - - -Tie_configuration::Tie_configuration () -{ - dir_ = CENTER; - position_ = 0; - delta_y_ = 0.0; -} Index: lilypond/python/convertrules.py diff -u lilypond/python/convertrules.py:1.12 lilypond/python/convertrules.py:1.13 --- lilypond/python/convertrules.py:1.12 Mon Aug 22 12:12:37 2005 +++ lilypond/python/convertrules.py Mon Aug 22 14:03:11 2005 @@ -2543,13 +2543,6 @@ def conv (str): str = re.sub('Performer_group_performer', 'Performer_group', str) str = re.sub('Engraver_group_engraver', 'Engraver_group', str) - return str - -conversions.append (((2, 7, 6), conv, - '''Performer_group_performer -> Performer_group, Engraver_group_engraver -> Engraver_group''')) - - -def conv (str): str = re.sub (r"#'inside-slur\s*=\s*##t *", r"#'avoid-slur = #'inside ", str) str = re.sub (r"#'inside-slur\s*=\s*##f *", @@ -2558,6 +2551,7 @@ r"#'avoid-slur", str) return str -conversions.append (((2, 7, 7), conv, - """inside-slur -> avoid-slur""")) +conversions.append (((2, 7, 6), conv, + '''Performer_group_performer -> Performer_group, Engraver_group_engraver -> Engraver_group +inside-slur -> avoid-slur''')) Index: lilypond/scm/define-grob-properties.scm diff -u lilypond/scm/define-grob-properties.scm:1.117 lilypond/scm/define-grob-properties.scm:1.118 --- lilypond/scm/define-grob-properties.scm:1.117 Mon Aug 22 00:58:02 2005 +++ lilypond/scm/define-grob-properties.scm Mon Aug 22 14:03:11 2005 @@ -469,6 +469,8 @@ (threshold ,number-pair? "(@var{min} . @var{max}), where @var{min} and @var{max} are dimensions in staff space.") + (tie-configuration ,list? "List of (@var{position} . @var{dir}) +pairs, indicating the desired tie configuration.") (transparent ,boolean? "This is almost the same as setting @code{print-function} to @code{#f}, but this retains the dimensions of this grob, which means that grobs can be erased individually.") _______________________________________________ Lilypond-cvs mailing list Lilypond-cvs@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-cvs