- else
- {
- /*
- Beams should intersect one beamthickness below stem end
- */
- Real dy = stem->stem_end_position () * ss / 2;
- dy -= mol.extent (Y_AXIS).length () / 2 * stem->get_direction ();
-
- /*
- uhg. Should use relative coords and placement
- */
- Real whole_note_correction;
- if (stem->invisible_b ())
- whole_note_correction = -stem->get_direction ()
- * stem->support_head ()->extent (X_AXIS).length () / 2;
- else
- whole_note_correction = 0;
-
- mol.translate (Offset (stem->relative_coordinate (0, X_AXIS) - relative_coordinate (0, X_AXIS) +
- whole_note_correction, dy));
+
+ Spanner *beam = Stem::get_beam (stem);
+ Direction stemdir = get_grob_direction (stem);
+ if (stemdir == 0)
+ stemdir = UP;
+
+ bool whole_note = Stem::duration_log (stem) <= 0;
+
+ Real beam_translation = get_beam_translation (me);
+
+ /* for a whole note, we position relative to the notehead, so we want the
+ stencil aligned on the flag closest to the head */
+ Direction stencil_dir = whole_note ? -stemdir : stemdir;
+ Stencil mol = raw_stencil (me, slope, stencil_dir);
+
+ Interval mol_ext = mol.extent (Y_AXIS);
+ Real ss = Staff_symbol_referencer::staff_space (me);
+
+ // ugh, rather calc from Stem_tremolo_req
+ int beam_count = beam ? (Stem::beam_multiplicity (stem).length () + 1) : 0;
+
+ Real beamthickness = 0.0;
+ SCM sbt = (beam) ? beam->get_property ("thickness") : SCM_EOL;
+ if (scm_is_number (sbt))
+ beamthickness = scm_to_double (sbt) * ss;
+
+ Real end_y
+ = Stem::stem_end_position (stem) * ss / 2
+ - stemdir * max (beam_count, 1) * beam_translation;
+
+ if (!beam && Stem::duration_log (stem) >= 3)
+ {
+ end_y -= stemdir * (Stem::duration_log (stem) - 2) * beam_translation;
+ if (stemdir == UP)
+ end_y -= stemdir * beam_translation * 0.5;