diff options
author | Neil Puttock <n.puttock@gmail.com> | 2009-09-18 22:01:24 +0100 |
---|---|---|
committer | Neil Puttock <n.puttock@gmail.com> | 2009-09-18 22:01:24 +0100 |
commit | 001ad87ae4b9cccc9588557e4b944b11b8fe05f1 (patch) | |
tree | a79a231777242bde02daa55df7faf237f8f234ab | |
parent | 786083941557d40acf9ec1920e89e0e02f3981e6 (diff) |
Fix collisions between hairpins and dynamic text spanner bounds.
* rename 'adjacent-hairpins to 'adjacent-spanners
* add DynamicTextSpanner grobs to 'adjacent-spanners in New_dynamic_engraver
* in Hairpin::print (), use renamed property to catch text spans and apply
the appropriate amount of bound-padding
* add regression test
-rw-r--r-- | input/regression/hairpin-neighboring-span-dynamics.ly | 27 | ||||
-rw-r--r-- | lily/hairpin.cc | 74 | ||||
-rw-r--r-- | lily/new-dynamic-engraver.cc | 68 | ||||
-rw-r--r-- | scm/define-grob-properties.scm | 4 |
4 files changed, 105 insertions, 68 deletions
diff --git a/input/regression/hairpin-neighboring-span-dynamics.ly b/input/regression/hairpin-neighboring-span-dynamics.ly new file mode 100644 index 0000000000..d969346e49 --- /dev/null +++ b/input/regression/hairpin-neighboring-span-dynamics.ly @@ -0,0 +1,27 @@ +\version "2.13.4" + +\header { + texidoc = "Bound padding for hairpins also works with neighboring +@code{DynamicTextSpanner} grobs. In this case, @code{bound-padding} +is not scaled down. +" +} + +\relative c' { + \override Hairpin #'to-barline = ##f + c2\> + \dimTextDim + c2\> + \dimHairpin + c\> c\! \break + \dimTextDim + c2\> + \override Hairpin #'bound-padding = #5 + \dimHairpin + c2\> + \dimTextDim + c2\> c\! \break + \crescHairpin + c2\< c\< + c2\< c\! +} diff --git a/lily/hairpin.cc b/lily/hairpin.cc index bb4fec084b..6403c62241 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -70,7 +70,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); @@ -86,8 +86,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... */ @@ -95,7 +95,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 { @@ -117,37 +117,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<Spanner *> (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<Spanner *> (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 { @@ -156,10 +166,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; } } } @@ -218,16 +228,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); @@ -243,7 +253,7 @@ ADD_INTERFACE (Hairpin, "A hairpin crescendo or decrescendo.", /* properties */ - "adjacent-hairpins " + "adjacent-spanners " "circled-tip " "bound-padding " "grow-direction " diff --git a/lily/new-dynamic-engraver.cc b/lily/new-dynamic-engraver.cc index 235dc178d9..489fcf5ea6 100644 --- a/lily/new-dynamic-engraver.cc +++ b/lily/new-dynamic-engraver.cc @@ -1,15 +1,12 @@ /* new-dynamic-engraver.cc -- implement New_dynamic_engraver - + source file of the GNU LilyPond music typesetter - + (c) 2008--2009 Han-Wen Nienhuys <hanwen@lilypond.org> - */ - #include "engraver.hh" - #include "hairpin.hh" #include "international.hh" #include "item.hh" @@ -35,13 +32,14 @@ protected: virtual void finalize (); private: - SCM get_property_setting (Stream_event *evt, char const *evprop, char const *ctxprop); + SCM get_property_setting (Stream_event *evt, char const *evprop, + char const *ctxprop); string get_spanner_type (Stream_event *ev); Drul_array<Stream_event *> accepted_spanevents_drul_; Spanner *current_spanner_; Spanner *finished_spanner_; - + Item *script_; Stream_event *script_event_; Stream_event *current_span_event_; @@ -74,7 +72,9 @@ New_dynamic_engraver::listen_span_dynamic (Stream_event *ev) } SCM -New_dynamic_engraver::get_property_setting (Stream_event *evt, char const *evprop, char const *ctxprop) +New_dynamic_engraver::get_property_setting (Stream_event *evt, + char const *evprop, + char const *ctxprop) { SCM spanner_type = evt->get_property (evprop); if (spanner_type == SCM_EOL) @@ -86,7 +86,9 @@ void New_dynamic_engraver::process_music () { if (current_spanner_ - && (accepted_spanevents_drul_[STOP] || script_event_ || accepted_spanevents_drul_[START])) + && (accepted_spanevents_drul_[STOP] + || script_event_ + || accepted_spanevents_drul_[START])) { Stream_event *ender = accepted_spanevents_drul_[STOP]; if (!ender) @@ -94,7 +96,7 @@ New_dynamic_engraver::process_music () if (!ender) ender = accepted_spanevents_drul_[START]; - + finished_spanner_ = current_spanner_; announce_end_grob (finished_spanner_, ender->self_scm ()); current_spanner_ = 0; @@ -107,7 +109,7 @@ New_dynamic_engraver::process_music () string start_type = get_spanner_type (current_span_event_); SCM cresc_type = get_property_setting (current_span_event_, "span-type", - (start_type + "Spanner").c_str ()); + (start_type + "Spanner").c_str ()); if (cresc_type == ly_symbol2scm ("text")) { @@ -116,11 +118,9 @@ New_dynamic_engraver::process_music () accepted_spanevents_drul_[START]->self_scm ()); SCM text = get_property_setting (current_span_event_, "span-text", - (start_type + "Text").c_str ()); + (start_type + "Text").c_str ()); if (Text_interface::is_markup (text)) - { - current_spanner_->set_property ("text", text); - } + current_spanner_->set_property ("text", text); } else { @@ -132,16 +132,17 @@ New_dynamic_engraver::process_music () } current_spanner_ = make_spanner ("Hairpin", current_span_event_->self_scm ()); - if (finished_spanner_) - { - Pointer_group_interface::add_grob (finished_spanner_, - ly_symbol2scm ("adjacent-hairpins"), - current_spanner_); - - Pointer_group_interface::add_grob (current_spanner_, - ly_symbol2scm ("adjacent-hairpins"), - finished_spanner_); - } + } + if (finished_spanner_) + { + if (Hairpin::has_interface (finished_spanner_)) + Pointer_group_interface::add_grob (finished_spanner_, + ly_symbol2scm ("adjacent-spanners"), + current_spanner_); + if (Hairpin::has_interface (current_spanner_)) + Pointer_group_interface::add_grob (current_spanner_, + ly_symbol2scm ("adjacent-spanners"), + finished_spanner_); } } @@ -161,26 +162,24 @@ New_dynamic_engraver::process_music () set_nested_property (current_spanner_, scm_list_3 (ly_symbol2scm ("bound-details"), ly_symbol2scm ("left"), - ly_symbol2scm ("attach-dir") - ), + ly_symbol2scm ("attach-dir")), scm_from_int (RIGHT)); - } } } - - void New_dynamic_engraver::stop_translation_timestep () { if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT)) - finished_spanner_->set_bound (RIGHT, - unsmob_grob (get_property ("currentMusicalColumn"))); + finished_spanner_ + ->set_bound (RIGHT, + unsmob_grob (get_property ("currentMusicalColumn"))); if (current_spanner_ && !current_spanner_->get_bound (LEFT)) - current_spanner_->set_bound (LEFT, - unsmob_grob (get_property ("currentMusicalColumn"))); + current_spanner_ + ->set_bound (LEFT, + unsmob_grob (get_property ("currentMusicalColumn"))); script_ = 0; script_event_ = 0; accepted_spanevents_drul_.set (0, 0); @@ -216,6 +215,7 @@ New_dynamic_engraver::get_spanner_type (Stream_event *ev) type = "crescendo"; else programming_error ("unknown dynamic spanner type"); + return type; } diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 0ff4f7641a..b9cf4ed3a2 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -884,8 +884,8 @@ constructed from a whole number of squiggles.") (accidental-grob ,ly:grob? "The accidental for this note.") (accidental-grobs ,list? "An alist with @code{(@var{notename} . @var{groblist})} entries.") - (adjacent-hairpins ,ly:grob-array? "An array of directly neighboring -hairpins.") + (adjacent-spanners ,ly:grob-array? "An array of directly neighboring +dynamic spanners.") (all-elements ,ly:grob-array? "An array of all grobs in this line. Its function is to protect objects from being garbage collected.") (arpeggio ,ly:grob? "A pointer to an @code{Arpeggio} object.") |