X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fslur.cc;h=05ff6477eafef83fbbf80becce13cd5acf83393e;hb=b638d530ac5a32a832646cdd2b680ce52d0764f0;hp=9cd4ab1d2de4ae343d8d2adda850692be87e5248;hpb=1ac137fdab1f1be8a5621599664008107b5a9a6a;p=lilypond.git diff --git a/lily/slur.cc b/lily/slur.cc index 9cd4ab1d2d..05ff6477ea 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1996, 1997--2000 Han-Wen Nienhuys + (c) 1996--2000 Han-Wen Nienhuys Jan Nieuwenhuizen */ @@ -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,38 +26,69 @@ #include "paper-column.hh" #include "molecule.hh" #include "debug.hh" -#include "box.hh" -#include "bezier.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" -Slur::Slur () +Slur::Slur (SCM s) + : Spanner (s) { - dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = 0.0; - dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0; - set_elt_property ("note-columns", SCM_EOL); + 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); } void Slur::add_column (Note_column*n) { - if (!gh_pair_p (n->get_elt_property ("note-heads"))) + if (!gh_pair_p (n->get_elt_pointer ("note-heads"))) warning (_ ("Putting slur over rest. Ignoring.")); else { - Group_interface gi (this, "note-columns"); - gi.add_element (n); + Pointer_group_interface (this, "note-columns").add_element (n); add_dependency (n); } + + add_bound_item (this, n); +} + +void +Slur::de_uglyfy (Slur_bezier_bow* bb, Real default_height) +{ + Real length = bb->curve_.control_[3][X_AXIS] ; + Real ff = bb->fit_factor (); + for (int i = 1; i < 3; i++) + { + Real ind = abs (bb->curve_.control_[(i-1)*3][X_AXIS] + - bb->curve_.control_[i][X_AXIS]) / length; + Real h = bb->curve_.control_[i][Y_AXIS] * ff / length; + + Real f = default_height / length; + Real c1 = paper_l ()->get_var ("bezier_control1"); + Real c2 = paper_l ()->get_var ("bezier_control2"); + Real c3 = paper_l ()->get_var ("bezier_control3"); + if (h > c1 * f) + { + h = c1 * f; + } + else if (h > c2 + c3 * ind) + { + h = c2 + c3 * ind; + } + + bb->curve_.control_[i][Y_AXIS] = h * length; + } + + bb->curve_.assert_sanity (); } Direction Slur::get_default_dir () const { Link_array encompass_arr = - Group_interface__extract_elements (this, (Note_column*)0, "note-columns"); + Pointer_group_interface__extract_elements (this, (Note_column*)0, "note-columns"); Direction d = DOWN; for (int i=0; i < encompass_arr.size (); i ++) @@ -71,11 +105,17 @@ Slur::get_default_dir () const void Slur::do_add_processing () { +#if 0 Link_array encompass_arr = - Group_interface__extract_elements (this, (Note_column*)0, "note-columns"); - set_bounds (LEFT, encompass_arr[0]); - if (encompass_arr.size () > 1) - set_bounds (RIGHT, encompass_arr.top ()); + Pointer_group_interface__extract_elements (this, (Note_column*)0, "note-columns"); + + if (encompass_arr.size ()) + { + set_bound (LEFT, encompass_arr[0]); + if (encompass_arr.size () > 1) + set_bound (RIGHT, encompass_arr.top ()); + } +#endif } @@ -85,17 +125,17 @@ 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) { warning (_ ("Slur over rest?")); - o[X_AXIS] = col->hpos_f (); + o[X_AXIS] = col->relative_coordinate (0, X_AXIS); o[Y_AXIS] = col->extent (Y_AXIS)[dir]; return o; } - Direction stem_dir = directional_element (stem_l).get (); - o[X_AXIS] = stem_l->hpos_f (); + Direction stem_dir = Directional_element_interface (stem_l).get (); + o[X_AXIS] = stem_l->relative_coordinate (0, X_AXIS); /* Simply set x to middle of notehead @@ -121,328 +161,170 @@ Slur::encompass_offset (Note_column const* col) const return o; } -/* - ARGRARGRARGRARGAR! +GLUE_SCORE_ELEMENT(Slur,after_line_breaking); - Fixme - */ -void -Slur::do_post_processing () +SCM +Slur::member_after_line_breaking () { - Link_array encompass_arr = - Group_interface__extract_elements (this, (Note_column*)0, "note-columns"); + set_extremities (); + set_control_points (); + return SCM_UNDEFINED; +} - if (!encompass_arr.size ()) - { - set_elt_property ("transparent", SCM_BOOL_T); - set_empty (X_AXIS); - set_empty (Y_AXIS); - 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 +SCM +slur_get_bound (SCM slur, SCM dir) +{ + 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] == spanned_drul_[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] = spanned_drul_[d]->extent (X_AXIS).length () / 2; - dx_f_drul_[d] -= d * x_gap_f; - - if (stem_l->get_direction () != my_dir) - { - dy_f_drul_[d] = note_column_drul[d]->extent (Y_AXIS)[my_dir]; - } - else + 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] = stem_l->chord_start_f () - + my_dir * half_staff_space; + index_set_cell (get_elt_property ("attachment"), dir, + gh_cdar (s)); + break; } - dy_f_drul_[d] += my_dir * y_gap_f; } - /* - side attached to (visible) stem - */ - else - { - dx_f_drul_[d] = stem_l->hpos_f () - - spanned_drul_[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 - { - 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; - } - } - } - /* - 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]; + while (flip (&dir) != LEFT); +} - if (fix_broken_b) +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))) { - Direction d = (encompass_arr.top () != spanned_drul_[RIGHT]) ? - RIGHT : LEFT; - dy_f_drul_[d] = info_drul[d][Y_AXIS]; - if (!interstaff_b) + if (Stem* st = dynamic_cast (n->stem_l ())) { - dy_f_drul_[d] -= interstaff_interval[d]; - if (cross_count) // interstaff_i ? + if (str == "head") { - dy_f_drul_[LEFT] += interstaff_interval[d]; - dy_f_drul_[RIGHT] += interstaff_interval[d]; + o = Offset (0, st->chord_start_f ()); + /* + Default position is centered in X, on outer side of head Y + */ + o += Offset (0.5 * n->extent (X_AXIS).length (), + 0.5 * ss * Directional_element_interface (this).get ()); } - } - } - - if (!fix_broken_b) - dy_f_drul_[RIGHT] += interstaff_f; - - - - return; - - /* - Now we've got a fine slur - Catch and correct some ugly cases - */ - String infix = interstaff_b ? "interstaff_" : ""; - Real height_damp_f = paper_l ()->get_var ("slur_"+infix +"height_damping"); - Real slope_damp_f = paper_l ()->get_var ("slur_"+infix +"slope_damping"); - Real snap_f = paper_l ()->get_var ("slur_"+infix +"snap_to_stem"); - Real snap_max_dy_f = paper_l ()->get_var ("slur_"+infix +"snap_max_slope_change"); - - Real dx_f = spanner_length ()+ dx_f_drul_[RIGHT] - dx_f_drul_[LEFT]; - Real dy_f = dy_f_drul_[RIGHT] - dy_f_drul_[LEFT]; - if (!fix_broken_b) - dy_f -= interstaff_f; - - /* - Avoid too steep slurs. - */ - Real slope_ratio_f = abs (dy_f / dx_f); - if (slope_ratio_f > slope_damp_f) - { - Direction d = (Direction)(- my_dir * (sign (dy_f))); - if (!d) - d = LEFT; - Real damp_f = (slope_ratio_f - slope_damp_f) * dx_f; - /* - must never change sign of dy - */ - damp_f = damp_f height_damp_f) - { - Direction d = (Direction)(- my_dir * (sign (dy_f))); - if (!d) - d = LEFT; - /* take third step */ - Real damp_f = (height_ratio_f - height_damp_f) * size[X_AXIS] / 3; - /* - if y positions at about the same height, correct both ends - */ - if (abs (dy_f / dx_f ) < slope_damp_f) + else if (str == "alongside-stem") { - dy_f_drul_[-d] += my_dir * damp_f; - dy_f_drul_[d] += my_dir * damp_f; + 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 ()); } - /* - don't change slope too much, would have been catched by slope damping - */ - else + else if (str == "stem") { - damp_f = damp_f stem_end_position () * hs); + /* + Default position is on stem X, at stem end Y + */ + 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") + { + o = Offset (0, get_attachment (-dir)[Y_AXIS]); + } } - } - } - /* - If, after correcting, we're close to stem-end... - */ - Drul_array snapy_f_drul; - snapy_f_drul[LEFT] = snapy_f_drul[RIGHT] = 0; - Drul_array snapx_f_drul; - snapx_f_drul[LEFT] = snapx_f_drul[RIGHT] = 0; - Drul_array snapped_b_drul; - snapped_b_drul[LEFT] = snapped_b_drul[RIGHT] = false; - do - { - Note_column * nc = note_column_drul[d]; - if (nc == spanned_drul_[d] - && nc->stem_l () - && nc->stem_l ()->get_direction () == my_dir - && abs (nc->stem_l ()->extent (Y_AXIS)[my_dir] - - dy_f_drul_[d] + (d == LEFT ? 0 : interstaff_f)) - <= snap_f) - { - /* - prepare to attach to stem-end - */ - snapx_f_drul[d] = nc->stem_l ()->hpos_f () - - spanned_drul_[d]->relative_coordinate (0, X_AXIS); - - snapy_f_drul[d] = nc->stem_l ()->extent (Y_AXIS)[my_dir] - + interstaff_interval[d] - + my_dir * 2 * y_gap_f; - snapped_b_drul[d] = 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); - - /* - only use snapped positions if sign (dy) will not change - and dy doesn't change too much - */ - if (!fix_broken_b) - dy_f += interstaff_f; /* - (sigh) - - More refactoring could be done. + URG */ - Real maxsnap = abs (dy_f * snap_max_dy_f); - if (snapped_b_drul[LEFT] && snapped_b_drul[RIGHT] - && ((sign (snapy_f_drul[RIGHT] - snapy_f_drul[LEFT]) == sign (dy_f))) - && (!dy_f || (abs (snapy_f_drul[RIGHT] - snapy_f_drul[LEFT] - dy_f) - < maxsnap))) + + if (str != "loose-end") { - dy_f_drul_ = snapy_f_drul; - dx_f_drul_ = snapx_f_drul; + 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)); } - else - do - { - Direction od = (Direction)-d; - if (snapped_b_drul[d] - && d * sign (snapy_f_drul[d] - dy_f_drul_[od]) == sign (dy_f) - && (!dy_f || (abs (snapy_f_drul[d] - dy_f_drul_[od] - d * dy_f) - < maxsnap))) - { - dy_f_drul_[d] = snapy_f_drul[d]; - dx_f_drul_[d] = snapx_f_drul[d]; - } - } - while (flip (&d) != LEFT); + return o; } - int Slur::cross_staff_count ()const { Link_array encompass_arr = - Group_interface__extract_elements (this, (Note_column*)0, "note-columns"); + Pointer_group_interface__extract_elements (this, (Note_column*)0, "note-columns"); int k=0; @@ -459,36 +341,30 @@ Array Slur::get_encompass_offset_arr () const { Link_array encompass_arr = - Group_interface__extract_elements (this, (Note_column*)0, "note-columns"); + Pointer_group_interface__extract_elements (this, (Note_column*)0, "note-columns"); 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] != spanned_drul_[LEFT]) + 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; } @@ -496,7 +372,7 @@ Slur::get_encompass_offset_arr () const /* right is broken edge */ - if (encompass_arr.top () != spanned_drul_[RIGHT]) + if (encompass_arr.top () != get_bound (RIGHT)) { last++; } @@ -507,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; } @@ -519,7 +394,9 @@ Slur::get_rods () const { Array a; Rod r; - r.item_l_drul_ = spanned_drul_; + + r.item_l_drul_[LEFT] = get_bound (LEFT); + r.item_l_drul_[RIGHT] = get_bound (RIGHT); r.distance_f_ = paper_l ()->get_var ("slur_x_minimum"); a.push (r); @@ -527,37 +404,12 @@ Slur::get_rods () const } - -#if 0 -SCM -ugly_scm (Bezier b) -{ - b.translate (-b.control_[0]); - Real alpha = b.control_[3].arg (); - - b.rotate ( -alpha); - if (b.control_[1][Y_AXIS] < 0) - { - b.control_[1][Y_AXIS] *= -1; - b.control_[2][Y_AXIS] *= -1; - } - - Real len = b.control_[3][X_AXIS]; - Real indent = 10 *b.control_[1][X_AXIS] / len ; - Real ht = 10 *b.control_[1][Y_AXIS] / len ; - - SCM res = scm_eval (scm_listify (ly_symbol2scm ("slur-ugly"), gh_double2scm (indent), gh_double2scm (ht), SCM_UNDEFINED )); - - return res; -} -#endif - - /* Ugh should have dash-length + dash-period */ -Molecule* -Slur::do_brew_molecule_p () const +GLUE_SCORE_ELEMENT(Slur,brew_molecule); +SCM +Slur::member_brew_molecule () const { Real thick = paper_l ()->get_var ("slur_thickness"); Bezier one = get_curve (); @@ -567,41 +419,79 @@ Slur::do_brew_molecule_p () 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); -#if 0 - SCM u = ugly_scm (one); - if (gh_pair_p (u)) - { - Molecule mark = lookup_l ()-> text ( "roman", - to_str (gh_scm2double (gh_car (u)), "%0.2f") + "," + - to_str(gh_scm2double (gh_cdr (u)), "%0.2f"), - paper_l ()); + return a.create_scheme(); +} - mark.translate_axis (20 , Y_AXIS); - a.add_molecule (mark); +void +Slur::set_control_points () +{ + Slur_bezier_bow bb (get_encompass_offset_arr (), + 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; + Real r_0 = paper_l ()->get_var ("slur_ratio"); + + bb.set_default_bezier (h_inf, r_0); + + if (bb.fit_factor () > 1.0) + { + Real length = bb.curve_.control_[3][X_AXIS]; + Real default_height = bb.get_default_height (h_inf, r_0, length); + bb.minimise_enclosed_area (paper_l(), default_height); + + Real bff = paper_l ()->get_var ("slur_force_blowfit"); + bb.curve_.control_[1][Y_AXIS] *= bff; + bb.curve_.control_[2][Y_AXIS] *= bff; + bb.blow_fit (); + + Real sb = paper_l ()->get_var ("slur_beautiful"); + Real beautiful = length * default_height * sb; + Real area = bb.enclosed_area_f (); + + /* + Slurs that fit beautifully are not ugly + */ + if (area > beautiful) + de_uglyfy (&bb, default_height); } -#endif - return new Molecule (a); -} + Bezier b = bb.get_bezier (); + SCM controls = SCM_EOL; + for (int i= 4; i--;) + controls = gh_cons ( ly_offset2scm (b.control_[i]), controls); + + set_elt_property ("control-points", controls); +} + + Bezier Slur::get_curve () const { - Array enc (get_encompass_offset_arr ()); - Direction dir = directional_element (this).get (); - Bezier_bow b (enc,dir); - - b.ratio_ = paper_l ()->get_var ("slur_ratio"); - b.height_limit_ = paper_l ()->get_var ("slur_height_limit"); - b.rc_factor_ = paper_l ()->get_var ("slur_rc_factor"); - - b.calculate (); - - Bezier curve = b.get_curve (); + Bezier b; + int i = 0; + 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"))) + ((Slur*)this)->set_control_points (); + + + for (SCM s= get_elt_property ("control-points"); s != SCM_EOL; s = gh_cdr (s)) + { + b.control_[i] = ly_scm2offset (gh_car (s)); + i++; + } + + Array enc (get_encompass_offset_arr ()); + Direction dir = Directional_element_interface (this).get (); + Real x1 = enc[0][X_AXIS]; Real x2 = enc.top ()[X_AXIS]; @@ -611,11 +501,11 @@ Slur::get_curve () const Real x = enc[i][X_AXIS]; if (x > x1 && x ? dir * (enc[i][Y_AXIS] - y); } } - curve.translate (Offset (0, dir * off)); - return curve; + b.translate (Offset (0, dir * off)); + return b; }