From 0c5927ef30c9f9a9ddec37cc2b9e660695d27303 Mon Sep 17 00:00:00 2001 From: Joe Neeman Date: Fri, 27 May 2011 18:57:16 +0300 Subject: [PATCH] Emit not-quite-cross-staff beams in the right context. This is related to 1043 and possibly other bugs. Previously, if a staff change happened immediately after the termination of an auto-engraved cross-staff beam, then the beam was parented to the wrong staff. Now, every beam is parented to the context in which it began. --- lily/auto-beam-engraver.cc | 11 ++++++++-- lily/engraver-group.cc | 11 ++++++++-- lily/engraver.cc | 42 +++++++++++++++----------------------- lily/grob-info.cc | 2 ++ lily/include/engraver.hh | 2 ++ lily/include/grob-info.hh | 9 ++++++++ 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 66b79fe008..0d5fa60ed2 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -80,6 +80,7 @@ private: Moment extend_mom_; Moment beam_start_moment_; Moment beam_start_location_; + Context *beam_start_context_; // We act as if beam were created, and start a grouping anyway. Beaming_pattern *grouping_; @@ -219,7 +220,9 @@ Auto_beam_engraver::create_beam () for (vsize i = 0; i < stems_->size (); i++) Beam::add_stem (beam, (*stems_)[i]); - announce_grob (beam, (*stems_)[0]->self_scm ()); + Grob_info i = make_grob_info (beam, (*stems_)[0]->self_scm ()); + i.rerouting_daddy_context_ = beam_start_context_; + announce_grob (i); return beam; } @@ -238,6 +241,7 @@ Auto_beam_engraver::begin_beam () beaming_options_.from_context (context ()); beam_settings_ = updated_grob_properties (context (), ly_symbol2scm ("Beam")); + beam_start_context_ = context ()->get_parent_context (); beam_start_moment_ = now_mom (); beam_start_location_ = robust_scm2moment (get_property ("measurePosition"), Moment (0)); @@ -269,7 +273,10 @@ Auto_beam_engraver::end_beam () if (finished_beam_) { - announce_end_grob (finished_beam_, SCM_EOL); + Grob_info i = make_grob_info (finished_beam_, SCM_EOL); + i.rerouting_daddy_context_ = beam_start_context_; + + announce_end_grob (i); finished_grouping_ = grouping_; finished_beaming_options_ = beaming_options_; } diff --git a/lily/engraver-group.cc b/lily/engraver-group.cc index 07a0ef5091..a5782d23b0 100644 --- a/lily/engraver-group.cc +++ b/lily/engraver-group.cc @@ -70,9 +70,16 @@ Engraver_group::announce_grob (Grob_info info) { announce_infos_.push_back (info); + Context *dad_con = context_->get_parent_context (); + if (info.rerouting_daddy_context_) + { + dad_con = info.rerouting_daddy_context_; + info.rerouting_daddy_context_ = 0; + } + Engraver_group *dad_eng - = context_->get_parent_context () - ? dynamic_cast (context_->get_parent_context ()->implementation ()) + = dad_con + ? dynamic_cast (dad_con->implementation ()) : 0; if (dad_eng) diff --git a/lily/engraver.cc b/lily/engraver.cc index 8e49280fd8..12615eb8d6 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -43,29 +43,33 @@ Engraver::announce_grob (Grob_info inf) void Engraver::announce_end_grob (Grob_info inf) { + inf.start_end_ = STOP; get_daddy_engraver ()->announce_grob (inf); } -/* - CAUSE is the object (typically a Stream_event object) that - was the reason for making E. -*/ -void -Engraver::announce_grob (Grob *e, SCM cause) +Grob_info +Engraver::make_grob_info(Grob *e, SCM cause) { /* TODO: Remove Music code when it's no longer needed */ if (Music *m = unsmob_music (cause)) { cause = m->to_event ()->unprotect (); } - if (unsmob_stream_event (cause) || unsmob_grob (cause)) + if (e->get_property ("cause") == SCM_EOL + && (unsmob_stream_event (cause) || unsmob_grob (cause))) e->set_property ("cause", cause); - Grob_info i (this, e); + return Grob_info (this, e); +} - Engraver_group *g = get_daddy_engraver (); - if (g) - g->announce_grob (i); +/* + CAUSE is the object (typically a Stream_event object) that + was the reason for making E. +*/ +void +Engraver::announce_grob (Grob *e, SCM cause) +{ + announce_grob (make_grob_info (e, cause)); } @@ -75,21 +79,7 @@ Engraver::announce_grob (Grob *e, SCM cause) void Engraver::announce_end_grob (Grob *e, SCM cause) { - /* TODO: Remove Music code when it's no longer needed */ - if (Music *m = unsmob_music (cause)) - { - cause = m->to_event ()->unprotect (); - } - if (e->get_property ("cause") == SCM_EOL - && (unsmob_stream_event (cause) || unsmob_grob (cause))) - e->set_property ("cause", cause); - - Grob_info i (this, e); - - i.start_end_ = STOP; - Engraver_group *g = get_daddy_engraver (); - if (g) - g->announce_grob (i); + announce_end_grob (make_grob_info (e, cause)); } diff --git a/lily/grob-info.cc b/lily/grob-info.cc index f02e836e75..b710477a8e 100644 --- a/lily/grob-info.cc +++ b/lily/grob-info.cc @@ -30,6 +30,7 @@ Grob_info::Grob_info (Translator *t, Grob *g) origin_trans_ = t; grob_ = g; start_end_ = START; + rerouting_daddy_context_ = 0; /* assert here, because this is easier to debug. @@ -42,6 +43,7 @@ Grob_info::Grob_info () grob_ = 0; start_end_ = START; origin_trans_ = 0; + rerouting_daddy_context_ = 0; } Stream_event * diff --git a/lily/include/engraver.hh b/lily/include/engraver.hh index 1488d78c75..162724b808 100644 --- a/lily/include/engraver.hh +++ b/lily/include/engraver.hh @@ -52,6 +52,8 @@ public: void announce_grob (Grob *, SCM cause); void announce_end_grob (Grob *, SCM cause); + Grob_info make_grob_info (Grob *, SCM cause); + Item *internal_make_item (SCM sym, SCM cause, char const *name, char const *f, int l, char const *fun); Spanner *internal_make_spanner (SCM sym, SCM cause, char const *name, diff --git a/lily/include/grob-info.hh b/lily/include/grob-info.hh index f9390fff44..56a49170a4 100644 --- a/lily/include/grob-info.hh +++ b/lily/include/grob-info.hh @@ -32,6 +32,7 @@ class Grob_info Translator *origin_trans_; Grob *grob_; Direction start_end_; + friend class Engraver; public: @@ -49,6 +50,14 @@ public: Item *item () const; Spanner *spanner () const; static bool less (Grob_info i, Grob_info j); + + /* + For contexts that change staves, it may be desirable to emit a + grob into a staff other than the current one. If this is non-null, + this grob should be announced in this context instead of the + daddy_context_. + */ + Context *rerouting_daddy_context_; }; #endif // STAFFELEMINFO_HH -- 2.39.2