+MAKE_SCHEME_CALLBACK (Multi_measure_rest, height, 1);
+SCM
+Multi_measure_rest::height (SCM smob)
+{
+ Grob *me = unsmob<Grob> (smob);
+
+ Real space = 1000000; // something very large...
+
+ Stencil mol;
+ mol.add_stencil (symbol_stencil (me, space));
+
+ return ly_interval2scm (mol.extent (Y_AXIS));
+}
+
+int
+calc_closest_duration_log (Grob *me, double duration, bool force_round_up)
+{
+ bool round_up = force_round_up
+ || to_boolean (me->get_property ("round-up-to-longer-rest"));
+ int closest_usable_duration_log;
+
+ // Out of range initial values.
+ if (round_up)
+ closest_usable_duration_log = -15; // high value
+ else
+ closest_usable_duration_log = 15; // low value
+ int minimum_usable_duration_log = -15;
+ int maximum_usable_duration_log = 15;
+
+ SCM duration_logs_list = me->get_property ("usable-duration-logs");
+ if (to_boolean (scm_null_p (duration_logs_list))
+ || !to_boolean (scm_list_p (duration_logs_list)))
+ {
+ warning (_ ("usable-duration-logs must be a non-empty list."
+ " Falling back to whole rests."));
+ closest_usable_duration_log = 0;
+ }
+ else
+ {
+ for (SCM s = duration_logs_list; scm_is_pair (s); s = scm_cdr (s))
+ {
+ int dur_log = scm_to_int (scm_car (s));
+ if (dur_log > minimum_usable_duration_log)
+ minimum_usable_duration_log = dur_log;
+ if (dur_log < maximum_usable_duration_log)
+ maximum_usable_duration_log = dur_log;
+ double dur = pow (2.0, -dur_log);
+ if (round_up)
+ {
+ if (duration <= dur && dur_log > closest_usable_duration_log)
+ closest_usable_duration_log = dur_log;
+ }
+ else
+ {
+ if (duration >= dur && dur_log < closest_usable_duration_log)
+ closest_usable_duration_log = dur_log;
+ }
+ }
+ }
+
+ if (closest_usable_duration_log == 15)
+ closest_usable_duration_log = minimum_usable_duration_log;
+ if (closest_usable_duration_log == -15)
+ closest_usable_duration_log = maximum_usable_duration_log;
+
+ return closest_usable_duration_log;
+}
+
+int
+calc_measure_duration_log (Grob *me)
+{
+ SCM sml = dynamic_cast<Spanner *> (me)->get_bound (LEFT)
+ ->get_property ("measure-length");
+ Rational ml = (unsmob<Moment> (sml)) ? unsmob<Moment> (sml)->main_part_
+ : Rational (1);
+ double measure_duration = ml.Rational::to_double ();
+ bool force_round_up = to_boolean (scm_list_p (scm_member (scm_cons (scm_from_int64 (ml.numerator ()),
+ scm_from_int64 (ml.denominator ())),
+ me->get_property ("round-up-exceptions"))));
+ return calc_closest_duration_log (me, measure_duration, force_round_up);
+}
+