X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fhairpin.cc;h=399b5d995e8876f37aec2622a947435bcdc35507;hb=3ef09ea5cf542f2443113e4004b0e3928f319567;hp=60366a0630fa7ee51dab702fe2444b6df12cb1f1;hpb=9d9e2e5637e06d98245c3395b58207ec173e7e7d;p=lilypond.git diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 60366a0630..399b5d995e 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -1,9 +1,20 @@ /* - hairpin.cc -- implement Hairpin + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 1997--2011 Han-Wen Nienhuys - (c) 1997--2007 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 + 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 "hairpin.hh" @@ -20,48 +31,27 @@ #include "note-column.hh" #include "warn.hh" -MAKE_SCHEME_CALLBACK (Hairpin, after_line_breaking, 1); +MAKE_SCHEME_CALLBACK (Hairpin, pure_height, 3); SCM -Hairpin::after_line_breaking (SCM smob) +Hairpin::pure_height (SCM smob, SCM, SCM) { - Spanner *me = dynamic_cast (unsmob_grob (smob)); - consider_suicide (me); + Grob *me = unsmob_grob (smob); + Real height = robust_scm2double (me->get_property ("height"), 0.0) + * Staff_symbol_referencer::staff_space (me); - return SCM_UNSPECIFIED; -} + Real thickness = robust_scm2double (me->get_property ("thickness"), 1) + * Staff_symbol_referencer::line_thickness (me); -void -Hairpin::consider_suicide (Spanner*me) -{ - Drul_array broken; - Drul_array bounds; - Direction d = LEFT; - do - { - bounds[d] = me->get_bound (d); - broken[d] = bounds[d]->break_status_dir () != CENTER; - } - while (flip (&d) != LEFT); - - if (broken[LEFT] - && ly_is_equal (bounds[RIGHT]->get_column ()->get_property ("when"), - bounds[LEFT]->get_property ("when"))) - me->suicide (); + height += thickness / 2; + return ly_interval2scm (Interval (-height, height)); } MAKE_SCHEME_CALLBACK (Hairpin, print, 1); - SCM Hairpin::print (SCM smob) { - Spanner *me = dynamic_cast (unsmob_grob (smob)); + Spanner *me = unsmob_spanner (smob); - if (Spanner *orig = dynamic_cast (me->original ())) - { - for (vsize i = 0; i < orig->broken_intos_.size (); i++) - Hairpin::consider_suicide (orig->broken_intos_[i]); - } - SCM s = me->get_property ("grow-direction"); if (!is_direction (s)) { @@ -84,7 +74,7 @@ Hairpin::print (SCM smob) broken[RIGHT] = broken[RIGHT] && me->broken_neighbor (RIGHT); broken[RIGHT] = broken[RIGHT] && me->broken_neighbor (RIGHT)->is_live (); - + if (broken[RIGHT]) { Spanner *next = me->broken_neighbor (RIGHT); @@ -100,8 +90,8 @@ Hairpin::print (SCM smob) Use the height and thickness of the hairpin when making a circled tip */ bool circled_tip = ly_scm2bool (me->get_property ("circled-tip")); - Real height = robust_scm2double (me->get_property ("height"), 0.2) * - Staff_symbol_referencer::staff_space (me); + Real height = robust_scm2double (me->get_property ("height"), 0.2) + * Staff_symbol_referencer::staff_space (me); /* FIXME: 0.525 is still just a guess... */ @@ -109,7 +99,7 @@ Hairpin::print (SCM smob) Real thick = 1.0; if (circled_tip) thick = robust_scm2double (me->get_property ("thickness"), 1.0) - * Staff_symbol_referencer::line_thickness (me); + * Staff_symbol_referencer::line_thickness (me); do { @@ -131,37 +121,47 @@ Hairpin::print (SCM smob) else { bool neighbor_found = false; - extract_grob_set (me, "adjacent-hairpins", pins); - for (vsize i = 0; i < pins.size (); i++) + Spanner *adjacent; + extract_grob_set (me, "adjacent-spanners", neighbors); + for (vsize i = 0; i < neighbors.size (); i++) { /* FIXME: this will fuck up in case of polyphonic notes in other voices. Need to look at note-columns in the current staff/voice. */ - - Spanner *pin = dynamic_cast (pins[i]); - if (pin - && (pin->get_bound (LEFT)->get_column () == b->get_column () - || pin->get_bound (RIGHT)->get_column () == b->get_column ())) - neighbor_found = true; + adjacent = dynamic_cast (neighbors[i]); + if (adjacent + && (adjacent->get_bound (-d)->get_column () + == b->get_column ())) + { + neighbor_found = true; + break; + } } Interval e = robust_relative_extent (b, common, X_AXIS); if (neighbor_found) { - /* - Handle back-to-back hairpins with a circle in the middle - */ - if (circled_tip && (grow_dir != d)) - x_points[d] = e.center () + d * (rad - thick / 2.0); - /* - If we're hung on a paper column, that means we're not - adjacent to a text-dynamic, and we may move closer. We - make the padding a little smaller, here. - */ + if (Hairpin::has_interface (adjacent)) + { + /* + Handle back-to-back hairpins with a circle in the middle + */ + if (circled_tip && (grow_dir != d)) + x_points[d] = e.center () + d * (rad - thick / 2.0); + /* + If we're hung on a paper column, that means we're not + adjacent to a text-dynamic, and we may move closer. We + make the padding a little smaller, here. + */ + else + x_points[d] = e.center () - d * padding / 3; + } + // Our neighbor is a dynamic text spanner, so add the + // same amount of padding as for text dynamics else - x_points[d] = e.center () - d * padding / 3; + x_points[d] = e[-d] - d * padding; } else { @@ -170,10 +170,10 @@ Hairpin::print (SCM smob) x_points[d] = e[-d]; else x_points[d] = e[d]; - + Item *bound = me->get_bound (d); if (bound->is_non_musical (bound)) - x_points[d] -= d * padding; + x_points[d] -= d * padding; } } } @@ -232,16 +232,16 @@ Hairpin::print (SCM smob) if (circled_tip) { Box extent (Interval (-rad, rad), Interval (-rad, rad)); - + /* Hmmm, perhaps we should have a Lookup::circle () method? */ Stencil circle (extent, - scm_list_4 (ly_symbol2scm ("circle"), - scm_from_double (rad), - scm_from_double (thick), - SCM_BOOL_F)); + scm_list_4 (ly_symbol2scm ("circle"), + scm_from_double (rad), + scm_from_double (thick), + SCM_BOOL_F)); /* - don't add another circle the hairpin is broken + don't add another circle if the hairpin is broken */ if (!broken[tip_dir]) mol.add_at_edge (X_AXIS, tip_dir, Stencil (circle), 0); @@ -257,7 +257,7 @@ ADD_INTERFACE (Hairpin, "A hairpin crescendo or decrescendo.", /* properties */ - "adjacent-hairpins " + "adjacent-spanners " "circled-tip " "bound-padding " "grow-direction "