X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fslur-configuration.cc;h=4bd0c7113959f92d21e29c19bf0e5f7b103c6356;hb=cfc908430e67711a28a33097aaea491f7c127a72;hp=02df6fe35ff6ea22ef40430162287fc69945f0d0;hpb=89b7e75f6888d2020f7fe8b258e818c0c5e7a223;p=lilypond.git diff --git a/lily/slur-configuration.cc b/lily/slur-configuration.cc index 02df6fe35f..4bd0c71139 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 @@ -31,6 +31,9 @@ #include "tie.hh" #include "warn.hh" +using std::string; +using std::vector; + Bezier avoid_staff_line (Slur_score_state const &state, Bezier bez) @@ -43,27 +46,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; - - // TODO: parameter - Real newp = round + resolution_dir * 5 * state.thickness_; + Direction resolution_dir = (distance > 0.0) ? UP : DOWN; - 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; @@ -105,7 +122,7 @@ fit_factor (Offset dz_unit, Offset dz_perp, Real close_to_edge_length, Real y = curve.get_other_coordinate (X_AXIS, p[X_AXIS]); if (y) - fit_factor = max (fit_factor, (p[Y_AXIS] / y)); + fit_factor = std::max (fit_factor, (p[Y_AXIS] / y)); } return fit_factor; } @@ -137,7 +154,7 @@ Slur_configuration::generate_curve (Slur_score_state const &state, (control3 - control0). */ Real max_indent = len / 3.1; - indent = min (indent, max_indent); + indent = std::min (indent, max_indent); Real a1 = sqr (len) / 3.0; Real a2 = 0.75 * sqr (indent + len / 3.0); @@ -167,7 +184,7 @@ Slur_configuration::generate_curve (Slur_score_state const &state, Real ff = fit_factor (dz_unit, dz_perp, state.parameters_.close_to_edge_length_, curve, state.dir_, avoid); - height = max (height, min (height * ff, max_h)); + height = std::max (height, std::min (height * ff, max_h)); curve.control_[0] = attachment_[LEFT]; curve.control_[1] = attachment_[LEFT] + dz_perp * height * state.dir_ @@ -187,7 +204,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) { @@ -241,7 +258,7 @@ Slur_configuration::score_encompass (Slur_score_state const &state) Real hd = (head_dy) ? (1 / fabs (head_dy) - 1 / state.parameters_.free_head_distance_) : state.parameters_.head_encompass_penalty_; - hd = min (max (hd, 0.0), state.parameters_.head_encompass_penalty_); + hd = std::min (std::max (hd, 0.0), state.parameters_.head_encompass_penalty_); demerit += hd; } @@ -256,7 +273,7 @@ Slur_configuration::score_encompass (Slur_score_state const &state) { Real closest - = state.dir_ * max (state.dir_ * state.encompass_infos_[j].get_point (state.dir_), state.dir_ * line_y); + = state.dir_ * std::max (state.dir_ * state.encompass_infos_[j].get_point (state.dir_), state.dir_ * line_y); Real d = fabs (closest - y); convex_head_distances.push_back (d); @@ -282,7 +299,7 @@ Slur_configuration::score_encompass (Slur_score_state const &state) for (vsize j = 0; j < n; j++) { - min_dist = min (min_dist, convex_head_distances[j]); + min_dist = std::min (min_dist, convex_head_distances[j]); avg_distance += convex_head_distances[j]; } @@ -305,9 +322,9 @@ Slur_configuration::score_encompass (Slur_score_state const &state) Real variance_penalty = state.parameters_.head_slur_distance_max_ratio_; if (min_dist > 0.0) variance_penalty - = min ((avg_distance / (min_dist + state.parameters_.absolute_closeness_measure_) - 1.0), variance_penalty); + = std::min ((avg_distance / (min_dist + state.parameters_.absolute_closeness_measure_) - 1.0), variance_penalty); - variance_penalty = max (variance_penalty, 0.0); + variance_penalty = std::max (variance_penalty, 0.0); variance_penalty *= state.parameters_.head_slur_distance_factor_; add_score (variance_penalty, "variance"); @@ -320,7 +337,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,19 +415,19 @@ 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"); - dist = max (dist, 0.0); + dist = std::max (dist, 0.0); Real penalty = info.penalty_ * peak_around (0.1 * state.parameters_.extra_encompass_free_distance_, state.parameters_.extra_encompass_free_distance_, @@ -456,7 +473,7 @@ Slur_configuration::score_slopes (Slur_score_state const &state) Real slur_dy = slur_dz[Y_AXIS]; Real demerit = 0.0; - demerit += max ((fabs (slur_dy / slur_dz[X_AXIS]) + demerit += std::max ((fabs (slur_dy / slur_dz[X_AXIS]) - state.parameters_.max_slope_), 0.0) * state.parameters_.max_slope_factor_; @@ -467,9 +484,9 @@ Slur_configuration::score_slopes (Slur_score_state const &state) if (!state.is_broken_) demerit += state.parameters_.steeper_slope_factor_ - * (max (fabs (slur_dy) - max_dy, 0.0)); + * (std::max (fabs (slur_dy) - max_dy, 0.0)); - demerit += max ((fabs (slur_dy / slur_dz[X_AXIS]) + demerit += std::max ((fabs (slur_dy / slur_dz[X_AXIS]) - state.parameters_.max_slope_), 0.0) * state.parameters_.max_slope_factor_;