X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fslur-configuration.cc;h=9eb4ef83bd03c74581d9da08b5664c1a062c9c54;hb=97a0169312a260933246ab224e4f8b0969871dd5;hp=02df6fe35ff6ea22ef40430162287fc69945f0d0;hpb=89b7e75f6888d2020f7fe8b258e818c0c5e7a223;p=lilypond.git diff --git a/lily/slur-configuration.cc b/lily/slur-configuration.cc index 02df6fe35f..9eb4ef83bd 100644 --- a/lily/slur-configuration.cc +++ b/lily/slur-configuration.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 2004--2012 Han-Wen Nienhuys + Copyright (C) 2004--2015 Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,27 +43,41 @@ avoid_staff_line (Slur_score_state const &state, && (state.extremes_[LEFT].staff_ == state.extremes_[RIGHT].staff_) && state.extremes_[LEFT].staff_ && state.extremes_[RIGHT].staff_) { - Real y = bez.curve_point (ts[0])[Y_AXIS]; + Real t = ts[0]; //the first (usually only) point where slur is horizontal + Real y = bez.curve_point (t)[Y_AXIS]; + // A Bezier curve at t moves 3t-3t² as far as the middle control points + Real factor = 3.0 * t * (1.0 - t); Grob *staff = state.extremes_[LEFT].staff_; - Real p = 2 * (y - staff->maybe_pure_coordinate (state.common_[Y_AXIS], Y_AXIS, state.stub_, 0, INT_MAX)) + Real p = 2 * (y - staff->relative_coordinate (state.common_[Y_AXIS], Y_AXIS)) / state.staff_space_; - Real const round = my_round (p); - Real const frac = p - round; - if (fabs (frac) < 4 * state.thickness_ - && Staff_symbol_referencer::on_staff_line (staff, int (round))) + 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 = frac ? state.dir_ : CENTER; + Direction resolution_dir = (distance > 0.0) ? UP : DOWN; - // TODO: parameter - Real newp = round + resolution_dir * 5 * state.thickness_; - - Real dy = (newp - p) * state.staff_space_ / 2.0; + 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)); } } return bez; @@ -76,7 +90,7 @@ fit_factor (Offset dz_unit, Offset dz_perp, Real close_to_edge_length, Real fit_factor = 0.0; Offset x0 = curve.control_[0]; curve.translate (-x0); - curve.rotate (-dz_unit.arg ()); + curve.rotate (-dz_unit.angle_degrees ()); curve.scale (1, d); Interval curve_xext; @@ -187,7 +201,7 @@ Slur_configuration::Slur_configuration () }; void -Slur_configuration::add_score (Real s, string desc) +Slur_configuration::add_score (Real s, const string &desc) { if (s < 0) { @@ -320,7 +334,7 @@ Slur_configuration::score_extra_encompass (Slur_score_state const &state) // we find forbidden attachments vector forbidden_attachments; for (vsize i = 0; i < state.extra_encompass_infos_.size (); i++) - if (Tie::has_interface (state.extra_encompass_infos_[i].grob_)) + if (has_interface (state.extra_encompass_infos_[i].grob_)) { Grob *t = state.extra_encompass_infos_[i].grob_; Grob *common_x = Grob::get_vertical_axis_group (t); @@ -398,14 +412,14 @@ Slur_configuration::score_extra_encompass (Slur_score_state const &state) } Real dist = 0.0; - if (info.type_ == ly_symbol2scm ("around")) + if (scm_is_eq (info.type_, ly_symbol2scm ("around"))) dist = info.extents_[Y_AXIS].distance (y); /* Have to score too: the curve enumeration is limited in its shape, and may produce curves which collide anyway. */ - else if (info.type_ == ly_symbol2scm ("inside")) + else if (scm_is_eq (info.type_, ly_symbol2scm ("inside"))) dist = state.dir_ * (y - info.extents_[Y_AXIS][state.dir_]); else programming_error ("unknown avoidance type");