- / state.staff_space_;
-
- Real distance = fabs (my_round (p) - p); // in halfspaces
- if (distance < 4 * state.thickness_
- && (int) fabs (my_round (p))
- <= 2 * Staff_symbol_referencer::staff_radius (staff) + 0.1
- && (int (fabs (my_round (p))) % 2
- != Staff_symbol_referencer::line_count (staff) % 2))
- {
- Direction resolution_dir
- = (distance ? state.dir_ : Direction (sign (p - my_round (p))));
-
- // TODO: parameter
- Real newp = my_round (p) + resolution_dir
- * 5 * state.thickness_;
-
- Real dy = (newp - p) * state.staff_space_ / 2.0;
-
- bez.control_[1][Y_AXIS] += dy;
- bez.control_[2][Y_AXIS] += dy;
- }
+ / state.staff_space_;
+
+ int round_p = (int) my_round (p);
+ if (!Staff_symbol_referencer::on_staff_line (staff, round_p))
+ round_p += (p > round_p) ? 1 : -1;
+ if (!Staff_symbol_referencer::on_staff_line (staff, round_p))
+ return bez;
+
+ Real const distance = (p - round_p) * state.staff_space_ / 2.0;
+ // Allow half the thickness of the slur at the point t, plus one basic
+ // blot-diameter (half for the slur outline, half for the staff line)
+ Real const min_distance = 0.5 * state.thickness_ * factor
+ + state.line_thickness_
+ + ((state.dir_ * distance > 0.0)
+ ? state.parameters_.gap_to_staffline_inside_
+ : state.parameters_.gap_to_staffline_outside_);
+ if (fabs (distance) < min_distance)
+ {
+ Direction resolution_dir = (distance > 0.0) ? UP : DOWN;
+
+ Real dy = resolution_dir * (min_distance - fabs (distance));
+
+ // Shape the curve, moving the horizontal point by factor * dy
+ bez.control_[1][Y_AXIS] += dy;
+ bez.control_[2][Y_AXIS] += dy;
+ // Move the entire curve by the remaining amount
+ bez.translate (Offset (0.0, dy - factor * dy));
+ }