X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fslur-configuration.cc;h=b144b2656ff927aeb5a51f506e631b98cf441499;hb=bfc7fdae57842d561568d1516337ce60e9aa8be0;hp=99577018129afd9dc8187864675e252e50fb6fcb;hpb=5edacf4c1908d0fe988d0ef9b3d6a9820a1e8734;p=lilypond.git diff --git a/lily/slur-configuration.cc b/lily/slur-configuration.cc index 9957701812..b144b2656f 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--2011 Han-Wen Nienhuys + Copyright (C) 2004--2012 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 @@ -28,6 +28,7 @@ #include "spanner.hh" #include "staff-symbol-referencer.hh" #include "stem.hh" +#include "tie.hh" #include "warn.hh" Bezier @@ -49,19 +50,15 @@ avoid_staff_line (Slur_score_state const &state, Real p = 2 * (y - staff->relative_coordinate (state.common_[Y_AXIS], Y_AXIS)) / 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)) + 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))) { - Direction resolution_dir - = (distance ? state.dir_ : Direction (sign (p - my_round (p)))); + Direction resolution_dir = frac ? state.dir_ : CENTER; // TODO: parameter - Real newp = my_round (p) + resolution_dir - * 5 * state.thickness_; + Real newp = round + resolution_dir * 5 * state.thickness_; Real dy = (newp - p) * state.staff_space_ / 2.0; @@ -93,10 +90,8 @@ fit_factor (Offset dz_unit, Offset dz_perp, Real close_to_edge_length, d * dot_product (z, dz_perp)); bool close_to_edge = false; - Direction d = LEFT; - do + for (LEFT_and_RIGHT (d)) close_to_edge = close_to_edge || -d * (p[X_AXIS] - curve_xext[d]) < close_to_edge_length; - while (flip (&d) != LEFT); if (close_to_edge) continue; @@ -196,7 +191,7 @@ Slur_configuration::add_score (Real s, string desc) { if (s < 0) { - programming_error ("Negative demerits found for slur. Ignoring"); + programming_error ("Negative demerits found for slur. Ignoring"); s = 0.0; } @@ -277,26 +272,15 @@ Slur_configuration::score_encompass (Slur_score_state const &state) demerit += stem_dem; } - else if (!edge) - { - Interval ext; - ext.add_point (state.encompass_infos_[j].stem_); - ext.add_point (state.encompass_infos_[j].head_); - - // ? - demerit += -state.parameters_.closeness_factor_ - * min (state.dir_ - * (y - (ext[state.dir_] + state.dir_ * state.parameters_.free_head_distance_)), 0.0) - / state.encompass_infos_.size (); - } } add_score (demerit, "encompass"); - if (convex_head_distances.size ()) + if (vsize n = convex_head_distances.size ()) { Real avg_distance = 0.0; Real min_dist = infinity_f; - for (vsize j = 0; j < convex_head_distances.size (); j++) + + for (vsize j = 0; j < n; j++) { min_dist = min (min_dist, convex_head_distances[j]); avg_distance += convex_head_distances[j]; @@ -306,12 +290,11 @@ Slur_configuration::score_encompass (Slur_score_state const &state) For slurs over 3 or 4 heads, the average distance is not a good normalizer. */ - Real n = convex_head_distances.size (); if (n <= 2) { Real fact = 1.0; avg_distance += height_ * fact; - n += fact; + ++n; } /* @@ -334,6 +317,39 @@ Slur_configuration::score_encompass (Slur_score_state const &state) void 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_)) + { + Grob *t = state.extra_encompass_infos_[i].grob_; + Grob *common_x = Grob::get_vertical_axis_group (t); + Real rp = t->relative_coordinate (common_x, X_AXIS); + SCM cp = t->get_property ("control-points"); + + Bezier b; + int j = 0; + for (SCM s = cp; scm_is_pair (s); s = scm_cdr (s)) + { + b.control_[j] = ly_scm2offset (scm_car (s)); + j++; + } + forbidden_attachments.push_back (Offset (b.control_[0]) + Offset (rp, 0)); + forbidden_attachments.push_back (Offset (b.control_[3]) + Offset (rp, 0)); + } + + bool too_close = false; + for (vsize k = 0; k < forbidden_attachments.size (); k++) + for (LEFT_and_RIGHT (side)) + if ((forbidden_attachments[k] - attachment_[side]).length () < state.parameters_.slur_tie_extrema_min_distance_) + { + too_close = true; + break; + } + + if (too_close) + add_score (state.parameters_.slur_tie_extrema_min_distance_penalty_, "extra"); + for (vsize j = 0; j < state.extra_encompass_infos_.size (); j++) { Drul_array attachment = attachment_; @@ -345,11 +361,11 @@ Slur_configuration::score_extra_encompass (Slur_score_state const &state) to prevent numerical inaccuracies in Bezier::get_other_coordinate (). */ - Direction d = LEFT; + bool found = false; Real y = 0.0; - do + for (LEFT_and_RIGHT (d)) { /* We need to check for the bound explicitly, since the @@ -370,7 +386,6 @@ Slur_configuration::score_extra_encompass (Slur_score_state const &state) } } - while (flip (&d) != LEFT); if (!found) { @@ -408,11 +423,11 @@ Slur_configuration::score_extra_encompass (Slur_score_state const &state) void Slur_configuration::score_edges (Slur_score_state const &state) { - Direction d = LEFT; + Offset dz = attachment_[RIGHT] - attachment_[LEFT]; Real slope = dz[Y_AXIS] / dz[X_AXIS]; - do + for (LEFT_and_RIGHT (d)) { Real y = attachment_[d][Y_AXIS]; Real dy = fabs (y - state.base_attachments_[d][Y_AXIS]); @@ -431,7 +446,6 @@ Slur_configuration::score_edges (Slur_score_state const &state) string dir_str = d == LEFT ? "L" : "R"; add_score (demerit, dir_str + " edge"); } - while (flip (&d) != LEFT); } void