From ab5003677ff5107eaaa6ab82b5463171bfe0f806 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Mon, 26 Jun 2000 16:21:27 +0200 Subject: [PATCH] patch::: 1.3.64.jcn1 1.3.63.jcn1 ============ * Started grand redo of slur endings, interstaff slurs are broken for now. * Fixed download url. * Moved direction.cc to flower. --- CHANGES | 9 + VERSION | 2 +- flower/direction.cc | 25 ++ lily/direction.cc | 25 -- lily/include/slur-bezier-bow.hh | 25 ++ lily/include/slur.hh | 7 +- lily/slur-bezier-bow.cc | 180 +++++++++++++ lily/slur.cc | 440 +++++++------------------------- ly/declarations.ly | 3 + scm/slur.scm | 62 +++++ 10 files changed, 405 insertions(+), 373 deletions(-) create mode 100644 flower/direction.cc create mode 100644 lily/include/slur-bezier-bow.hh create mode 100644 lily/slur-bezier-bow.cc create mode 100644 scm/slur.scm diff --git a/CHANGES b/CHANGES index da042c27fc..0d289e95fa 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +1.3.63.jcn1 +============ + +* Started grand redo of slur endings, interstaff slurs are broken for now. + +* Fixed download url. + +* Moved direction.cc to flower. + 1.3.63.uu1 ========== diff --git a/VERSION b/VERSION index 98dbd94bff..914fac1745 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=64 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=jcn1 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/flower/direction.cc b/flower/direction.cc new file mode 100644 index 0000000000..aeddc311a2 --- /dev/null +++ b/flower/direction.cc @@ -0,0 +1,25 @@ +/* + direction.cc -- implement Direction + + source file of the GNU LilyPond music typesetter + + (c) 1998--2000 Han-Wen Nienhuys + + */ + +#include "direction.hh" + +String +direction_str (Direction d, Axis a) +{ + String s("center"); + if (a == Y_AXIS) + { + s =( d == UP ? "up" : "down"); + } + else if (a == X_AXIS) + { + s = (d == LEFT ? "left" : "right" ); + } + return s; +} diff --git a/lily/direction.cc b/lily/direction.cc index aeddc311a2..e69de29bb2 100644 --- a/lily/direction.cc +++ b/lily/direction.cc @@ -1,25 +0,0 @@ -/* - direction.cc -- implement Direction - - source file of the GNU LilyPond music typesetter - - (c) 1998--2000 Han-Wen Nienhuys - - */ - -#include "direction.hh" - -String -direction_str (Direction d, Axis a) -{ - String s("center"); - if (a == Y_AXIS) - { - s =( d == UP ? "up" : "down"); - } - else if (a == X_AXIS) - { - s = (d == LEFT ? "left" : "right" ); - } - return s; -} diff --git a/lily/include/slur-bezier-bow.hh b/lily/include/slur-bezier-bow.hh new file mode 100644 index 0000000000..7fbbffd762 --- /dev/null +++ b/lily/include/slur-bezier-bow.hh @@ -0,0 +1,25 @@ +/* + slur-bezier-bow.hh -- declare Slur_bezier_bow + + source file of the GNU LilyPond music typesetter + + (c) 2000 Jan Nieuwenhuizen +*/ + +#ifndef SLUR_BEZIER_BOW_HH +#define SLUR_BEZIER_BOW_HH + +#include "bezier-bow.hh" + +class Slur_bezier_bow : public Bezier_bow +{ +public: + Slur_bezier_bow (Array encompass, Direction dir); + Array area_x_gradients_array (Real area); + void blow_fit (); + Real enclosed_area_f () const; + Real fit_factor () const; + void minimise_enclosed_area (Paper_def* paper_l, Real default_height); +}; + +#endif /* SLUR_BEZIER_BOW_HH */ diff --git a/lily/include/slur.hh b/lily/include/slur.hh index 654bc45685..80b18fbfc7 100644 --- a/lily/include/slur.hh +++ b/lily/include/slur.hh @@ -26,17 +26,12 @@ public: virtual Array get_encompass_offset_arr () const; Bezier get_curve () const; - /* - JUNKME - */ - Drul_array dy_f_drul_; - Drul_array dx_f_drul_; - virtual Direction get_default_dir () const; SCM member_after_line_breaking (); static SCM after_line_breaking (SCM); virtual void do_add_processing (); Array get_rods () const; + Offset get_attachment (Direction dir) const; private: void de_uglyfy (Slur_bezier_bow* bb, Real default_height); diff --git a/lily/slur-bezier-bow.cc b/lily/slur-bezier-bow.cc new file mode 100644 index 0000000000..0dc7ba2418 --- /dev/null +++ b/lily/slur-bezier-bow.cc @@ -0,0 +1,180 @@ +/* + slur-bezier-bow.cc -- implement Slur_bezier_bow + + source file of the GNU LilyPond music typesetter + + (c) 2000 Jan Nieuwenhuizen +*/ + +#include "debug.hh" +#include "paper-def.hh" +#include "slur-bezier-bow.hh" +#include "main.hh" + +Slur_bezier_bow::Slur_bezier_bow (Array encompass, Direction dir) + : Bezier_bow (encompass, dir) +{ +} + +void +Slur_bezier_bow::blow_fit () +{ + Real len = curve_.control_[3][X_AXIS]; + Real h = curve_.control_[1][Y_AXIS] * fit_factor () / len; + curve_.control_[1][Y_AXIS] = h * len; + curve_.control_[2][Y_AXIS] = h * len; + curve_.assert_sanity (); +} + + +Real +Slur_bezier_bow::enclosed_area_f () const +{ + Real a = 0; + for (int i=0; i < encompass_.size (); i++) + { + Interval x; + Interval y; + if (i == 0) + { + x = Interval (0, encompass_[1][X_AXIS] / 2); + y = Interval (0, + curve_.get_other_coordinate (X_AXIS, + encompass_[1][X_AXIS] + / 2)); + } + else if (i == encompass_.size () - 1) + { + x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS])/2, + encompass_[i][X_AXIS]); + y = Interval (0, + (curve_.get_other_coordinate (X_AXIS, + (x[MIN] + x[MAX]) / 2))); + } + else + { + x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS]) / 2, + (encompass_[i][X_AXIS] + encompass_[i+1][X_AXIS]) / 2); + y = Interval (encompass_[i][Y_AXIS], + (curve_.get_other_coordinate (X_AXIS, x[MIN]) + + curve_.get_other_coordinate (X_AXIS, + (x[MIN] + x[MAX]) / 2) + + curve_.get_other_coordinate (X_AXIS, x[MAX])) / 3); + } + + Real da = x.length () * y.length (); + a += da; + } + return a; +} + +Array +Slur_bezier_bow::area_x_gradients_array (Real area) +{ + Real len = curve_.control_[3][X_AXIS]; + Real grow = len / 10.0; + Array da (2); + for (int i=0; i < 2; i++) + { + Real r = curve_.control_[i+1][X_AXIS]; + curve_.control_[i+1][X_AXIS] += grow; + da[i] = (enclosed_area_f () - area) / grow; + curve_.control_[i+1][X_AXIS] = r; + } + return da; +} + +void +Slur_bezier_bow::minimise_enclosed_area (Paper_def* paper_l, + Real default_height) +{ + Real length = curve_.control_[3][X_AXIS]; + Real sb = paper_l->get_var ("slur_beautiful"); + Real beautiful = length * default_height * sb; + + DEBUG_OUT << to_str ("Beautiful: %f\n", beautiful); + DEBUG_OUT << to_str ("Length: %f\n", length); + DEBUG_OUT << to_str ("D-height: %f\n", default_height); + DEBUG_OUT << to_str ("FitFac: %f\n", fit_factor ()); + + if (fit_factor () > 1.0) + blow_fit (); + + Real pct_c0 = paper_l->get_var ("bezier_pct_c0"); + Real pct_c3 = paper_l->get_var ("bezier_pct_c3"); + Real pct_in_max = paper_l->get_var ("bezier_pct_in_max"); + Real pct_out_max = paper_l->get_var ("bezier_pct_out_max"); + Real steps = paper_l->get_var ("bezier_area_steps"); + + for (int i=0; i < steps; i++) + { + Real area = enclosed_area_f (); + if (!i) + DEBUG_OUT << to_str ("Init area: %f\n", area); + + if (area <= beautiful) + break; + + Array da = area_x_gradients_array (area); + + // urg + Real pct = pct_c0 + pct_c3 * length * length * length; + pct *= (steps - i) / steps; + if (da[0] > 0 || da[1] < 0) + pct = pct x1 && encompass_[i][X_AXIS] < x2) + { + Real y = curve_.get_other_coordinate (X_AXIS, encompass_[i][X_AXIS]); + if (y>0) + { + Real f = encompass_[i][Y_AXIS] / y; + factor = factor >? f; + } + } + } + + + return factor; +} + + + + diff --git a/lily/slur.cc b/lily/slur.cc index fd59628e57..aaed8b51a1 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -23,203 +23,20 @@ #include "paper-column.hh" #include "molecule.hh" #include "debug.hh" -#include "box.hh" -#include "bezier-bow.hh" +#include "slur-bezier-bow.hh" #include "main.hh" #include "cross-staff.hh" #include "group-interface.hh" #include "staff-symbol-referencer.hh" -class Slur_bezier_bow : public Bezier_bow -{ -public: - Slur_bezier_bow (Array encompass, Direction dir); - Array area_x_gradients_array (Real area); - void blow_fit (); - Real enclosed_area_f () const; - Real fit_factor () const; - void minimise_enclosed_area (Paper_def* paper_l, Real default_height); -}; - -Slur_bezier_bow::Slur_bezier_bow (Array encompass, Direction dir) - : Bezier_bow (encompass, dir) -{ -} - -void -Slur_bezier_bow::blow_fit () -{ - Real len = curve_.control_[3][X_AXIS]; - Real h = curve_.control_[1][Y_AXIS] * fit_factor () / len; - curve_.control_[1][Y_AXIS] = h * len; - curve_.control_[2][Y_AXIS] = h * len; - curve_.assert_sanity (); -} - - -Real -Slur_bezier_bow::enclosed_area_f () const -{ - Real a = 0; - for (int i=0; i < encompass_.size (); i++) - { - Interval x; - Interval y; - if (i == 0) - { - x = Interval (0, encompass_[1][X_AXIS] / 2); - y = Interval (0, - curve_.get_other_coordinate (X_AXIS, - encompass_[1][X_AXIS] - / 2)); - } - else if (i == encompass_.size () - 1) - { - x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS])/2, - encompass_[i][X_AXIS]); - y = Interval (0, - (curve_.get_other_coordinate (X_AXIS, - (x[MIN] + x[MAX]) / 2))); - } - else - { - x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS]) / 2, - (encompass_[i][X_AXIS] + encompass_[i+1][X_AXIS]) / 2); - y = Interval (encompass_[i][Y_AXIS], - (curve_.get_other_coordinate (X_AXIS, x[MIN]) - + curve_.get_other_coordinate (X_AXIS, - (x[MIN] + x[MAX]) / 2) - + curve_.get_other_coordinate (X_AXIS, x[MAX])) / 3); - } - - Real da = x.length () * y.length (); - a += da; - } - return a; -} - -Array -Slur_bezier_bow::area_x_gradients_array (Real area) -{ - Real len = curve_.control_[3][X_AXIS]; - Real grow = len / 10.0; - Array da (2); - for (int i=0; i < 2; i++) - { - Real r = curve_.control_[i+1][X_AXIS]; - curve_.control_[i+1][X_AXIS] += grow; - da[i] = (enclosed_area_f () - area) / grow; - curve_.control_[i+1][X_AXIS] = r; - } - return da; -} - -void -Slur_bezier_bow::minimise_enclosed_area (Paper_def* paper_l, - Real default_height) -{ - Real length = curve_.control_[3][X_AXIS]; - Real sb = paper_l->get_var ("slur_beautiful"); - Real beautiful = length * default_height * sb; - - DEBUG_OUT << to_str ("Beautiful: %f\n", beautiful); - DEBUG_OUT << to_str ("Length: %f\n", length); - DEBUG_OUT << to_str ("D-height: %f\n", default_height); - DEBUG_OUT << to_str ("FitFac: %f\n", fit_factor ()); - - if (fit_factor () > 1.0) - blow_fit (); - - Real pct_c0 = paper_l->get_var ("bezier_pct_c0"); - Real pct_c3 = paper_l->get_var ("bezier_pct_c3"); - Real pct_in_max = paper_l->get_var ("bezier_pct_in_max"); - Real pct_out_max = paper_l->get_var ("bezier_pct_out_max"); - Real steps = paper_l->get_var ("bezier_area_steps"); - - for (int i=0; i < steps; i++) - { - Real area = enclosed_area_f (); - if (!i) - DEBUG_OUT << to_str ("Init area: %f\n", area); - - if (area <= beautiful) - break; - - Array da = area_x_gradients_array (area); - - // urg - Real pct = pct_c0 + pct_c3 * length * length * length; - pct *= (steps - i) / steps; - if (da[0] > 0 || da[1] < 0) - pct = pct x1 && encompass_[i][X_AXIS] < x2) - { - Real y = curve_.get_other_coordinate (X_AXIS, encompass_[i][X_AXIS]); - if (y>0) - { - Real f = encompass_[i][Y_AXIS] / y; - factor = factor >? f; - } - } - } - - - return factor; -} - - - - - -/* - Slur -*/ - Slur::Slur (SCM s) : Spanner (s) { - // URG - dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = 0.0; - dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0; - + /* + silly value for testing + */ + set_elt_property ("attachment", gh_cons (ly_symbol2scm ("alongside-stem"), + ly_symbol2scm ("alongside-stem"))); set_elt_pointer ("note-columns", SCM_EOL); set_elt_property ("control-points", SCM_EOL); } @@ -351,168 +168,121 @@ Slur::member_after_line_breaking () return SCM_UNDEFINED; } -/* - urg - FIXME - */ -void -Slur::set_extremities () +SCM +slur_get_bound (SCM slur, SCM dir) { - Link_array encompass_arr = - Pointer_group_interface__extract_elements (this, (Note_column*)0, "note-columns"); - - if (!encompass_arr.size ()) - { - suicide(); - return; - } - - if (!directional_element (this).get ()) - directional_element (this).set (get_default_dir ()); - - - /* - Slur and tie placement [OSU] - - Slurs: - * x = centre of head - d * x_gap_f + return ((Slur*)unsmob_element (slur))->get_bound (to_dir (dir))->self_scm_; +} - TODO: - * y = length < 5ss : horizontal tangent + d * 0.25 ss - y = length >= 5ss : y next interline - d * 0.25 ss - */ +SCM +score_element_get_pointer (SCM se, SCM name) +{ + SCM s = scm_assq (name, unsmob_element (se)->pointer_alist_); + return (s == SCM_BOOL_F) ? SCM_UNDEFINED : gh_cdr (s); +} - Real staff_space = paper_l ()->get_var ("interline"); - Real half_staff_space = staff_space / 2; +SCM +score_element_get_property (SCM se, SCM name) +{ + SCM s = scm_assq (name, unsmob_element (se)->property_alist_); + return (s == SCM_BOOL_F) ? SCM_UNDEFINED : gh_cdr (s); +} - Real x_gap_f = paper_l ()->get_var ("slur_x_gap"); - Real y_gap_f = paper_l ()->get_var ("slur_y_gap"); +void +init_score_elts () +{ + scm_make_gsubr ("get-pointer", 2 , 0, 0, + (SCM(*)(...)) score_element_get_pointer); + scm_make_gsubr ("get-property", 2 , 0, 0, + (SCM(*)(...)) score_element_get_property); + scm_make_gsubr ("get-bound", 2 , 0, 0, + (SCM(*)(...)) slur_get_bound); +} - Drul_array note_column_drul; - note_column_drul[LEFT] = encompass_arr[0]; - note_column_drul[RIGHT] = encompass_arr.top (); +ADD_SCM_INIT_FUNC (score_elt, init_score_elts); - bool fix_broken_b = false; +void +Slur::set_extremities () +{ + if (!directional_element (this).get ()) + directional_element (this).set (get_default_dir ()); - Direction my_dir = directional_element (this).get (); - - Direction d = LEFT; + Direction dir = LEFT; do { - dx_f_drul_[d] = 0; - dy_f_drul_[d] = 0; - - if ((note_column_drul[d] == get_bound (d)) - && note_column_drul[d]->first_head () - && (note_column_drul[d]->stem_l ())) + // for (SCM s = get_elt_property ("slur-extremity-rules"); s != SCM_EOL; s = gh_cdr (s)) + for (SCM s = scm_eval (ly_symbol2scm ("slur-extremity-rules")); + s != SCM_EOL; s = gh_cdr (s)) { - Stem* stem_l = note_column_drul[d]->stem_l (); - /* - side directly attached to note head; - no beam getting in the way - */ - if ((stem_l->extent (Y_AXIS).empty_b () - || !((stem_l->get_direction () == my_dir) && (my_dir != d))) - && !((my_dir == stem_l->get_direction ()) - && stem_l->beam_l () && (stem_l->beam_count (-d) >= 1))) + SCM r = scm_eval (scm_listify (gh_caar (s), + this->self_scm_, + gh_int2scm ((int)dir), + SCM_UNDEFINED)); + if (r != SCM_BOOL_F) { - dx_f_drul_[d] = get_bound (d)->extent (X_AXIS).length () / 2; - dx_f_drul_[d] -= d * x_gap_f; + index_set_cell (get_elt_property ("attachment"), dir, + gh_cdar (s)); + break; + } + } + } + while (flip (&dir) != LEFT); +} - if (stem_l->get_direction () != my_dir) - { - dy_f_drul_[d] = note_column_drul[d]->extent (Y_AXIS)[my_dir]; - } - else - { - dy_f_drul_[d] = stem_l->chord_start_f () - + my_dir * half_staff_space; - } - dy_f_drul_[d] += my_dir * y_gap_f; +Offset +Slur::get_attachment (Direction dir) const +{ + SCM s = get_elt_property ("attachment"); + SCM a = dir == LEFT ? gh_car (s) : gh_cdr (s); + Real ss = Staff_symbol_referencer_interface (this).staff_space (); + Real hs = ss / 2.0; + Offset o; + if (Note_column* n = dynamic_cast (get_bound (dir))) + { + if (Stem* st = dynamic_cast (n->stem_l ())) + { + String str = ly_symbol2string (a); + if (str == "head") + { + o = Offset (0, st->chord_start_f ()); } - /* - side attached to (visible) stem - */ - else + else if (str == "alongside-stem") { - dx_f_drul_[d] = stem_l->relative_coordinate (0, X_AXIS) - - get_bound (d)->relative_coordinate (0, X_AXIS); - /* - side attached to beamed stem - */ - if (stem_l->beam_l () && (stem_l->beam_count (-d) >= 1)) - { - dy_f_drul_[d] = stem_l->extent (Y_AXIS)[my_dir]; - dy_f_drul_[d] += my_dir * 2 * y_gap_f; - } - /* - side attached to notehead, with stem getting in the way - */ - else + o = Offset (0, st->chord_start_f ()); + } + else if (str == "stem") + { + o = Offset (0, st->stem_end_position () * hs); + } + else if (str == "loose-end") + { + SCM other_a = dir == LEFT ? gh_cdr (s) : gh_car (s); + if (ly_symbol2string (other_a) != "loose-end") { - dx_f_drul_[d] -= d * x_gap_f; - - dy_f_drul_[d] = stem_l->chord_start_f () - + my_dir * half_staff_space; - dy_f_drul_[d] += my_dir * y_gap_f; + o = Offset (0, get_attachment (-dir)[Y_AXIS]); } } - } - /* - loose end - */ - else - { - dx_f_drul_[d] = get_broken_left_end_align (); - - /* - broken: should get y from other piece, so that slur - continues up/down trend - - for now: be horizontal.. - */ - fix_broken_b = true; - } - } - while (flip (&d) != LEFT); - - int cross_count = cross_staff_count (); - bool interstaff_b = (0 < cross_count) && (cross_count < encompass_arr.size ()); - Drul_array info_drul; - Drul_array interstaff_interval; - - do - { - info_drul[d] = encompass_offset (encompass_arr.boundary (d, 0)); - interstaff_interval[d] = - calc_interstaff_dist (encompass_arr.boundary (d,0), - this); - } - while (flip (&d) != LEFT); - - Real interstaff_f = interstaff_interval[RIGHT] - interstaff_interval[LEFT]; - - if (fix_broken_b) - { - Direction d = (encompass_arr.top () != get_bound (RIGHT)) ? - RIGHT : LEFT; - dy_f_drul_[d] = info_drul[d][Y_AXIS]; - if (!interstaff_b) - { - dy_f_drul_[d] -= interstaff_interval[d]; - if (cross_count) // interstaff_i ? + o += Offset (0.5 * st->get_direction () + * n->extent (X_AXIS).length (), 0); + + SCM l = scm_assoc + (scm_listify (a, + gh_int2scm (st->get_direction () * dir), + gh_int2scm (directional_element (this).get () * dir), + SCM_UNDEFINED), + scm_eval (ly_symbol2scm ("slur-extremity-offset-alist"))); + + if (l != SCM_BOOL_F) { - dy_f_drul_[LEFT] += interstaff_interval[d]; - dy_f_drul_[RIGHT] += interstaff_interval[d]; + o += ly_scm2offset (gh_cdr (l)) * ss * dir; } } } - - if (!fix_broken_b) - dy_f_drul_[RIGHT] += interstaff_f; + + return o; } - int Slur::cross_staff_count ()const { @@ -538,27 +308,16 @@ Slur::get_encompass_offset_arr () const Array offset_arr; -#if 0 - /* - check non-disturbed slur - FIXME: x of ends off by a tiny bit!! - */ - offset_arr.push (Offset (0, dy_f_drul_[LEFT])); - offset_arr.push (Offset (0, dy_f_drul_[RIGHT])); - return offset_arr; -#endif - Offset origin (relative_coordinate (0, X_AXIS), 0); int first = 1; int last = encompass_arr.size () - 2; - offset_arr.push (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT])); + offset_arr.push (get_attachment (LEFT)); /* left is broken edge */ - int cross_count = cross_staff_count (); bool cross_b = cross_count && cross_count < encompass_arr.size (); if (encompass_arr[0] != get_bound (LEFT)) @@ -583,8 +342,7 @@ Slur::get_encompass_offset_arr () const offset_arr.push (o - origin); } - offset_arr.push (Offset (spanner_length ()+ dx_f_drul_[RIGHT], - dy_f_drul_[RIGHT])); + offset_arr.push (Offset (spanner_length (), 0) + get_attachment (RIGHT)); return offset_arr; } diff --git a/ly/declarations.ly b/ly/declarations.ly index e6f16c1539..ec640fb578 100644 --- a/ly/declarations.ly +++ b/ly/declarations.ly @@ -6,6 +6,9 @@ maxima = \duration #'( -3 0 ) #(eval-string (ly-gulp-file "generic-property.scm")) +% urg, move to basic property? +#(eval-string (ly-gulp-file "slur.scm")) + \include "nederlands.ly" % dutch \include "chord-modifiers.ly" \include "script.ly" diff --git a/scm/slur.scm b/scm/slur.scm new file mode 100644 index 0000000000..ce6f4be123 --- /dev/null +++ b/scm/slur.scm @@ -0,0 +1,62 @@ + +;;; als aan echte stok +;;; if ((note_column_drul[d] == get_bound (d)) +;;; && note_column_drul[d]->first_head () +;;; && (note_column_drul[d]->stem_l ())) +;;; +;;; *Need: Score_elment::pointer_alist_ +;;; Score_elment::property_alist_ +;;; Spanner::Drul_array spanned_drul_; +;;; spanner:: (cons get_bound (LEFT) get_bound (RIGHT)) + +(define (attached-to-stem slur dir) + (let* ((note-columns (get-pointer slur 'note-columns)) + (col (if (= dir 1) (car note-columns) (car (reverse note-columns)))) + (stem (get-pointer col 'stem))) + (and + (eq? col (get-bound slur dir)) + stem + (get-pointer stem 'heads)))) + +(define slur-extremity-rules + '( + ;;if (stem_l->beam_l () && (stem_l->beam_count (-d) >= 1)) + ((lambda (slur dir) + ;; urg, code dup + ;; if attached-to-stem + (let* ((note-columns (get-pointer slur 'note-columns)) + (col (if (= dir 1) (car note-columns) (car (reverse note-columns)))) + (stem (get-pointer col 'stem))) + (and + (and + (eq? col (get-bound slur dir)) + stem + (get-pointer stem 'heads)) + ;; and got beam + (and (get-pointer stem 'beam) + ;; and beam on same side as slur + (let ((beaming (get-property stem 'beaming))) + (if (pair? beaming) + (>= 1 + (if (= dir -1) (car beaming) (cdr beaming))) + #f)))))) . stem) + ((lambda (slur dir) (not (attached-to-stem slur dir))) . loose-end) + ;; default case, attach to head + ((lambda (x y) #t) . head) + + ;; silly rule, just to check + ((lambda (slur dir) + (and (attached-to-stem slur dir) + (= (get-property slur 'direction) dir))) . stem) + )) + + +(define slur-extremity-offset-alist + '( + ((head 1 1) . (-0.25 . 0.2)) + ((head 1 -1) . (-0.25 . -0.75)) + ((head -1 1) . (-0.25 . 0.75)) + ((head -1 -1) . (-0.75 . 1.2)) + ((stem 1 1) . (0 . 0.2)) + ((stem -1 -1) . (0 . 0.2)) + )) -- 2.39.5