X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fslur.cc;h=6ee169c079582cffddf768459d83197934b37206;hb=f530eeb5bbaf470235e17161a3a4605ecdcfb8dd;hp=3d47e876fc07ce0c18d21803f0ce2840f3f52ae5;hpb=ac6c83f047635535d0481a15654c13e776334dc6;p=lilypond.git diff --git a/lily/slur.cc b/lily/slur.cc index 3d47e876fc..6ee169c079 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -1,10 +1,21 @@ /* - slur.cc -- implement external interface for Slur + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter - - (c) 1996--2007 Han-Wen Nienhuys + Copyright (C) 1996--2010 Han-Wen Nienhuys Jan Nieuwenhuizen + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "slur.hh" @@ -82,7 +93,10 @@ Slur::pure_height (SCM smob, SCM start_scm, SCM end_scm) ret.unite (d); } - ret.widen (height * 0.5); + // The +0.5 comes from the fact that we try to place a slur + // 0.5 staff spaces from the note-head. + // (see Slur_score_state.get_base_attachments ()) + ret.widen (height * 0.5 + 0.5); return ly_interval2scm (ret); } @@ -119,15 +133,11 @@ Slur::print (SCM smob) Bezier one = get_curve (me); Stencil a; - SCM p = me->get_property ("dash-period"); - SCM f = me->get_property ("dash-fraction"); - if (scm_is_number (p) && scm_is_number (f)) - a = Lookup::dashed_slur (one, line_thick, robust_scm2double (p, 1.0), - robust_scm2double (f, 0)); - else - a = Lookup::slur (one, - get_grob_direction (me) * base_thick, - line_thick); + SCM dash_definition = me->get_property ("dash-definition"); + a = Lookup::slur (one, + get_grob_direction (me) * base_thick, + line_thick, + dash_definition); #if DEBUG_SLUR_SCORING SCM annotation = me->get_property ("annotation"); @@ -160,7 +170,7 @@ Slur::print (SCM smob) /* it would be better to do this at engraver level, but that is - fragile, as the breakabl items are generated on staff level, at + fragile, as the breakable items are generated on staff level, at which point slur starts and ends have to be tracked */ void @@ -279,9 +289,9 @@ Slur::outside_slur_callback (SCM grob, SCM offset_scm) 0.0); yext.widen (slur_padding); - Real EPS = 1e-3; + const Real EPS = 1e-3; Interval bezext (curve.control_[0][X_AXIS], curve.control_[3][X_AXIS]); - bool consider[] = { false, false, false }; + bool consider[] = {false, false, false}; Real ys[] = {0, 0, 0}; bool do_shift = false; @@ -308,11 +318,13 @@ Slur::outside_slur_callback (SCM grob, SCM offset_scm) } Real avoidance_offset = 0.0; - for (int d = LEFT, k = 0; d <= RIGHT; d++, k++) - if (consider[k]) - avoidance_offset = dir * (max (dir * avoidance_offset, - dir * (ys[k] - yext[-dir] + dir * slur_padding))); - + if (do_shift) + { + for (int d = LEFT, k = 0; d <= RIGHT; d++, k++) + if (consider[k]) + avoidance_offset = dir * (max (dir * avoidance_offset, + dir * (ys[k] - yext[-dir] + dir * slur_padding))); + } return scm_from_double (offset + avoidance_offset); } @@ -349,14 +361,36 @@ Slur::auxiliary_acknowledge_extra_object (Grob_info const &info, if (slur) { chain_offset_callback (e, outside_slur_callback_proc, Y_AXIS); + chain_callback (e, outside_slur_cross_staff_proc, ly_symbol2scm("cross-staff")); e->set_object ("slur", slur->self_scm ()); } } - else + else if (avoid != ly_symbol2scm ("ignore")) e->warning (_f ("Ignoring grob for slur: %s. avoid-slur not set?", e->name().c_str ())); } +/* + A callback that will be chained together with the original cross-staff + value of a grob that is placed 'outside or 'around a slur. This just says + that any grob becomes cross-staff if it is placed 'outside or 'around a + cross-staff slur. +*/ +MAKE_SCHEME_CALLBACK (Slur, outside_slur_cross_staff, 2) +SCM +Slur::outside_slur_cross_staff (SCM smob, SCM previous) +{ + if (previous == SCM_BOOL_T) + return previous; + + Grob *me = unsmob_grob (smob); + Grob *slur = unsmob_grob (me->get_object ("slur")); + + if (!slur) + return SCM_BOOL_F; + return slur->get_property ("cross-staff"); +} + MAKE_SCHEME_CALLBACK (Slur, calc_cross_staff, 1) SCM Slur::calc_cross_staff (SCM smob) @@ -387,14 +421,79 @@ Slur::calc_cross_staff (SCM smob) } ADD_INTERFACE (Slur, - "A slur.", + "A slur." + "\n" + "The following properties may be set in the @code{details}" + " list.\n" + "\n" + "@table @code\n" + "@item region-size\n" + "Size of region (in staff spaces) for determining" + " potential endpoints in the Y direction.\n" + "@item head-encompass-penalty\n" + "Demerit to apply when note heads collide with a slur.\n" + "@item stem-encompass-penalty\n" + "Demerit to apply when stems collide with a slur.\n" + "@item closeness-factor\n" + "Additional demerit used when scoring encompasses.\n" + "@item edge-attraction-factor\n" + "Factor used to calculate the demerit for distances" + " between slur endpoints and their corresponding base" + " attachments.\n" + "@item same-slope-penalty\n" + "Demerit for slurs with attachment points that are" + " horizontally aligned.\n" + "@item steeper-slope-factor\n" + "Factor used to calculate demerit only if this slur is" + " not broken.\n" + "@item non-horizontal-penalty\n" + "Demerit for slurs with attachment points that are not" + " horizontally aligned.\n" + "@item max-slope\n" + "The maximum slope allowed for this slur.\n" + "@item max-slope-factor\n" + "Factor that calculates demerit based on the max slope.\n" + "@item free-head-distance\n" + "The amount of vertical free space that must exist" + " between a slur and note heads.\n" + "@item absolute-closeness-measure\n" + "Factor to calculate demerit for variance between a note" + " head and slur.\n" + "@item extra-object-collision-penalty\n" + "Factor to calculate demerit for extra objects that the" + " slur encompasses, including accidentals, fingerings, and" + " tuplet numbers.\n" + "@item accidental-collision\n" + "Factor to calculate demerit for @code{Accidental} objects" + " that the slur encompasses. This property value replaces" + " the value of @code{extra-object-collision-penalty}.\n" + "@item extra-encompass-free-distance\n" + "The amount of vertical free space that must exist" + " between a slur and various objects it encompasses," + " including accidentals, fingerings, and tuplet numbers.\n" + "@item extra-encompass-collision-distance\n" + "This detail is currently unused.\n" + "@item head-slur-distance-factor\n" + "Factor to calculate demerit for variance between a note" + " head and slur.\n" + "@item head-slur-distance-max-ratio\n" + "The maximum value for the ratio of distance between a" + " note head and slur.\n" + "@item free-slur-distance\n" + "The amount of vertical free space that must exist" + " between adjacent slurs. This subproperty only works" + " for @code{PhrasingSlur}.\n" + "@item edge-slope-exponent\n" + "Factor used to calculate the demerit for the slope of" + " a slur near its endpoints; a larger value yields a" + " larger demerit.\n" + "@end table\n", /* properties */ "annotation " "avoid-slur " /* UGH. */ "control-points " - "dash-fraction " - "dash-period " + "dash-definition " "details " "direction " "eccentricity "