+ count_ = 0;
+ stems_ = 0;
+ shortest_mom_ = Moment (Rational (1, 8));
+ finished_beam_ = 0;
+ finished_grouping_ = 0;
+ grouping_ = 0;
+ beam_settings_ = SCM_EOL;
+}
+
+/*
+ Determine end moment for auto beaming (or begin moment, but mostly
+ 0==anywhere) In order of increasing priority:
+
+ i. begin anywhere, end at every beat
+ ii. end * <num> <den>
+ iii. end <type> <num> <den>
+
+ iv. end * * *
+ v. end <type> * *
+
+
+ Rationale:
+
+ [to be defined in config file]
+ i. easy catch-all rule
+ ii. exceptions for time signature
+ iii. exceptions for time signature, for specific duration type
+
+ [user override]
+ iv. generic override
+ v. override for specific duration type
+
+*/
+bool
+Auto_beam_engraver::test_moment (Direction dir, Moment test_mom)
+{
+ Moment now = now_mom();
+ if (dir == START
+ && now.grace_part_)
+ {
+ return false;
+ }
+
+ SCM wild = scm_list_n (ly_symbol2scm ("*"), ly_symbol2scm ("*"), SCM_UNDEFINED);
+ SCM function;
+ if (dir == START)
+ function = scm_list_n (ly_symbol2scm ("begin"), SCM_UNDEFINED);
+ else
+ function = scm_list_n (ly_symbol2scm ("end"), SCM_UNDEFINED);
+
+ Moment one_beat = *unsmob_moment (get_property ("beatLength"));
+ int num = int ((*unsmob_moment (get_property ("measureLength")) / one_beat).main_part_);
+ int den = one_beat.den ();
+ SCM time = scm_list_n (gh_int2scm (num), gh_int2scm (den), SCM_UNDEFINED);
+
+ SCM type = scm_list_n (gh_int2scm (test_mom.num ()),
+ gh_int2scm (test_mom.den ()), SCM_UNDEFINED);
+
+ SCM settings = get_property ("autoBeamSettings");
+
+ /* first guess */
+
+ /* begin beam at any position
+ (and fallback for end) */
+ Moment moment (0);
+
+ /* end beam at end of beat */
+ if (dir == STOP)
+ {
+ SCM beat (get_property ("beatLength"));
+
+ if (unsmob_moment (beat))
+ moment = *unsmob_moment (beat);
+ }
+
+ /* second guess: property generic time exception */
+ SCM m = gh_assoc (gh_append3 (function, wild, time), settings);
+
+ if (m != SCM_BOOL_F && unsmob_moment (ly_cdr (m)))
+ moment = * unsmob_moment (ly_cdr (m));
+
+ /* third guess: property time exception, specific for duration type */
+ m = gh_assoc (gh_append3 (function, type, time), settings);
+ if (m != SCM_BOOL_F && unsmob_moment (ly_cdr (m)))
+ moment = * unsmob_moment (ly_cdr (m));
+
+ /* fourth guess [user override]: property plain generic */
+ m = gh_assoc (gh_append3 (function, wild, wild), settings);
+ if (m != SCM_BOOL_F && unsmob_moment (ly_cdr (m)))
+ moment = * unsmob_moment (ly_cdr (m));
+
+ /* fifth guess [user override]: property plain, specific for duration type */
+ m = gh_assoc (gh_append3 (function, type, wild), settings);
+ if (m != SCM_BOOL_F && unsmob_moment (ly_cdr (m)))
+ moment = * unsmob_moment (ly_cdr (m));
+
+ Rational r;
+ if (moment.to_bool ())
+ {
+ /* Ugh? measurePosition can be negative, when \partial
+ We may have to fix this elsewhere (timing translator)
+ r = unsmob_moment (get_property ("measurePosition"))->mod_rat (moment);
+ */
+ Moment pos = * unsmob_moment (get_property ("measurePosition"));
+ if (pos < Moment (0))
+ {
+ Moment length = * unsmob_moment (get_property ("measureLength"));
+ pos = length - pos;
+ }
+ r = pos.main_part_.mod_rat (moment.main_part_);
+ }
+ else
+ {
+ if (dir == START)
+ /* if undefined, starting is ok */
+ r = 0;
+ else
+ /* but ending is not */
+ r = 1;
+ }
+
+ return !r;