From 6e98fc2ce127495233a714cdcdf6553570633ba3 Mon Sep 17 00:00:00 2001 From: fred Date: Tue, 26 Mar 2002 23:23:54 +0000 Subject: [PATCH] lilypond-1.3.65 --- CHANGES | 33 +++- VERSION | 2 +- lily/slur.cc | 482 +++++++++++++++------------------------------------ scm/slur.scm | 55 ++++++ 4 files changed, 229 insertions(+), 343 deletions(-) create mode 100644 scm/slur.scm diff --git a/CHANGES b/CHANGES index da042c27fc..48da8c0b8d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,37 @@ -1.3.63.uu1 +1.3.64.uu1 ========== +* Bugfix: translate volta spanner at start of line. + +* Changed directional_element() calls to instantiations +of Directional_element_interface. + +* Removed Dynamic_line_spanner, and cleaned up Dynamic_engraver. + +* Removed Staff_info type. Information about columns is now transferred +via currentMusicalColumn and currentCommandColumn. + + +1.3.64.jcn2 +============ + +* Made slur attachment position user settable; properties: +slurBeginAttachment slurEndAttachment, values: 'head 'stem +'along-side-stem. See input/test/slur-attachment.ly and ophee-slurs.ly. + +* Fixed slur attachment positions, added missing rule and use simple +default starting positions for attachments. + +* Started rewrite of slur ending code, interstaff slurs are broken for +now. + +* Fixed download URL of the webpage. + +* Moved direction.cc to flower/. + +1.3.64 +====== + * Lyrics centered on notehead. * Various bugfixes hyphen-spanner. diff --git a/VERSION b/VERSION index 98dbd94bff..3f4a9599f7 100644 --- a/VERSION +++ b/VERSION @@ -1,7 +1,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 -PATCH_LEVEL=64 +PATCH_LEVEL=65 MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a diff --git a/lily/slur.cc b/lily/slur.cc index fd59628e57..05ff6477ea 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -11,6 +11,9 @@ [TODO] * begin and end should be treated as a/acknowledge Scripts. * broken slur should have uniform trend + * smart changing of endings + * smart changing of (Y-?)offsets to avoid ugly beziers + (along-side-stem) */ #include "directional-element-interface.hh" @@ -23,203 +26,16 @@ #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; - + set_elt_property ("attachment", gh_cons (SCM_BOOL_F, SCM_BOOL_F)); set_elt_pointer ("note-columns", SCM_EOL); set_elt_property ("control-points", SCM_EOL); } @@ -234,6 +50,8 @@ Slur::add_column (Note_column*n) Pointer_group_interface (this, "note-columns").add_element (n); add_dependency (n); } + + add_bound_item (this, n); } void @@ -287,6 +105,7 @@ Slur::get_default_dir () const void Slur::do_add_processing () { +#if 0 Link_array encompass_arr = Pointer_group_interface__extract_elements (this, (Note_column*)0, "note-columns"); @@ -296,6 +115,7 @@ Slur::do_add_processing () if (encompass_arr.size () > 1) set_bound (RIGHT, encompass_arr.top ()); } +#endif } @@ -305,7 +125,7 @@ Slur::encompass_offset (Note_column const* col) const { Offset o; Stem* stem_l = col->stem_l (); - Direction dir = directional_element (this).get (); + Direction dir = Directional_element_interface (this).get (); if (!stem_l) { @@ -314,7 +134,7 @@ Slur::encompass_offset (Note_column const* col) const o[Y_AXIS] = col->extent (Y_AXIS)[dir]; return o; } - Direction stem_dir = directional_element (stem_l).get (); + Direction stem_dir = Directional_element_interface (stem_l).get (); o[X_AXIS] = stem_l->relative_coordinate (0, X_AXIS); /* @@ -351,168 +171,155 @@ 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_interface (this).get ()) + Directional_element_interface (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 ())) + if (!gh_symbol_p (index_cell (get_elt_property ("attachment"), dir))) { - 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))) + + // 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)) { - dx_f_drul_[d] = get_bound (d)->extent (X_AXIS).length () / 2; - dx_f_drul_[d] -= d * x_gap_f; - - if (stem_l->get_direction () != my_dir) + SCM r = scm_eval (scm_listify (gh_caar (s), + this->self_scm_, + gh_int2scm ((int)dir), + SCM_UNDEFINED)); + if (r != SCM_BOOL_F) { - dy_f_drul_[d] = note_column_drul[d]->extent (Y_AXIS)[my_dir]; + index_set_cell (get_elt_property ("attachment"), dir, + gh_cdar (s)); + break; } - else - { - dy_f_drul_[d] = stem_l->chord_start_f () - + my_dir * half_staff_space; - } - dy_f_drul_[d] += my_dir * y_gap_f; } - /* - side attached to (visible) stem - */ - else + } + } + while (flip (&dir) != LEFT); +} + +Offset +Slur::get_attachment (Direction dir) const +{ + SCM s = get_elt_property ("attachment"); + SCM a = dir == LEFT ? gh_car (s) : gh_cdr (s); + String str = ly_symbol2string (a); + 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 ())) + { + if (str == "head") { - dx_f_drul_[d] = stem_l->relative_coordinate (0, X_AXIS) - - get_bound (d)->relative_coordinate (0, X_AXIS); + o = Offset (0, st->chord_start_f ()); /* - side attached to beamed stem + Default position is centered in X, on outer side of head Y */ - 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; - } + o += Offset (0.5 * n->extent (X_AXIS).length (), + 0.5 * ss * Directional_element_interface (this).get ()); + } + else if (str == "alongside-stem") + { + o = Offset (0, st->chord_start_f ()); + /* + Default position is on stem X, on outer side of head Y + */ + o += Offset (n->extent (X_AXIS).length () + * (1 + st->get_direction ()), + 0.5 * ss * Directional_element_interface (this).get ()); + } + else if (str == "stem") + { + o = Offset (0, st->stem_end_position () * hs); /* - side attached to notehead, with stem getting in the way + Default position is on stem X, at stem end Y */ - else + o += Offset (0.5 * + (n->extent (X_AXIS).length () + - st->extent (X_AXIS).length ()) + * (1 + st->get_direction ()), + 0); + } + 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; + + + SCM l = scm_assoc + (scm_listify (a, + gh_int2scm (st->get_direction () * dir), + gh_int2scm (Directional_element_interface (this).get () * dir), + SCM_UNDEFINED), + scm_eval (ly_symbol2scm ("slur-extremity-offset-alist"))); + + if (l != SCM_BOOL_F) + { + o += ly_scm2offset (gh_cdr (l)) * ss * dir; + } } } - 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]; + /* + URG + */ - if (fix_broken_b) + if (str != "loose-end") { - 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 ? - { - dy_f_drul_[LEFT] += interstaff_interval[d]; - dy_f_drul_[RIGHT] += interstaff_interval[d]; - } - } + Link_array encompass_arr = + Pointer_group_interface__extract_elements (this, (Note_column*)0, + "note-columns"); + o -= Offset (0, calc_interstaff_dist (dir == LEFT ? encompass_arr[0] + : encompass_arr.top (), this)); } - - if (!fix_broken_b) - dy_f_drul_[RIGHT] += interstaff_f; + return o; } - int Slur::cross_staff_count ()const { @@ -538,33 +345,26 @@ 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 (); + + /* + URG + */ bool cross_b = cross_count && cross_count < encompass_arr.size (); if (encompass_arr[0] != get_bound (LEFT)) { first--; - Real is = calc_interstaff_dist (encompass_arr[0], this); + Real is = calc_interstaff_dist (encompass_arr[0], this); if (cross_b) offset_arr[0][Y_AXIS] += is; } @@ -583,8 +383,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; } @@ -620,7 +419,7 @@ Slur::member_brew_molecule () const if (gh_number_p (d)) a = lookup_l ()->dashed_slur (one, thick, thick * gh_scm2double (d)); else - a = lookup_l ()->slur (one, directional_element (this).get () * thick, thick); + a = lookup_l ()->slur (one, Directional_element_interface (this).get () * thick, thick); return a.create_scheme(); } @@ -629,7 +428,7 @@ void Slur::set_control_points () { Slur_bezier_bow bb (get_encompass_offset_arr (), - directional_element (this).get ()); + Directional_element_interface (this).get ()); Real staff_space = Staff_symbol_referencer_interface (this).staff_space (); Real h_inf = paper_l ()->get_var ("slur_height_limit_factor") * staff_space; @@ -676,7 +475,8 @@ Slur::get_curve () const Bezier b; int i = 0; - if (!directional_element (this).get ()) + if (!Directional_element_interface (this).get () + || ! gh_symbol_p (index_cell (get_elt_property ("attachment"), LEFT))) ((Slur*)this)->set_extremities (); if (!gh_pair_p (get_elt_property ("control-points"))) @@ -690,7 +490,7 @@ Slur::get_curve () const } Array enc (get_encompass_offset_arr ()); - Direction dir = directional_element (this).get (); + Direction dir = Directional_element_interface (this).get (); Real x1 = enc[0][X_AXIS]; Real x2 = enc.top ()[X_AXIS]; diff --git a/scm/slur.scm b/scm/slur.scm new file mode 100644 index 0000000000..c21ae76db4 --- /dev/null +++ b/scm/slur.scm @@ -0,0 +1,55 @@ + +(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 + '( + ((lambda (slur dir) + ;; urg, code dup + (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 stem + (not (= (get-property slur 'direction) + (get-property stem 'direction)))))) . head) + + ((lambda (slur dir) + ;; if attached-to-stem + (and (attached-to-stem slur dir) + ;; and got beam + ;; urg, code dup + (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 stem + (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) + )) + + +(define slur-extremity-offset-alist + '( + ((head 1 1) . (-0.25 . 0.2)) + ((head 1 -1) . (-0.25 . -0.25)) + ((head -1 1) . (-0.25 . 0.25)) + ((head -1 -1) . (-0.85 . -0.2)) + + ((stem 1 1) . (0 . 0.5)) + ((stem -1 -1) . (0 . -0.5)) + )) -- 2.39.5