From b37946fa1a9c41aa5ad4ee460a837ad101780b5b Mon Sep 17 00:00:00 2001 From: hanwen Date: Sun, 18 Jul 2004 12:26:40 +0000 Subject: [PATCH] * lily/new-slur.cc: cleanup, split in functions. * lily/parser.yy (chord_body_element): allow octave-check = inside chord body. * lily/new-slur.cc (score_encompass): variable head-distance penalty. * lily/new-slur.cc (print): use debug-slur-quanting paper var. --- ChangeLog | 5 + input/regression/new-slur.ly | 13 +- lily/new-slur.cc | 458 +++++++++++++++++++++-------------- lily/parser.yy | 22 +- 4 files changed, 308 insertions(+), 190 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3932c36842..f9070154d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2004-07-18 Han-Wen Nienhuys + * lily/new-slur.cc: cleanup, split in functions. + + * lily/parser.yy (chord_body_element): allow octave-check = inside + chord body. + * lily/new-slur.cc (score_encompass): variable head-distance penalty. * lily/stem.cc (height): call Beam::after_line_breaking(). diff --git a/input/regression/new-slur.ly b/input/regression/new-slur.ly index 4547c9a5a6..5c4a5820b9 100644 --- a/input/regression/new-slur.ly +++ b/input/regression/new-slur.ly @@ -22,20 +22,21 @@ } d8.[) c16] d8.[ \grace f16( e16)] - + s2 << {c=''8.([ es16] bes4~bes )} \\ {r8 r r } >> + s4 f'=''16( e) d( c) + s2. + c'=''2(~c8 d16 c b8 a) - f='4 f - | 4 ( f ) - f - ^( f ) - f + + 4 ( f ) f + ^( f ) f _( f ) _( g ) _( \stemDown g \stemBoth ) diff --git a/lily/new-slur.cc b/lily/new-slur.cc index 42cfa6c8af..883e19c006 100644 --- a/lily/new-slur.cc +++ b/lily/new-slur.cc @@ -4,7 +4,7 @@ source file of the GNU LilyPond music typesetter (c) 1996--2004 Han-Wen Nienhuys - Jan Nieuwenhuizen + Jan Nieuwenhuizen */ @@ -72,21 +72,46 @@ struct Bound_info { }; /* - TODO: put in details list. - */ -const int SLUR_REGION_SIZE = 5; -const Real HEAD_ENCOMPASS_PENALTY = 1000.0; -const Real STEM_ENCOMPASS_PENALTY = 30.0; -const Real CLOSENESS_FACTOR = 10; -const Real EDGE_ATTRACTION_FACTOR = 4; -const Real HEAD_FREE_SPACE = 0.3; -const Real SAME_SLOPE_PENALTY = 20; -const Real STEEPER_SLOPE_FACTOR = 50; -const Real NON_HORIZONTAL_PENALTY = 15; -const Real HEAD_STRICT_FREE_SPACE = 0.2; -const Real MAX_SLOPE = 1.1; -const Real MAX_SLOPE_FACTOR = 10; -const Real FREE_HEAD_DISTANCE = 0.5 ; + TODO: put in details property. +*/ +struct Slur_score_parameters +{ + int SLUR_REGION_SIZE ; + Real HEAD_ENCOMPASS_PENALTY ; + Real STEM_ENCOMPASS_PENALTY ; + Real CLOSENESS_FACTOR ; + Real EDGE_ATTRACTION_FACTOR ; + Real SAME_SLOPE_PENALTY ; + Real STEEPER_SLOPE_FACTOR ; + Real NON_HORIZONTAL_PENALTY ; + Real HEAD_STRICT_FREE_SPACE ; + Real MAX_SLOPE ; + Real MAX_SLOPE_FACTOR ; + Real FREE_HEAD_DISTANCE ; + Slur_score_parameters (); +}; + +void +init_score_param (Slur_score_parameters *score_param) +{ + score_param->SLUR_REGION_SIZE = 5; + score_param->HEAD_ENCOMPASS_PENALTY = 1000.0; + score_param->STEM_ENCOMPASS_PENALTY = 30.0; + score_param->CLOSENESS_FACTOR = 10; + score_param->EDGE_ATTRACTION_FACTOR = 4; + score_param->SAME_SLOPE_PENALTY = 20; + score_param->STEEPER_SLOPE_FACTOR = 50; + score_param->NON_HORIZONTAL_PENALTY = 15; + score_param->HEAD_STRICT_FREE_SPACE = 0.2; + score_param->MAX_SLOPE = 1.1; + score_param->MAX_SLOPE_FACTOR = 10; + score_param->FREE_HEAD_DISTANCE = 0.3 ; +} + +Slur_score_parameters::Slur_score_parameters() +{ + init_score_param (this); +} #define DEBUG_SLUR_QUANTING 1 @@ -110,35 +135,57 @@ public: static void add_column (Grob *me, Grob *col); DECLARE_SCHEME_CALLBACK (print, (SCM)); static void score_slopes (Grob * me, Grob *common[], + Slur_score_parameters * score_param, + Drul_array, Drul_array base_attach, Array * scores); static void score_edges (Grob * me, Grob *common[], - Drul_array extremes, - Drul_array base_attach, - Array * scores); - static void score_encompass (Grob * me, Grob *common[], - Drul_array, - Drul_array, Array * scores); + Slur_score_parameters * score_param, + + Drul_array extremes, + Drul_array base_attach, + Array * scores); + static void score_encompass (Grob * me, Grob *common[], + Slur_score_parameters*, + Drul_array, + Drul_array, Array * scores); + + static Encompass_info get_encompass_info (Grob *me, + Grob *col, + Grob **common) ; static void set_interface (Grob*); static bool has_interface (Grob*); - static Array get_encompass_offsets (Grob *me); static Bezier get_curve (Grob *me); static Bezier get_bezier (Grob *me, Drul_array,Real,Real); static Direction get_default_dir (Grob *me); DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM)); DECLARE_SCHEME_CALLBACK (height, (SCM,SCM)); -private: + static void set_end_points (Grob*); static Real get_boundary_notecolumn_y (Grob *me, Direction dir); static Real broken_trend_y (Grob *me, Grob**, Direction dir); - static Offset get_attachment (Grob *me,Direction dir, Grob **common); - static void de_uglyfy (Grob *me,Slur_bezier_bow* bb, Real default_height); - static SCM set_extremities (Grob *me); static void set_control_points (Grob *me); - static void check_slope (Grob *me); - static Encompass_info get_encompass_info (Grob *me, Grob *col, Grob **common); + static Drul_array get_bound_info (Spanner* me, + Grob **common); + + static void generate_curves (Grob*me, Array *scores); + static Array enumerate_attachments (Grob * me, Grob *common[], + Slur_score_parameters * score_param, + Drul_array extremes, + Drul_array base_attachment, Drul_array end_ys); + ; + static Drul_array get_base_attachments (Spanner*sp, + Grob **common, + + Drul_array extremes); + + static Drul_array get_y_attachment_range (Spanner*sp, + Grob **common, + + Drul_array extremes, + Drul_array base_attachment); }; Real @@ -159,7 +206,7 @@ New_slur::broken_trend_y (Grob *me, Grob**common, Direction hdir) Grob *neighbor = mother->broken_intos_[j]; if (hdir == RIGHT) neighbor->set_property ("direction", - me->get_property ("direction")); + me->get_property ("direction")); Spanner * common_mother = dynamic_cast (common[Y_AXIS]->original_); int common_k = broken_spanner_index (dynamic_cast (common[Y_AXIS])); @@ -213,8 +260,8 @@ New_slur::add_column (Grob*me, Grob*n) Encompass_info New_slur::get_encompass_info (Grob *me, - Grob *col, - Grob **common) + Grob *col, + Grob **common) { Grob* stem = unsmob_grob (col->get_property ("stem")); @@ -310,22 +357,51 @@ New_slur::get_bezier (Grob *me, Drul_array extremes, return bb.get_bezier (); } + +Drul_array +New_slur::get_bound_info (Spanner* me, + Grob **common) +{ + Drul_array extremes; + Direction d = LEFT; + Direction dir = get_grob_direction (me); + + do { + extremes[d].bound_ = me->get_bound (d); + + if (Note_column::has_interface (extremes[d].bound_)) + { + extremes[d].note_column_ = extremes[d].bound_; + extremes[d].stem_ = Note_column::get_stem (extremes[d].note_column_); + extremes[d].stem_dir_ = get_grob_direction (extremes[d].stem_); + extremes[d].stem_extent_[X_AXIS] = extremes[d].stem_->extent (common[X_AXIS], X_AXIS); + extremes[d].stem_extent_[Y_AXIS] = extremes[d].stem_->extent (common[Y_AXIS], Y_AXIS); + extremes[d].slur_head_ = Stem::extremal_heads (extremes[d].stem_)[dir]; + extremes[d].slur_head_extent_ = extremes[d].slur_head_->extent (common[X_AXIS], X_AXIS); + extremes[d].staff_ = Staff_symbol_referencer::get_staff_symbol (extremes[d].slur_head_); + } + else + { + extremes[d].neighbor_y_ = broken_trend_y (me, common, d); + } + } while (flip (&d) != LEFT); + + return extremes; +} + void New_slur::set_end_points (Grob *me) { Link_array columns = Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-columns"); + + Slur_score_parameters params; if (columns.is_empty ()) { me->suicide (); return ; } - Real staff_space = Staff_symbol_referencer::staff_space ((Grob*)me); - Real minimum_length = staff_space * robust_scm2double (me->get_property ("minimum-length"), - 2.0); - - Drul_array base_attachment; SCM eltlist = me->get_property ("note-columns"); Grob *common[] = {common_refpoint_of_list (eltlist, me, X_AXIS), @@ -337,31 +413,117 @@ New_slur::set_end_points (Grob *me) common[X_AXIS] = common[X_AXIS]->common_refpoint (sp->get_bound (LEFT), X_AXIS); - Drul_array extremes; - Direction dir = get_grob_direction (me); + Drul_array extremes = get_bound_info (sp, common); + Drul_array base_attachment = get_base_attachments (sp, common, extremes); + Drul_array end_ys = get_y_attachment_range (sp, common, extremes, base_attachment); + Array scores = enumerate_attachments (me, common, + ¶ms, extremes, base_attachment, end_ys); + generate_curves (me, &scores); + + score_edges (me, common, ¶ms,extremes, base_attachment, &scores); + score_slopes (me, common, ¶ms,extremes, base_attachment, &scores); + score_encompass (me, common, ¶ms,extremes, base_attachment, &scores); + + Real opt = 1e6; + int opt_idx = 0; + for (int i = scores.size (); i--;) + { + if (scores[i].score_ < opt) + { + opt = scores[i].score_; + opt_idx = i; + } + } + +#if DEBUG_SLUR_QUANTING + SCM inspect_quants = me->get_property ("inspect-quants"); + if (to_boolean (me->get_paper ()->lookup_variable (ly_symbol2scm ("debug-slur-quanting"))) + && ly_c_pair_p (inspect_quants)) + { + Drul_array ins = ly_scm2interval (inspect_quants); + int i = 0; + + Real mindist = 1e6; + for (; i < scores.size (); i ++) + { + Real d =fabs (scores[i].attachment_[LEFT][Y_AXIS] - ins[LEFT]) + + fabs (scores[i].attachment_[RIGHT][Y_AXIS] - ins[RIGHT]); + if (d < mindist) + { + opt_idx = i; + mindist= d; + } + } + if (mindist > 1e5) + programming_error ("Could not find quant."); + } + scores[opt_idx].score_card_ += to_string ("i%d", opt_idx); + + // debug quanting + me->set_property ("quant-score", + scm_makfrom0str (scores[opt_idx].score_card_.to_str0 ())); +#endif + + Bezier const &b = scores[opt_idx].curve_; + + SCM controls = SCM_EOL; + for (int i = 4; i--;) + { + Offset o = b.control_[i] - + Offset (me->relative_coordinate (common[X_AXIS], X_AXIS), + me->relative_coordinate (common[Y_AXIS], Y_AXIS)); + + controls = scm_cons (ly_offset2scm (o), controls); + } + + me->set_property ("control-points", controls); +} + + +Drul_array +New_slur::get_y_attachment_range (Spanner*me, + Grob **common, + Drul_array extremes, + Drul_array base_attachment) +{ + Drul_array end_ys; + Direction dir = get_grob_direction (me); Direction d = LEFT; do { - extremes[d].bound_ = dynamic_cast (me)->get_bound (d); - - if (Note_column::has_interface (extremes[d].bound_)) + if (extremes[d].note_column_) { - extremes[d].note_column_ = extremes[d].bound_; - extremes[d].stem_ = Note_column::get_stem (extremes[d].note_column_); - extremes[d].stem_dir_ = get_grob_direction (extremes[d].stem_); - extremes[d].stem_extent_[X_AXIS] = extremes[d].stem_->extent (common[X_AXIS], X_AXIS); - extremes[d].stem_extent_[Y_AXIS] = extremes[d].stem_->extent (common[Y_AXIS], Y_AXIS); - extremes[d].slur_head_ = Stem::extremal_heads (extremes[d].stem_)[dir]; - extremes[d].slur_head_extent_ = extremes[d].slur_head_->extent (common[X_AXIS], X_AXIS); - extremes[d].staff_ = Staff_symbol_referencer::get_staff_symbol (extremes[d].slur_head_); + end_ys[d] = dir * ((dir * (base_attachment[d][Y_AXIS] + 4.0 *dir)) + >? (dir * (dir + extremes[d].note_column_->extent(common[Y_AXIS],Y_AXIS)[dir])) + >? (dir * base_attachment[-d][Y_AXIS]) + ); } else { - extremes[d].neighbor_y_ = broken_trend_y (me, common, d); + end_ys[d] = extremes[d].neighbor_y_ + 4.0 * dir ; } } while (flip (&d) != LEFT); - + + return end_ys; +} + +Drul_array +New_slur::get_base_attachments (Spanner*me, + Grob **common, + Drul_array extremes) +{ + Link_array columns = + Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-columns"); + Drul_array base_attachment; + + + Slur_score_parameters params; + + Real staff_space = Staff_symbol_referencer::staff_space ((Grob*)me); + + Direction dir = get_grob_direction (me); + Direction d = LEFT; do { Grob *stem = extremes[d].stem_; @@ -374,7 +536,7 @@ New_slur::set_end_points (Grob *me) if (d== RIGHT) x = extremes[d].bound_->extent (common[X_AXIS], X_AXIS)[d]; else - x = sp->get_broken_left_end_align (); + x = me->get_broken_left_end_align (); } else { @@ -411,29 +573,45 @@ New_slur::set_end_points (Grob *me) } while (flip (&d) != LEFT); - - Interval end_ys; - do { - if (extremes[d].note_column_) - { - end_ys[d] = dir * ((dir * (base_attachment[d][Y_AXIS] + 4.0 *dir)) - >? (dir * (dir + extremes[d].note_column_->extent(common[Y_AXIS],Y_AXIS)[dir])) - >? (dir * base_attachment[-d][Y_AXIS]) - ); - } - else - { - end_ys[d] = extremes[d].neighbor_y_ + 4.0 * dir ; - } - } while (flip (&d) != LEFT); - + return base_attachment; +} + + + +void +New_slur::generate_curves (Grob*me, Array *scores) + +{ + + Real staff_space = Staff_symbol_referencer::staff_space ((Grob*)me); + + Real r_0 = robust_scm2double (me->get_property ("ratio"), 1); + Real h_inf = staff_space * ly_scm2double (me->get_property ("height-limit")); + for (int i = scores->size(); i-- ;) + { + (*scores)[i].curve_ = get_bezier (me, (*scores)[i].attachment_, + r_0, h_inf); + } +} + +Array +New_slur::enumerate_attachments (Grob * me, Grob *common[], + Slur_score_parameters * score_param, + Drul_array extremes, + Drul_array base_attachment, + Drul_array end_ys) +{ + /*ugh. */ Array scores; + + Direction dir = get_grob_direction (me); + Real staff_space = Staff_symbol_referencer::staff_space ((Grob*)me); Drul_array os; - - /*ugh. */ os[LEFT] = base_attachment[LEFT]; - + Real minimum_length = staff_space * robust_scm2double (me->get_property ("minimum-length"), + 2.0); + for (int i = 0; dir * os[LEFT][Y_AXIS] <= dir * end_ys[LEFT]; i++) { os[RIGHT] = base_attachment[RIGHT]; @@ -463,7 +641,7 @@ New_slur::set_end_points (Grob *me) Offset dz = os[RIGHT] - os[LEFT]; if (dz[X_AXIS] < minimum_length - || fabs (dz[Y_AXIS] / dz[X_AXIS]) > MAX_SLOPE + || fabs (dz[Y_AXIS] / dz[X_AXIS]) > score_param->MAX_SLOPE ) { do { @@ -480,82 +658,15 @@ New_slur::set_end_points (Grob *me) os[LEFT][Y_AXIS] += dir * staff_space /2 ; } - - { - Real r_0 = robust_scm2double (me->get_property ("ratio"), 1); - Real h_inf = staff_space * ly_scm2double (me->get_property ("height-limit")); - for (int i = scores.size(); i-- ;) - { - scores[i].curve_ = get_bezier (me, scores[i].attachment_, - r_0, h_inf); - } - } - - score_edges (me, common, extremes, base_attachment, &scores); - score_slopes (me, common, extremes, base_attachment, &scores); - score_encompass (me, common, extremes, base_attachment, &scores); - - Real opt = 1e6; - int opt_idx = 0; - for (int i = scores.size (); i--;) - { - if (scores[i].score_ < opt) - { - opt = scores[i].score_; - opt_idx = i; - } - } - - -#if DEBUG_SLUR_QUANTING - SCM inspect_quants = me->get_property ("inspect-quants"); - if (to_boolean (me->get_paper ()->lookup_variable (ly_symbol2scm ("debug-slur-quanting"))) - && ly_c_pair_p (inspect_quants)) - { - Drul_array ins = ly_scm2interval (inspect_quants); - int i = 0; - - Real mindist = 1e6; - for (; i < scores.size (); i ++) - { - Real d =fabs (scores[i].attachment_[LEFT][Y_AXIS] - ins[LEFT]) - + fabs (scores[i].attachment_[RIGHT][Y_AXIS] - ins[RIGHT]); - if (d < mindist) - { - opt_idx = i; - mindist= d; - } - } - if (mindist > 1e5) - programming_error ("Could not find quant."); - } - - - scores[opt_idx].score_card_ += to_string ("i%d", opt_idx); - - // debug quanting - me->set_property ("quant-score", - scm_makfrom0str (scores[opt_idx].score_card_.to_str0 ())); -#endif - - Bezier const &b = scores[opt_idx].curve_; - - SCM controls = SCM_EOL; - for (int i = 4; i--;) - { - Offset o = b.control_[i] - - Offset (me->relative_coordinate (common[X_AXIS], X_AXIS), - me->relative_coordinate (common[Y_AXIS], Y_AXIS)); - - controls = scm_cons (ly_offset2scm (o), controls); - } - - me->set_property ("control-points", controls); + return scores; } + void New_slur::score_encompass (Grob * me, Grob *common[], + Slur_score_parameters * score_param, + Drul_array extremes, Drul_array base_attach, Array * scores) @@ -585,27 +696,27 @@ New_slur::score_encompass (Grob * me, Grob *common[], Real head_dy = (y - infos[j].head_); if (dir * head_dy < 0) { - demerit += HEAD_ENCOMPASS_PENALTY; + demerit += score_param->HEAD_ENCOMPASS_PENALTY; } else { Real hd = - (head_dy) ? (1/(fabs (head_dy) - 1/FREE_HEAD_DISTANCE)) - : HEAD_ENCOMPASS_PENALTY; - hd = (hd >? 0)FREE_HEAD_DISTANCE)) + : score_param->HEAD_ENCOMPASS_PENALTY; + hd = (hd >? 0)HEAD_ENCOMPASS_PENALTY; demerit += hd; } if (dir * (y - infos[j].stem_) < 0) - demerit += STEM_ENCOMPASS_PENALTY; + demerit += score_param->STEM_ENCOMPASS_PENALTY; else if (j && j < encompasses.size () - 1) { Interval ext; ext.add_point (infos[j].stem_); ext.add_point (infos[j].head_); - demerit += - CLOSENESS_FACTOR * (dir * (y - (ext[dir] + dir * HEAD_FREE_SPACE)) CLOSENESS_FACTOR * (dir * (y - (ext[dir] + dir * score_param->FREE_HEAD_DISTANCE)) extremes, - Drul_array base_attach, - Array * scores) + Slur_score_parameters * score_param, + + Drul_array extremes, + Drul_array base_attach, + Array * scores) { - Direction dir = get_grob_direction (me); + Direction dir = get_grob_direction (me); for (int i =0 ; i < scores->size (); i++) { @@ -635,22 +748,10 @@ New_slur::score_edges (Grob * me, Grob *common[], Real y = scores->elem (i).attachment_[d][Y_AXIS]; Real dy = fabs (y - base_attach[d][Y_AXIS]); - Real factor = EDGE_ATTRACTION_FACTOR; + Real factor = score_param->EDGE_ATTRACTION_FACTOR; -#if 0 - if (extremes[d].stem_ && extremes[d].stem_dir_ == dir) - { - if (!extremes[d].stem_extent_[Y_AXIS].contains (y)) - { - dy = fabs (extremes[d].stem_extent_[Y_AXIS][dir] - y); - } - else - factor *= 0.3; - } - Real demerit = dy * factor; -#else Real demerit = - EDGE_ATTRACTION_FACTOR + score_param->EDGE_ATTRACTION_FACTOR * fabs (scores->elem (i).attachment_[d][Y_AXIS] - base_attach[d][Y_AXIS]); if (extremes[d].stem_ @@ -658,8 +759,6 @@ New_slur::score_edges (Grob * me, Grob *common[], && !Stem::get_beaming (extremes[d].stem_, -d) ) demerit /= 5; - -#endif (*scores)[i].score_ += demerit; #if DEBUG_SLUR_QUANTING @@ -671,6 +770,7 @@ New_slur::score_edges (Grob * me, Grob *common[], void New_slur::score_slopes (Grob * me, Grob *common[], + Slur_score_parameters*score_param, Drul_array extremes, Drul_array base_attach, Array * scores) @@ -703,19 +803,19 @@ New_slur::score_slopes (Grob * me, Grob *common[], Real demerit = 0.0; if (!has_beams) - demerit += STEEPER_SLOPE_FACTOR * (dir * (fabs (slur_dy) - fabs (dy)) >? 0); + demerit += score_param->STEEPER_SLOPE_FACTOR * (dir * (fabs (slur_dy) - fabs (dy)) >? 0); - demerit += ((fabs (slur_dy/slur_dz[X_AXIS]) - MAX_SLOPE)>?0) * MAX_SLOPE_FACTOR; + demerit += ((fabs (slur_dy/slur_dz[X_AXIS]) - score_param->MAX_SLOPE)>?0) * score_param->MAX_SLOPE_FACTOR; if (sign (dy) == 0 && sign (slur_dy) != 0) - demerit += NON_HORIZONTAL_PENALTY; + demerit += score_param->NON_HORIZONTAL_PENALTY; if (sign (dy) && sign (slur_dy) && sign (slur_dy) != sign (dy)) demerit += - has_beams ? SAME_SLOPE_PENALTY/10 : SAME_SLOPE_PENALTY; + has_beams ? score_param->SAME_SLOPE_PENALTY/10 : score_param->SAME_SLOPE_PENALTY; #if DEBUG_SLUR_QUANTING (*scores)[i].score_card_ += to_string ("S%.2f",d); @@ -756,7 +856,7 @@ New_slur::height (SCM smob, SCM ax) /* Ugh should have dash-length + dash-period - */ +*/ MAKE_SCHEME_CALLBACK (New_slur, print,1); SCM New_slur::print (SCM smob) @@ -778,7 +878,7 @@ New_slur::print (SCM smob) /* TODO: replace dashed with generic property. - */ + */ SCM d = me->get_property ("dashed"); if (ly_c_number_p (d)) a = Lookup::dashed_slur (one, thick, thick * robust_scm2double (d, 0)); @@ -796,7 +896,7 @@ New_slur::print (SCM smob) SCM properties = Font_interface::text_font_alist_chain (me); Stencil tm = *unsmob_stencil (Text_item::interpret_markup - (me->get_paper ()->self_scm (), properties, quant_score)); + (me->get_paper ()->self_scm (), properties, quant_score)); a.add_at_edge (Y_AXIS, get_grob_direction (me), tm, 1.0, 0); } #endif @@ -809,5 +909,5 @@ New_slur::print (SCM smob) ADD_INTERFACE (New_slur, "new-slur-interface", - "A slur", - "attachment attachment-offset beautiful control-points dashed details de-uglify-parameters direction extremity-function extremity-offset-alist height-limit note-columns ratio slope-limit thickness y-free"); + "A slur", + "control-points dashed details direction height-limit note-columns ratio slope-limit thickness"); diff --git a/lily/parser.yy b/lily/parser.yy index 984516cefa..49d14e1399 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1466,19 +1466,31 @@ chord_body_elements: ; chord_body_element: - pitch exclamations questions post_events + pitch exclamations questions octave_check post_events { + int q = $3; + int ex = $2; + SCM check = $4; + SCM post = $5; + Music *n = MY_MAKE_MUSIC ("NoteEvent"); n->set_property ("pitch", $1); - if ($3 % 2) + if (q % 2) n->set_property ("cautionary", SCM_BOOL_T); - if ($2 % 2 || $3 % 2) + if (ex % 2 || q % 2) n->set_property ("force-accidental", SCM_BOOL_T); - if (ly_c_pair_p ($4)) { - SCM arts = scm_reverse_x ($4, SCM_EOL); + if (ly_c_pair_p (post)) { + SCM arts = scm_reverse_x (post, SCM_EOL); n->set_property ("articulations", arts); } + if (ly_c_number_p (check)) + { + int q = ly_scm2int (check); + n->set_property ("absolute-octave", scm_int2num (q-1)); + } + + $$ = n; } | DRUM_PITCH post_events { -- 2.39.5