X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fhairpin.cc;h=9f5bb1a7e42edc2b620494b7d052d04a69746cd0;hb=9446d6a4f83a94754f584d2d973195fd800d1af6;hp=87f32017a491ca7b9d6a669bf8e25fa4c3c45c10;hpb=c3ff1c6cd20e15e9036ee7120012e05b1d62a46d;p=lilypond.git diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 87f32017a4..9f5bb1a7e4 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -1,13 +1,25 @@ /* - 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" +#include "axis-group-interface.hh" #include "dimensions.hh" #include "international.hh" #include "line-interface.hh" @@ -20,49 +32,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; -} - -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); + Real thickness = robust_scm2double (me->get_property ("thickness"), 1) + * Staff_symbol_referencer::line_thickness (me); - 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)) { @@ -85,13 +75,13 @@ 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); Stencil *s = next->get_stencil (); if (!s || s->is_empty ()) - broken[RIGHT] = false; + broken[RIGHT] = false; } Grob *common = bounds[LEFT]->common_refpoint (bounds[RIGHT], X_AXIS); @@ -101,8 +91,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... */ @@ -110,74 +100,86 @@ 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 { Item *b = bounds[d]; x_points[d] = b->relative_coordinate (common, X_AXIS); if (broken [d]) - { - if (d == LEFT) - x_points[d] = b->extent (common, X_AXIS)[RIGHT]; - } + { + if (d == LEFT) + x_points[d] = b->extent (common, X_AXIS)[RIGHT]; + } else - { - if (Text_interface::has_interface (b)) - { - Interval e = b->extent (common, X_AXIS); - if (!e.is_empty ()) - x_points[d] = e[-d] - d * padding; - } - else - { - bool neighbor_found = false; - extract_grob_set (me, "adjacent-hairpins", pins); - for (vsize i = 0; i < pins.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. - */ + { + if (Text_interface::has_interface (b)) + { + Interval e = b->extent (common, X_AXIS); + if (!e.is_empty ()) + x_points[d] = e[-d] - d * padding; + } + else + { + bool neighbor_found = false; + Spanner *adjacent = NULL; + 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. + */ + adjacent = dynamic_cast (neighbors[i]); + if (adjacent + && (adjacent->get_bound (-d)->get_column () + == b->get_column ())) + { + neighbor_found = true; + break; + } + } - 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; - } + Interval e = (Axis_group_interface::has_interface (b) + ? Axis_group_interface::generic_bound_extent (b, common, X_AXIS) + : robust_relative_extent (b, common, X_AXIS)); + if (neighbor_found) + { + 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[-d] - d * padding; + } + else + { + if (Note_column::has_interface (b) + && Note_column::has_rests (b)) + x_points[d] = e[-d]; + else + x_points[d] = e[d]; - 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. - */ - else - x_points[d] = e.center () - d * padding / 3; - } - else - { - if (Note_column::has_interface (b) - && Note_column::has_rests (b)) - 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; - } - } - } + Item *bound = me->get_bound (d); + if (bound->is_non_musical (bound)) + x_points[d] -= d * padding; + } + } + } } while (flip (&d) != LEFT); @@ -185,7 +187,7 @@ Hairpin::print (SCM smob) if (width < 0) { me->warning (_ ((grow_dir < 0) ? "decrescendo too small" - : "crescendo too small")); + : "crescendo too small")); width = 0; } @@ -207,7 +209,6 @@ Hairpin::print (SCM smob) /* should do relative to staff-symbol staff-space? */ - Stencil mol; Real x = 0.0; @@ -218,14 +219,14 @@ Hairpin::print (SCM smob) if (circled_tip && !broken[tip_dir]) { if (grow_dir > 0) - x = rad * 2.0; + x = rad * 2.0; else if (grow_dir < 0) - width -= rad *2.0; + width -= rad * 2.0; } mol = Line_interface::line (me, Offset (x, starth), Offset (width, endh)); mol.add_stencil (Line_interface::line (me, - Offset (x, -starth), - Offset (width, -endh))); + Offset (x, -starth), + Offset (width, -endh))); /* Support al/del niente notation by putting a circle at the @@ -234,34 +235,34 @@ 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); + mol.add_at_edge (X_AXIS, tip_dir, Stencil (circle), 0); } mol.translate_axis (x_points[LEFT] - - bounds[LEFT]->relative_coordinate (common, X_AXIS), - X_AXIS); + - bounds[LEFT]->relative_coordinate (common, X_AXIS), + X_AXIS); return mol.smobbed_copy (); } ADD_INTERFACE (Hairpin, - "A hairpin crescendo/decrescendo.", + "A hairpin crescendo or decrescendo.", - /* props */ - "adjacent-hairpins " - "circled-tip " - "bound-padding " - "grow-direction " - "height " - ); + /* properties */ + "adjacent-spanners " + "circled-tip " + "bound-padding " + "grow-direction " + "height " + );