- first = current;
-
- get_set_column (current, first->get_column ());
-
- if (i > 0)
- current->translate_axis (distance, X_AXIS);
-
- distance
- += scm_to_double (current->get_property ("head-width"))
- - scm_to_double (current->get_property ("thickness"));
+ {
+ first = current;
+ staff_space = Staff_symbol_referencer::staff_space (first);
+ thickness = scm_to_double (current->get_property ("thickness"));
+ }
+
+ move_related_items_to_column (current, first->get_column (),
+ distance);
+
+ Real head_width = scm_to_double (current->get_property ("head-width"));
+ distance += head_width - thickness;
+
+ if (size_t const dot_count = Rhythmic_head::dot_count (current))
+ /*
+ Move dots above/behind the ligature.
+ dots should also avoid staff lines.
+ */
+ {
+ Grob *dot_gr = Rhythmic_head::get_dots (current);
+
+ bool const on_line = Staff_symbol_referencer::on_line
+ (current,
+ robust_scm2int (current->get_property ("staff-position"), 0));
+ Real vert_shift = on_line ? staff_space * 0.5 : 0.0;
+ bool const flexa_begin
+ = scm_to_int (current->get_property ("primitive"))
+ & MLP_FLEXA_BEGIN;
+
+ if (i + 1 < primitives.size ())
+ /*
+ dot in the midst => avoid next note;
+ what to avoid and where depends on
+ being on a line or between lines
+ */
+ {
+ int const delta
+ = scm_to_int (current->get_property ("delta-position"));
+ if (flexa_begin)
+ vert_shift += delta < 0
+ ? staff_space : (on_line ? -2.0 : -1.0) * staff_space;
+ else if (on_line)
+ {
+ if (0 < delta && delta < 3)
+ vert_shift -= staff_space;
+ }
+ else if (delta == 1 || delta == -1)
+ vert_shift -= delta * staff_space;
+ }
+ else
+ min_length += head_width * dot_count;
+
+ dot_gr->translate_axis (vert_shift, Y_AXIS);
+
+ /*
+ move all dots behind head
+ */
+ dot_gr->translate_axis
+ ((flexa_begin ? staff_space * 0.6 : head_width) - 2.0 * thickness, X_AXIS);
+ }