+ Real ss = Staff_symbol_referencer::staff_space (me);
+ Real length = 7;
+ SCM s = scm_cdr (scm_assq (ly_symbol2scm ("lengths"), details));
+ if (scm_is_pair (s))
+ length = 2 * scm_to_double (robust_list_ref (durlog - 2, s));
+
+ Direction dir = get_grob_direction (me);
+
+ /* Stems in unnatural (forced) direction should be shortened,
+ according to [Roush & Gourlay] */
+ Interval hp = head_positions (me);
+ if (dir && dir * hp[dir] >= 0)
+ {
+ SCM sshorten = scm_cdr (scm_assq (ly_symbol2scm ("stem-shorten"), details));
+ SCM scm_shorten = scm_is_pair (sshorten)
+ ? robust_list_ref (max (duration_log (me) - 2, 0), sshorten) : SCM_EOL;
+ Real shorten = 2* robust_scm2double (scm_shorten, 0);
+
+ /* On boundary: shorten only half */
+ if (abs (head_positions (me)[dir]) <= 1)
+ shorten *= 0.5;
+
+ length -= shorten;
+ }
+
+ length *= robust_scm2double (me->get_property ("length-fraction"), 1.0);
+
+ /* Tremolo stuff. */
+ Grob *t_flag = unsmob_grob (me->get_object ("tremolo-flag"));
+ if (t_flag && !unsmob_grob (me->get_object ("beam")))
+ {
+ /* Crude hack: add extra space if tremolo flag is there.
+
+ We can't do this for the beam, since we get into a loop
+ (Stem_tremolo::raw_stencil () looks at the beam.) --hwn */
+
+ Real minlen = 1.0
+ + 2 * Stem_tremolo::raw_stencil (t_flag).extent (Y_AXIS).length ()
+ / ss;
+
+ if (durlog >= 3)
+ {
+ Interval flag_ext = flag (me).extent (Y_AXIS);
+ if (!flag_ext.is_empty ())
+ minlen += 2 * flag_ext.length () / ss;
+
+ /* The clash is smaller for down stems (since the tremolo is
+ angled up.) */
+ if (dir == DOWN)
+ minlen -= 1.0;
+ }
+ length = max (length, minlen + 1.0);
+ }