X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fphrasing-slur-engraver.cc;h=5e5e7ced8cfa0650b29a81b80f42cd7487ce7f8a;hb=6e99d79145c093c931838c1a8c2f447cb6d5660a;hp=ea2439534c2b210e42250269471c7c26c684d3c6;hpb=d1268d3c8de1cbfee0c878265450f9a4b3492805;p=lilypond.git diff --git a/lily/phrasing-slur-engraver.cc b/lily/phrasing-slur-engraver.cc index ea2439534c..5e5e7ced8c 100644 --- a/lily/phrasing-slur-engraver.cc +++ b/lily/phrasing-slur-engraver.cc @@ -70,6 +70,7 @@ protected: void process_music (); virtual void finalize (); + virtual void derived_mark () const; public: TRANSLATOR_DECLARATIONS (Phrasing_slur_engraver); @@ -79,6 +80,15 @@ Phrasing_slur_engraver::Phrasing_slur_engraver () { } +void +Phrasing_slur_engraver::derived_mark () const +{ + for (vsize i=start_events_.size(); i--;) + scm_gc_mark (start_events_[i]->self_scm ()); + for (vsize i=stop_events_.size(); i--;) + scm_gc_mark (stop_events_[i]->self_scm ()); +} + IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, phrasing_slur); void Phrasing_slur_engraver::listen_phrasing_slur (Stream_event *ev) @@ -165,6 +175,7 @@ Phrasing_slur_engraver::finalize () slurs_[i]->warning (_ ("unterminated phrasing slur")); slurs_[i]->suicide (); } + slurs_.clear (); } void @@ -207,7 +218,7 @@ Phrasing_slur_engraver::process_music () Direction updown = to_dir (ev->get_property ("direction")); bool completed; - for (vsize j = 0; !(completed = (j == slurs_.size ())); j++) + for (vsize j = slurs_.size (); !(completed = (j-- == 0));) { // Check if we already have a slur with the same spanner-id. if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), "")) @@ -223,31 +234,28 @@ Phrasing_slur_engraver::process_music () // If this slur event has no direction, it will not // contribute anything new to the existing slur(s), so - // we can ignore it. This is not entirely accurate: - // tweaks or context properties like those set with - // \slurUp can still override a neutral direction, so - // when encountering a slur event with "opposite" - // direction first, then one with neutral direction, we - // only let the "opposite" direction remain, while if - // the order is the other way round, a double slur - // results since the direction of the first slur is no - // longer attributable to a "neutral" slur event. A - // mixture of neutral and directed events is nothing - // that the partcombiner should crank out, and it would - // be decidedly strange for manual input. + // we can ignore it. if (!updown) break; - // If the existing slur does not have a direction yet, - // give it ours + Stream_event *c = unsmob_stream_event (slurs_[j]->get_property ("cause")); - Direction slur_dir = to_dir (slurs_[j]->get_property ("direction")); + if (!c) { + slurs_[j]->programming_error ("phrasing slur without a cause"); + continue; + } + + Direction slur_dir = to_dir (c->get_property ("direction")); + + // If the existing slur does not have a direction yet, + // we'd rather take the new one. if (!slur_dir) { - set_grob_direction (slurs_[j], updown); - break; + slurs_[j]->suicide (); + slurs_.erase (slurs_.begin () + j); + continue; } // If the existing slur has the same direction as ours, drop ours @@ -271,13 +279,31 @@ Phrasing_slur_engraver::process_music () void Phrasing_slur_engraver::stop_translation_timestep () { + if (Grob *g = unsmob_grob (get_property ("currentCommandColumn"))) + { + for (vsize i = 0; i < end_slurs_.size (); i++) + Slur::add_extra_encompass (end_slurs_[i], g); + + if (!start_events_.size ()) + for (vsize i = 0; i < slurs_.size (); i++) + Slur::add_extra_encompass (slurs_[i], g); + } + + for (vsize i = 0; i < end_slurs_.size (); i++) + { + Spanner *s = dynamic_cast (end_slurs_[i]); + if (!s->get_bound (RIGHT)) + s->set_bound (RIGHT, unsmob_grob (get_property ("currentMusicalColumn"))); + announce_end_grob (s, SCM_EOL); + } + for (vsize i = 0; i < objects_to_acknowledge_.size (); i++) Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slurs_, end_slurs_); + objects_to_acknowledge_.clear (); end_slurs_.clear (); start_events_.clear (); stop_events_.clear (); - objects_to_acknowledge_.clear (); } ADD_ACKNOWLEDGER (Phrasing_slur_engraver, inline_accidental);