+ programming_error ("Beam dir not set.");
+ beam_dir = UP;
+ }
+
+
+ Real staff_space = Staff_symbol_referencer::staff_space (me);
+ Real half_space = staff_space / 2;
+ int multiplicity = Beam::get_multiplicity (beam);
+
+
+ SCM space_proc = beam->get_grob_property ("space-function");
+ SCM space = gh_call1 (space_proc, gh_int2scm (multiplicity));
+ Real interbeam_f = gh_scm2double (space) * staff_space;
+
+ Real thick = gh_scm2double (beam->get_grob_property ("thickness"));
+ Stem_info info;
+ info.idealy_f_ = chord_start_f (me);
+
+ // for simplicity, we calculate as if dir == UP
+ info.idealy_f_ *= beam_dir;
+ SCM grace_prop = me->get_grob_property ("grace");
+
+ bool grace_b = to_boolean (grace_prop);
+
+ Array<Real> a;
+ SCM s;
+
+ s = me->get_grob_property ("beamed-minimum-lengths");
+ a.clear ();
+ for (SCM q = s; q != SCM_EOL; q = gh_cdr (q))
+ a.push (gh_scm2double (gh_car (q)));
+
+
+ Real minimum_length = a[multiplicity <? (a.size () - 1)] * staff_space;
+ s = me->get_grob_property ("beamed-lengths");
+
+ a.clear ();
+ for (SCM q = s; q != SCM_EOL; q = gh_cdr (q))
+ a.push (gh_scm2double (gh_car (q)));
+
+ Real stem_length = a[multiplicity <? (a.size () - 1)] * staff_space;
+
+ if (!beam_dir || (beam_dir == Directional_element_interface::get (me)))
+ /* normal beamed stem */
+ {
+ if (multiplicity)
+ {
+ info.idealy_f_ += thick + (multiplicity - 1) * interbeam_f;
+ }
+ info.miny_f_ = info.idealy_f_;
+ info.maxy_f_ = INT_MAX;
+
+ info.idealy_f_ += stem_length;
+ info.miny_f_ += minimum_length;
+
+ /*
+ lowest beam of (UP) beam must never be lower than second staffline
+
+ Hmm, reference (Wanske?)
+
+ Although this (additional) rule is probably correct,
+ I expect that highest beam (UP) should also never be lower
+ than middle staffline, just as normal stems.
+
+ */
+ bool no_extend_b = to_boolean (me->get_grob_property ("no-stem-extend"));
+ if (!grace_b && !no_extend_b)
+ {
+ /* highest beam of (UP) beam must never be lower than middle
+ staffline
+ lowest beam of (UP) beam must never be lower than second staffline
+ */
+ info.miny_f_ =
+ info.miny_f_ >? 0
+ >? (- 2 * half_space - thick
+ + (multiplicity > 0) * thick
+ + interbeam_f * (multiplicity - 1));
+ }