X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbeam.cc;h=0f76d58caee8feaa4284ec53bd52356977ad8e0b;hb=f47a52d0c0b6f0f2bc39708528ba9cec4882aaa2;hp=e12cd2cdd7ab1e6dd9c79fc6a4e04b25087d4ba4;hpb=f2731e17f7fca531ef4c4d0a2d7299592015745a;p=lilypond.git diff --git a/lily/beam.cc b/lily/beam.cc index e12cd2cdd7..0f76d58cae 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -26,12 +26,13 @@ Notes: */ + #include // tanh. -#include "stencil.hh" +#include "beam.hh" +#include "interval-set.hh" #include "directional-element-interface.hh" #include "beaming.hh" -#include "beam.hh" #include "misc.hh" #include "least-squares.hh" #include "stem.hh" @@ -80,7 +81,7 @@ Beam::get_beam_translation (Grob *me) if (ly_c_procedure_p (func)) { SCM s = scm_call_2 (func, me->self_scm (), scm_int2num (get_beam_count (me))); - return ly_scm2double (s); + return scm_to_double (s); } else { @@ -93,9 +94,9 @@ int Beam::get_beam_count (Grob *me) { int m = 0; - for (SCM s = me->get_property ("stems"); ly_c_pair_p (s); s = ly_cdr (s)) + for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s)) { - Grob *stem = unsmob_grob (ly_car (s)); + Grob *stem = unsmob_grob (scm_car (s)); m = m >? (Stem::beam_multiplicity (stem).length () + 1); } return m; @@ -115,7 +116,7 @@ Beam::space_function (SCM smob, SCM beam_count) Real line = Staff_symbol_referencer::line_thickness (me); Real thickness = get_thickness (me); - Real beam_translation = ly_scm2int (beam_count) < 4 + Real beam_translation = scm_to_int (beam_count) < 4 ? (2*staff_space + line - thickness) / 2.0 : (3*staff_space + line - thickness) / 3.0; @@ -153,7 +154,7 @@ Beam::before_line_breaking (SCM smob) { me->warning (_ ("removing beam with less than two stems")); - unsmob_grob (ly_car (stems))->set_property ("beam", SCM_EOL); + unsmob_grob (scm_car (stems))->set_property ("beam", SCM_EOL); me->suicide (); return SCM_UNSPECIFIED; @@ -199,17 +200,17 @@ position_with_maximal_common_beams (SCM left_beaming, SCM right_beaming, Direction left_dir, Direction right_dir) { - Slice lslice = int_list_to_slice (ly_cdr (left_beaming)); + Slice lslice = int_list_to_slice (scm_cdr (left_beaming)); int best_count = 0; int best_start = 0; for (int i = lslice[-left_dir]; (i - lslice[left_dir])* left_dir <= 0 ; i+= left_dir) { - int count =0; - for ( SCM s = ly_car (right_beaming); ly_c_pair_p (s); s = ly_cdr (s)) + int count = 0; + for ( SCM s = scm_car (right_beaming); scm_is_pair (s); s = scm_cdr (s)) { - int k = - right_dir * ly_scm2int (ly_car (s)) + i; + int k = - right_dir * scm_to_int (scm_car (s)) + i; if (scm_c_memq (scm_int2num (k), left_beaming) != SCM_BOOL_F) count ++; } @@ -227,7 +228,7 @@ position_with_maximal_common_beams (SCM left_beaming, SCM right_beaming, void Beam::connect_beams (Grob *me) { - Link_array stems= + Link_array stems = Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); Slice last_int; @@ -240,7 +241,7 @@ Beam::connect_beams (Grob *me) SCM this_beaming = this_stem->get_property ("beaming"); Direction this_dir = get_grob_direction (this_stem); - if (ly_c_pair_p (last_beaming) && ly_c_pair_p (this_beaming)) + if (scm_is_pair (last_beaming) && scm_is_pair (this_beaming)) { int start_point = position_with_maximal_common_beams (last_beaming, this_beaming, @@ -255,10 +256,10 @@ Beam::connect_beams (Grob *me) new_slice.set_empty (); SCM s = index_get_cell (this_beaming, d); - for (; ly_c_pair_p (s); s = ly_cdr (s)) + for (; scm_is_pair (s); s = scm_cdr (s)) { int new_beam_pos = - start_point - this_dir * ly_scm2int (ly_car (s)); + start_point - this_dir * scm_to_int (scm_car (s)); new_slice.add_point (new_beam_pos); scm_set_car_x (s, scm_int2num (new_beam_pos)); @@ -274,10 +275,10 @@ Beam::connect_beams (Grob *me) else { scm_set_car_x ( this_beaming, SCM_EOL); - SCM s = ly_cdr (this_beaming); - for (; ly_c_pair_p (s); s = ly_cdr (s)) + SCM s = scm_cdr (this_beaming); + for (; scm_is_pair (s); s = scm_cdr (s)) { - int np = - this_dir * ly_scm2int (ly_car (s)); + int np = - this_dir * scm_to_int (scm_car (s)); scm_set_car_x (s, scm_int2num (np)); last_int.add_point (np); } @@ -288,7 +289,7 @@ Beam::connect_beams (Grob *me) scm_set_cdr_x (this_beaming, SCM_EOL); } - if (scm_ilength (ly_cdr (this_beaming)) > 0) + if (scm_ilength (scm_cdr (this_beaming)) > 0) { last_beaming = this_beaming; last_dir = this_dir; @@ -307,7 +308,7 @@ Beam::print (SCM grob) Spanner *me = unsmob_spanner (grob); position_beam (me); - Link_array stems= + Link_array stems = Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); Grob* xcommon = common_refpoint_of_array (stems, me, X_AXIS); @@ -335,12 +336,12 @@ Beam::print (SCM grob) pos = Interval (0,0); } else - pos= ly_scm2realdrul (posns); + pos = ly_scm2realdrul (posns); scale_drul (&pos, Staff_symbol_referencer::staff_space (me)); Real dy = pos[RIGHT] - pos[LEFT]; - Real dydx = (dy && dx) ? dy/dx : 0; + Real slope = (dy && dx) ? dy/dx : 0; Real thick = get_thickness (me); Real bdy = get_beam_translation (me); @@ -352,7 +353,7 @@ Beam::print (SCM grob) Real gap_length = robust_scm2double (me->get_property ("gap"), 0.0); Stencil the_beam; - Real lt = me->get_paper ()->get_dimension (ly_symbol2scm ("linethickness")); + Real lt = me->get_layout ()->get_dimension (ly_symbol2scm ("linethickness")); for (int i = 0; i<= stems.size (); i++) { @@ -367,18 +368,18 @@ Beam::print (SCM grob) right from the left stem, and rfliebertjes pointing left from right stem. */ - SCM left = (i > 0) ? ly_cdr (last_beaming) : SCM_EOL; - SCM right = st ? ly_car (this_beaming) : SCM_EOL; + SCM left = (i > 0) ? scm_cdr (last_beaming) : SCM_EOL; + SCM right = st ? scm_car (this_beaming) : SCM_EOL; Array full_beams; Array lfliebertjes; Array rfliebertjes; for (SCM s = left; - ly_c_pair_p (s); s =ly_cdr (s)) + scm_is_pair (s); s = scm_cdr (s)) { - int b = ly_scm2int (ly_car (s)); - if (scm_c_memq (ly_car (s), right) != SCM_BOOL_F) + int b = scm_to_int (scm_car (s)); + if (scm_c_memq (scm_car (s), right) != SCM_BOOL_F) { full_beams.push (b); } @@ -388,10 +389,10 @@ Beam::print (SCM grob) } } for (SCM s = right; - ly_c_pair_p (s); s =ly_cdr (s)) + scm_is_pair (s); s = scm_cdr (s)) { - int b = ly_scm2int (ly_car (s)); - if (scm_c_memq (ly_car (s), left) == SCM_BOOL_F) + int b = scm_to_int (scm_car (s)); + if (scm_c_memq (scm_car (s), left) == SCM_BOOL_F) { rfliebertjes.push (b); } @@ -403,7 +404,7 @@ Beam::print (SCM grob) Real break_overshoot = 3.0; Real w = (i > 0 && st) ? (xposn - last_xposn) : break_overshoot; - Real stem_offset =0.0; + Real stem_offset = 0.0; if (i > 0) { w += last_stem_width / 2; @@ -414,15 +415,15 @@ Beam::print (SCM grob) w += stem_width/ 2 ; - Real blot = me->get_paper ()->get_dimension (ly_symbol2scm ("blotdiameter")); - Stencil whole = Lookup::beam (dydx, w, thick, blot); + Real blot = me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter")); + Stencil whole = Lookup::beam (slope, w, thick, blot); Stencil gapped; int gap_count = 0; - if (ly_c_number_p (me->get_property ("gap-count"))) + if (scm_is_number (me->get_property ("gap-count"))) { - gap_count = ly_scm2int (me->get_property ("gap-count")); - gapped = Lookup::beam (dydx, w - 2 * gap_length, thick, blot); + gap_count = scm_to_int (me->get_property ("gap-count")); + gapped = Lookup::beam (slope, w - 2 * gap_length, thick, blot); full_beams.sort (default_compare); if (stem_dir == UP) @@ -440,7 +441,7 @@ Beam::print (SCM grob) b.translate_axis (gap_length, X_AXIS); } b.translate_axis (last_xposn - x0 + stem_offset, X_AXIS); - b.translate_axis (dydx * (last_xposn - x0) + bdy * full_beams[j], Y_AXIS); + b.translate_axis (slope * (last_xposn - x0) + bdy * full_beams[j], Y_AXIS); the_beam.add_stencil (b); } @@ -455,7 +456,7 @@ Beam::print (SCM grob) SCM proc = me->get_property ("flag-width-function"); SCM result = scm_call_1 (proc, scm_int2num (t)); - nw_f = ly_scm2double (result); + nw_f = scm_to_double (result); } else nw_f = break_overshoot / 2; @@ -479,20 +480,20 @@ Beam::print (SCM grob) lw = me->get_bound (RIGHT)->relative_coordinate (xcommon, X_AXIS) - last_xposn; - Stencil rhalf = Lookup::beam (dydx, rw, thick, blot); - Stencil lhalf = Lookup::beam (dydx, lw, thick, blot); + Stencil rhalf = Lookup::beam (slope, rw, thick, blot); + Stencil lhalf = Lookup::beam (slope, lw, thick, blot); for (int j = lfliebertjes.size (); j--;) { Stencil b (lhalf); b.translate_axis (last_xposn - x0, X_AXIS); - b.translate_axis (dydx * (last_xposn-x0) + bdy * lfliebertjes[j], Y_AXIS); + b.translate_axis (slope * (last_xposn-x0) + bdy * lfliebertjes[j], Y_AXIS); the_beam.add_stencil (b); } for (int j = rfliebertjes.size (); j--;) { Stencil b (rhalf); b.translate_axis (xposn - x0 - rw , X_AXIS); - b.translate_axis (dydx * (xposn-x0 -rw) + bdy * rfliebertjes[j], Y_AXIS); + b.translate_axis (slope * (xposn-x0 -rw) + bdy * rfliebertjes[j], Y_AXIS); the_beam.add_stencil (b); } } @@ -508,8 +509,8 @@ Beam::print (SCM grob) #if (DEBUG_QUANTING) SCM quant_score = me->get_property ("quant-score"); - if (to_boolean (me->get_paper ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting"))) - && ly_c_string_p (quant_score)) + if (to_boolean (me->get_layout ()->lookup_variable (ly_symbol2scm ("debug-beam-quanting"))) + && scm_is_string (quant_score)) { /* @@ -522,8 +523,8 @@ Beam::print (SCM grob) Direction stem_dir = stems.size() ? to_dir (stems[0]->get_property ("direction")) : UP; - Stencil tm = *unsmob_stencil (Text_item::interpret_markup - (me->get_paper ()->self_scm (), properties, quant_score)); + Stencil tm = *unsmob_stencil (Text_interface::interpret_markup + (me->get_layout ()->self_scm (), properties, quant_score)); the_beam.add_at_edge (Y_AXIS, stem_dir, tm, 1.0, 0); } #endif @@ -543,10 +544,10 @@ Beam::get_default_dir (Grob *me) count[UP] = count[DOWN] = 0; Direction d = DOWN; - Link_array stems= + Link_array stems = Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); - for (int i=0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) do { Grob *s = stems[i]; Direction sd = get_grob_direction (s); @@ -568,7 +569,7 @@ Beam::get_default_dir (Grob *me) scm_cons (scm_int2num (total[UP]), scm_int2num (total[DOWN]))); - if (ly_c_number_p (s) && ly_scm2int (s)) + if (scm_is_number (s) && scm_to_int (s)) return to_dir (s); /* If dir is not determined: get default */ @@ -583,9 +584,9 @@ void Beam::set_stem_directions (Grob *me, Direction d) { Link_array stems - =Pointer_group_interface__extract_grobs (me, (Grob*) 0, "stems"); + = Pointer_group_interface__extract_grobs (me, (Grob*) 0, "stems"); - for (int i=0; i allowed_regions_; - - Int_set () - { - set_full (); - } - - void set_full () - { - allowed_regions_.clear (); - Interval s; - s.set_full (); - allowed_regions_.push (s); - } - - void remove_interval (Interval rm) - { - for (int i = 0; i < allowed_regions_.size (); ) - { - Interval s = rm; - - s.intersect (allowed_regions_[i]); - - if (!s.is_empty ()) - { - Interval before = allowed_regions_[i]; - Interval after = allowed_regions_[i]; - - before[RIGHT] = s[LEFT]; - after[LEFT] = s[RIGHT]; - - if (!before.is_empty () && before.length () > 0.0) - { - allowed_regions_.insert (before, i); - i++; - } - allowed_regions_.del (i); - if (!after.is_empty () && after.length () > 0.0) - { - allowed_regions_.insert (after, i); - i++; - } - } - else - i++; - } - } -}; - - /* Only try horizontal beams for knees. No reliable detection of anything else is possible here, since we don't know funky-beaming @@ -664,23 +606,23 @@ void Beam::consider_auto_knees (Grob* me) { SCM scm = me->get_property ("auto-knee-gap"); - if (!ly_c_number_p (scm)) + if (!scm_is_number (scm)) return ; - Real threshold = ly_scm2double (scm); + Real threshold = scm_to_double (scm); - Int_set gaps; + Interval_set gaps; gaps.set_full (); - Link_array stems= + Link_array stems = Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); Grob *common = common_refpoint_of_array (stems, me, Y_AXIS); Real staff_space = Staff_symbol_referencer::staff_space (me); Array hps_array; - for (int i=0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) { Grob* stem = stems[i]; if (Stem::is_invisible (stem)) @@ -713,7 +655,7 @@ Beam::consider_auto_knees (Grob* me) } Interval max_gap; - Real max_gap_len =0.0; + Real max_gap_len = 0.0; for (int i = gaps.allowed_regions_.size () -1; i >= 0 ; i--) { @@ -789,7 +731,7 @@ Beam::set_stem_shorten (Grob *me) SCM shorten_elt = robust_list_ref (beam_count -1, shorten_list); - Real shorten_f = ly_scm2double (shorten_elt) * staff_space; + Real shorten_f = scm_to_double (shorten_elt) * staff_space; /* your similar cute comment here */ shorten_f *= forced_fraction; @@ -815,6 +757,8 @@ Beam::after_line_breaking (SCM smob) void Beam::position_beam (Grob *me) { + if (!me->is_live ()) + return ; if (to_boolean (me->get_property ("positioning-done"))) return ; @@ -824,18 +768,41 @@ Beam::position_beam (Grob *me) SCM s = ly_deep_copy (me->get_property ("positions")); me->set_property ("positions", s); - if (ly_car (s) == SCM_BOOL_F) + if (scm_car (s) == SCM_BOOL_F) { // one wonders if such genericity is necessary --hwn. SCM callbacks = me->get_property ("position-callbacks"); - for (SCM i = callbacks; ly_c_pair_p (i); i = ly_cdr (i)) - scm_call_1 (ly_car (i), me->self_scm ()); + for (SCM i = callbacks; scm_is_pair (i); i = scm_cdr (i)) + scm_call_1 (scm_car (i), me->self_scm ()); } set_stem_lengths (me); } +void +set_minimum_dy (Grob *me, Real * dy) +{ + if (*dy) + { + /* + If dy is smaller than the smallest quant, we + get absurd direction-sign penalties. + */ + + Real ss = Staff_symbol_referencer::staff_space (me); + Real thickness = Beam::get_thickness (me) / ss ; + Real slt = Staff_symbol_referencer::line_thickness (me) / ss; + Real sit = (thickness - slt) / 2; + Real inter = 0.5; + Real hang = 1.0 - (thickness - slt) / 2; + + *dy = sign (*dy) * (fabs (*dy) + >? + (sit x_posns ; - Link_array stems= + Link_array stems = Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); Grob *commony = common_refpoint_of_array (stems, me, Y_AXIS); @@ -872,7 +839,7 @@ Beam::least_squares (SCM smob) + lvs->relative_coordinate (commony, Y_AXIS) - my_y); Real x0 = first_visible_stem (me)->relative_coordinate (commonx, X_AXIS); - for (int i=0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) { Grob* s = stems[i]; @@ -882,8 +849,8 @@ Beam::least_squares (SCM smob) Real dx = last_visible_stem (me)->relative_coordinate (commonx, X_AXIS) - x0; - Real y =0; - Real dydx = 0; + Real y = 0; + Real slope = 0; Real dy = 0; if (!ideal.delta ()) @@ -921,7 +888,7 @@ Beam::least_squares (SCM smob) else { Array ideals; - for (int i=0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) { Grob* s = stems[i]; if (Stem::is_invisible (s)) @@ -932,9 +899,11 @@ Beam::least_squares (SCM smob) - my_y)); } - minimise_least_squares (&dydx, &y, ideals); + minimise_least_squares (&slope, &y, ideals); + + dy = slope * dx; - dy = dydx * dx; + set_minimum_dy (me,&dy); me->set_property ("least-squares-dy", scm_make_real (dy)); pos = Interval (y, (y+dy)); } @@ -954,10 +923,10 @@ Beam::least_squares (SCM smob) We can't combine with previous function, since check concave and slope damping comes first. -TODO: we should use the concaveness to control the amount of damping -applied. + TODO: we should use the concaveness to control the amount of damping + applied. - */ +*/ MAKE_SCHEME_CALLBACK (Beam, shift_region_to_valid, 1); SCM Beam::shift_region_to_valid (SCM grob) @@ -967,7 +936,7 @@ Beam::shift_region_to_valid (SCM grob) Code dup. */ Array x_posns ; - Link_array stems= + Link_array stems = Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); Grob *commonx = common_refpoint_of_array (stems, me, X_AXIS); Grob *commony = common_refpoint_of_array (stems, me, Y_AXIS); @@ -977,8 +946,8 @@ Beam::shift_region_to_valid (SCM grob) if (!fvs) return SCM_UNSPECIFIED; - Real x0 =fvs->relative_coordinate (commonx, X_AXIS); - for (int i=0; i < stems.size (); i++) + Real x0 = fvs->relative_coordinate (commonx, X_AXIS); + for (int i = 0; i < stems.size (); i++) { Grob* s = stems[i]; @@ -998,7 +967,7 @@ Beam::shift_region_to_valid (SCM grob) Real dy = pos[RIGHT] - pos[LEFT]; Real y = pos[LEFT]; - Real dydx =dy/dx; + Real slope = dy/dx; /* @@ -1007,7 +976,7 @@ Beam::shift_region_to_valid (SCM grob) */ Interval feasible_left_point; feasible_left_point.set_full (); - for (int i=0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) { Grob* s = stems[i]; if (Stem::is_invisible (s)) @@ -1017,7 +986,7 @@ Beam::shift_region_to_valid (SCM grob) Real left_y = Stem::get_stem_info (s).shortest_y_ - - dydx * x_posns [i]; + - slope * x_posns [i]; /* left_y is now relative to the stem S. We want relative to @@ -1053,121 +1022,6 @@ Beam::shift_region_to_valid (SCM grob) return SCM_UNSPECIFIED; } -MAKE_SCHEME_CALLBACK (Beam, check_concave, 1); -SCM -Beam::check_concave (SCM smob) -{ - Grob *me = unsmob_grob (smob); - - Link_array stems = - Pointer_group_interface__extract_grobs (me, (Grob*) 0, "stems"); - - Direction beam_dir = CENTER; - for (int i = 0; i < stems.size ();) - { - if (Stem::is_invisible (stems[i])) - stems.del (i); - else - { - if (Direction sd = Stem::get_direction (stems[i])) - { - /* - Don't do knee beams. - */ - if (beam_dir && sd && sd != beam_dir) - return SCM_UNSPECIFIED; - - beam_dir = sd; - } - i++; - } - } - - if (stems.size () < 3) - return SCM_UNSPECIFIED; - - - /* Concaveness #1: If distance of an inner notehead to line between - two outer noteheads is bigger than CONCAVENESS-GAP (2.0ss), - beam is concave (Heinz Stolba). - - In the case of knees, the line connecting outer heads is often - not related to the beam slope (it may even go in the other - direction). Skip the check when the outer stems point in - different directions. --hwn - - */ - bool is_concave1 = false; - SCM gap = me->get_property ("concaveness-gap"); - if (ly_c_number_p (gap)) - { - Real r1 = ly_scm2double (gap); - Real dy = Stem::chord_start_y (stems.top ()) - - Stem::chord_start_y (stems[0]); - - - Real slope = dy / (stems.size () - 1); - - Real y0 = Stem::chord_start_y (stems[0]); - for (int i = 1; i < stems.size () - 1; i++) - { - Real c = - beam_dir *((Stem::chord_start_y (stems[i]) - y0) - i * slope); - if (c - r1 > 0) - { - is_concave1 = true; - break; - } - } - } - - - /* Concaveness #2: Sum distances of inner noteheads that fall - outside the interval of the two outer noteheads. - - We only do this for beams where first and last stem have the same - direction. --hwn. - - - Note that "convex" stems compensate for "concave" stems. - (is that intentional?) --hwn. - */ - - Real concaveness2 = 0; - SCM thresh = me->get_property ("concaveness-threshold"); - Real r2 = infinity_f; - if (!is_concave1 && ly_c_number_p (thresh)) - { - r2 = ly_scm2double (thresh); - - Interval iv; - iv.add_point (Stem::chord_start_y (stems[0])); - iv.add_point (Stem::chord_start_y (stems.top ())); - - for (int i = 1; i < stems.size () - 1; i++) - { - Real f = Stem::chord_start_y (stems[i]); - concaveness2 += ( (f - iv[MAX] ) >? 0) + - ( (f - iv[MIN] ) plain horizontal */ - if (is_concave1 || concaveness2 > r2) - { - Drul_array pos = ly_scm2interval (me->get_property ("positions")); - Real r = linear_combination (pos, 0); - - r /= Staff_symbol_referencer::staff_space (me); - me->set_property ("positions", ly_interval2scm (Drul_array (r, r))); - me->set_property ("least-squares-dy", scm_make_real (0)); - } - - return SCM_UNSPECIFIED; -} - /* This neat trick is by Werner Lemberg, damped = tanh (slope) corresponds with some tables in [Wanske] CHECKME */ @@ -1181,11 +1035,11 @@ Beam::slope_damping (SCM smob) return SCM_UNSPECIFIED; SCM s = me->get_property ("damping"); - int damping = ly_scm2int (s); + Real damping = scm_to_double (s); if (damping) { - Drul_array pos = ly_scm2interval (me->get_property ("positions")); + Drul_array pos = ly_scm2interval (me->get_property ("positions")); scale_drul (&pos, Staff_symbol_referencer::staff_space (me)); Real dy = pos[RIGHT] - pos[LEFT]; @@ -1198,10 +1052,17 @@ Beam::slope_damping (SCM smob) Real dx = last_visible_stem (me)->relative_coordinate (commonx, X_AXIS) - first_visible_stem (me)->relative_coordinate (commonx, X_AXIS); - Real dydx = dy && dx ? dy/dx : 0; - dydx = 0.6 * tanh (dydx) / damping; - Real damped_dy = dydx * dx; + Real slope = dy && dx ? dy/dx : 0; + + Real concaveness = robust_scm2double (me->get_property ("concaveness"), 0.0); + + slope = 0.6 * tanh (slope) / (damping + concaveness); + + Real damped_dy = slope * dx; + + set_minimum_dy (me, &damped_dy); + pos[LEFT] += (dy - damped_dy) / 2; pos[RIGHT] -= (dy - damped_dy) / 2; @@ -1221,11 +1082,11 @@ where_are_the_whole_beams (SCM beaming) { Slice l; - for ( SCM s = ly_car (beaming); ly_c_pair_p (s) ; s = ly_cdr (s)) + for ( SCM s = scm_car (beaming); scm_is_pair (s) ; s = scm_cdr (s)) { - if (scm_c_memq (ly_car (s), ly_cdr (beaming)) != SCM_BOOL_F) + if (scm_c_memq (scm_car (s), scm_cdr (beaming)) != SCM_BOOL_F) - l.add_point (ly_scm2int (ly_car (s))); + l.add_point (scm_to_int (scm_car (s))); } return l; @@ -1263,7 +1124,7 @@ Beam::calc_stem_y (Grob *me, Grob* s, Grob ** common, { Slice bm = Stem::beam_multiplicity (s); if (!bm.is_empty ()) - stem_y +=bm[my_dir] * beam_translation; + stem_y += bm[my_dir] * beam_translation; } Real id = me->relative_coordinate (common[Y_AXIS], Y_AXIS) @@ -1279,7 +1140,7 @@ Beam::calc_stem_y (Grob *me, Grob* s, Grob ** common, void Beam::set_stem_lengths (Grob *me) { - Link_array stems= + Link_array stems = Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); if (!stems.size ()) @@ -1294,9 +1155,9 @@ Beam::set_stem_lengths (Grob *me) scale_drul (&pos, staff_space); bool gap = false; - Real thick =0.0; - if (ly_c_number_p (me->get_property ("gap-count")) - &&ly_scm2int (me->get_property ("gap-count"))) + Real thick = 0.0; + if (scm_is_number (me->get_property ("gap-count")) + &&scm_to_int (me->get_property ("gap-count"))) { gap = true; thick = get_thickness (me); @@ -1309,7 +1170,7 @@ Beam::set_stem_lengths (Grob *me) Real xl = fvs ? fvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0; Real xr = lvs ? lvs->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0; - for (int i=0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) { Grob* s = stems[i]; if (Stem::is_invisible (s)) @@ -1334,11 +1195,11 @@ Beam::set_stem_lengths (Grob *me) void Beam::set_beaming (Grob *me, Beaming_info_list *beaming) { - Link_array stems= + Link_array stems = Pointer_group_interface__extract_grobs (me, (Grob *)0, "stems"); Direction d = LEFT; - for (int i=0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) { /* Don't overwrite user settings. @@ -1375,7 +1236,7 @@ Beam::forced_stem_count (Grob *me) Link_arraystems = Pointer_group_interface__extract_grobs (me, (Grob*) 0, "stems"); int f = 0; - for (int i=0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) { Grob *s = stems[i]; @@ -1451,9 +1312,9 @@ SCM Beam::rest_collision_callback (SCM element_smob, SCM axis) { Grob *rest = unsmob_grob (element_smob); - Axis a = (Axis) ly_scm2int (axis); + Axis a = (Axis) scm_to_int (axis); - if (ly_c_number_p (rest->get_property ("staff-position"))) + if (scm_is_number (rest->get_property ("staff-position"))) return scm_int2num (0); assert (a == Y_AXIS); @@ -1470,7 +1331,7 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis) Drul_array pos (0, 0); SCM s = beam->get_property ("positions"); - if (ly_c_pair_p (s) && ly_c_number_p (ly_car (s))) + if (scm_is_pair (s) && scm_is_number (scm_car (s))) pos = ly_scm2interval (s); Real staff_space = Staff_symbol_referencer::staff_space (rest); @@ -1482,15 +1343,20 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis) // ugh -> use commonx Real x0 = first_visible_stem (beam)->relative_coordinate (0, X_AXIS); Real dx = last_visible_stem (beam)->relative_coordinate (0, X_AXIS) - x0; - Real dydx = dy && dx ? dy/dx : 0; + Real slope = dy && dx ? dy/dx : 0; Direction d = Stem::get_direction (stem); - Real stem_y = pos[LEFT] + (stem->relative_coordinate (0, X_AXIS) - x0) * dydx; + Real stem_y = pos[LEFT] + (stem->relative_coordinate (0, X_AXIS) - x0) * slope; Real beam_translation = get_beam_translation (beam); Real beam_thickness = Beam::get_thickness (beam); + + /* + TODO: this is not strictly correct for 16th knee beams. + */ + int beam_count = + Stem::beam_multiplicity (stem).length() + 1; - int beam_count = get_direction_beam_count (beam, d); Real height_of_my_beams = beam_thickness / 2 + (beam_count - 1) * beam_translation; Real beam_y = stem_y - d * height_of_my_beams; @@ -1499,7 +1365,8 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis) Real rest_dim = rest->extent (common_y, Y_AXIS)[d]; Real minimum_distance = - staff_space * robust_scm2double (rest->get_property ("minimum-distance"), 0.0); + + staff_space * (robust_scm2double (stem->get_property ("stemlet-length"), 0.0) + + robust_scm2double (rest->get_property ("minimum-distance"), 0.0)); Real shift = d * ( ((beam_y - d * minimum_distance) - rest_dim) * d get_property ("knee"); - if (ly_c_boolean_p (k)) + if (scm_is_bool (k)) return ly_scm2bool (k); bool knee = false; int d = 0; - for (SCM s = me->get_property ("stems"); ly_c_pair_p (s); s = ly_cdr (s)) + for (SCM s = me->get_property ("stems"); scm_is_pair (s); s = scm_cdr (s)) { - Direction dir = get_grob_direction (unsmob_grob (ly_car (s))); + Direction dir = get_grob_direction (unsmob_grob (scm_car (s))); if (d && d != dir) { knee = true; @@ -1569,8 +1436,8 @@ ADD_INTERFACE (Beam, "beam-interface", "The @code{thickness} property is the weight of beams, and is measured " "in staffspace" , - "knee positioning-done position-callbacks concaveness-gap " - "concaveness-threshold dir-function quant-score auto-knee-gap gap " + "knee positioning-done position-callbacks " + "concaveness dir-function quant-score auto-knee-gap gap " "gap-count chord-tremolo beamed-stem-shorten shorten least-squares-dy " "damping inspect-quants flag-width-function neutral-direction positions space-function " "thickness");