X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ffigured-bass-engraver.cc;h=8a06ea3a1b8471ef5fcfee3ab3229d25e1f3c3ee;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=f201ee01f754665b92e2dfabec201bdbac2bda2c;hpb=75482cfd6b33d261633cdff0e81e19cde090c5d2;p=lilypond.git diff --git a/lily/figured-bass-engraver.cc b/lily/figured-bass-engraver.cc index f201ee01f7..8a06ea3a1b 100644 --- a/lily/figured-bass-engraver.cc +++ b/lily/figured-bass-engraver.cc @@ -3,22 +3,21 @@ source file of the GNU LilyPond music typesetter - (c) 2005 Han-Wen Nienhuys + (c) 2005--2008 Han-Wen Nienhuys */ #include "engraver.hh" +#include "align-interface.hh" +#include "axis-group-interface.hh" #include "context.hh" -#include "music.hh" +#include "grob-array.hh" #include "item.hh" -#include "spanner.hh" -#include "axis-group-interface.hh" -#include "align-interface.hh" #include "pointer-group-interface.hh" +#include "spanner.hh" +#include "stream-event.hh" #include "text-interface.hh" -#include "grob-array.hh" - #include "translator.icc" @@ -29,9 +28,12 @@ struct Figure_group SCM number_; SCM alteration_; + SCM augmented_; + SCM diminished_; + SCM augmented_slash_; Item *figure_item_; - Music *current_music_; + Stream_event *current_event_; bool force_no_continuation_; Figure_group () @@ -41,41 +43,52 @@ struct Figure_group continuation_line_ = 0; number_ = SCM_EOL; alteration_ = SCM_EOL; + augmented_ = SCM_EOL; + diminished_ = SCM_EOL; + augmented_slash_ = SCM_EOL; group_ = 0; - current_music_ = 0; + current_event_ = 0; } bool is_continuation () const { return - current_music_ + current_event_ && !force_no_continuation_ && ly_is_equal (number_, - current_music_->get_property ("figure")) + current_event_->get_property ("figure")) && ly_is_equal (alteration_, - current_music_->get_property ("alteration")); + current_event_->get_property ("alteration")) + && ly_is_equal (augmented_, + current_event_->get_property ("augmented")) + && ly_is_equal (diminished_, + current_event_->get_property ("diminished")) + && ly_is_equal (augmented_slash_, + current_event_->get_property ("augmented-slash")); } }; struct Figured_bass_engraver : public Engraver { - TRANSLATOR_DECLARATIONS(Figured_bass_engraver); - void clear_spanners(); + TRANSLATOR_DECLARATIONS (Figured_bass_engraver); + void clear_spanners (); void add_brackets (); void create_grobs (); - void center_continuations (Link_array const &consecutive_lines); + void center_continuations (vector const &consecutive_lines); void center_repeated_continuations (); protected: - Array groups_; + vector groups_; Spanner *alignment_; - Link_array new_musics_; + vector new_events_; bool continuation_; - bool new_music_found_; + bool new_event_found_; Moment stop_moment_; - Music *rest_event_; - - virtual bool try_music (Music *); + Stream_event *rest_event_; + + DECLARE_TRANSLATOR_LISTENER (rest); + DECLARE_TRANSLATOR_LISTENER (bass_figure); + virtual void derived_mark () const; void start_translation_timestep (); @@ -86,24 +99,27 @@ protected: void Figured_bass_engraver::derived_mark () const { - for (int i = 0; i < groups_.size (); i++) + for (vsize i = 0; i < groups_.size (); i++) { scm_gc_mark (groups_[i].number_); scm_gc_mark (groups_[i].alteration_); + scm_gc_mark (groups_[i].augmented_); + scm_gc_mark (groups_[i].diminished_); + scm_gc_mark (groups_[i].augmented_slash_); } } void Figured_bass_engraver::stop_translation_timestep () { - if (groups_.is_empty () + if (groups_.empty () || now_mom ().main_part_ < stop_moment_.main_part_ || now_mom ().grace_part_ < Rational (0)) return ; bool found = false; - for (int i = 0; !found && i < groups_.size (); i++) - found = found || groups_[i].current_music_; + for (vsize i = 0; !found && i < groups_.size (); i++) + found = found || groups_[i].current_event_; if (!found) clear_spanners (); @@ -114,7 +130,7 @@ Figured_bass_engraver::Figured_bass_engraver () alignment_ = 0; continuation_ = false; rest_event_ = 0; - new_music_found_ = false; + new_event_found_ = false; } void @@ -125,60 +141,71 @@ Figured_bass_engraver::start_translation_timestep () return ; rest_event_ = 0; - new_musics_.clear (); - for (int i = 0; i < groups_.size (); i++) - { - groups_[i].current_music_ = 0; - } + new_events_.clear (); + for (vsize i = 0; i < groups_.size (); i++) + groups_[i].current_event_ = 0; + continuation_ = false; + + } -bool -Figured_bass_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Figured_bass_engraver, rest); +void +Figured_bass_engraver::listen_rest (Stream_event *ev) { - new_music_found_ = true; - if (m->is_mus_type ("rest-event")) + if (to_boolean (get_property ("ignoreFiguredBassRest"))) { - rest_event_ = m; - return true; + new_event_found_ = true; + + /* + No ASSIGN_EVENT_ONCE () ; otherwise we get warnings about + polyphonic rests. + */ + rest_event_ = ev; } - else +} + +IMPLEMENT_TRANSLATOR_LISTENER (Figured_bass_engraver, bass_figure); +void +Figured_bass_engraver::listen_bass_figure (Stream_event *ev) +{ + new_event_found_ = true; + Moment stop = now_mom () + get_event_length (ev, now_mom ()); + stop_moment_ = max (stop_moment_, stop); + + if (to_boolean (get_property ("useBassFigureExtenders"))) { - stop_moment_ = now_mom () + m->get_length (); - - SCM fig = m->get_property ("figure"); - for (int i = 0; i < groups_.size (); i++) + SCM fig = ev->get_property ("figure"); + for (vsize i = 0; i < groups_.size (); i++) { - if (!groups_[i].current_music_ + if (!groups_[i].current_event_ && ly_is_equal (groups_[i].number_, fig)) { - groups_[i].current_music_ = m; + groups_[i].current_event_ = ev; groups_[i].force_no_continuation_ - = to_boolean (m->get_property ("no-continuation")); + = to_boolean (ev->get_property ("no-continuation")); continuation_ = true; - return true; + return; } } - - new_musics_.push (m); - - return true; - } + } + new_events_.push_back (ev); } void -Figured_bass_engraver::center_continuations (Link_array const &consecutive_lines) +Figured_bass_engraver::center_continuations (vector const &consecutive_lines) { if (consecutive_lines.size () == 2) { - Link_array left_figs; - for (int j = consecutive_lines.size(); j--;) - left_figs.push (consecutive_lines[j]->get_bound (LEFT)); + vector left_figs; + for (vsize j = consecutive_lines.size (); j--;) + left_figs.push_back (consecutive_lines[j]->get_bound (LEFT)); SCM ga = Grob_array::make_array (); unsmob_grob_array (ga)->set_array (left_figs); - for (int j = consecutive_lines.size(); j--;) + for (vsize j = consecutive_lines.size (); j--;) consecutive_lines[j]->set_object ("figures", unsmob_grob_array (ga)->smobbed_copy ()); } @@ -187,19 +214,17 @@ Figured_bass_engraver::center_continuations (Link_array const &consecut void Figured_bass_engraver::center_repeated_continuations () { - Link_array consecutive_lines; - for (int i = 0; i <= groups_.size(); i++) + vector consecutive_lines; + for (vsize i = 0; i <= groups_.size (); i++) { if (i < groups_.size () && groups_[i].continuation_line_ - && (consecutive_lines.is_empty () - || (consecutive_lines[0]->get_bound(LEFT)->get_column () + && (consecutive_lines.empty () + || (consecutive_lines[0]->get_bound (LEFT)->get_column () == groups_[i].continuation_line_->get_bound (LEFT)->get_column () - && consecutive_lines[0]->get_bound(RIGHT)->get_column () + && consecutive_lines[0]->get_bound (RIGHT)->get_column () == groups_[i].continuation_line_->get_bound (RIGHT)->get_column ()))) - { - consecutive_lines.push (groups_[i].continuation_line_); - } + consecutive_lines.push_back (groups_[i].continuation_line_); else { center_continuations (consecutive_lines); @@ -213,38 +238,56 @@ Figured_bass_engraver::clear_spanners () { if (!alignment_) return; - - alignment_ = 0; + + if (alignment_) + { + announce_end_grob (alignment_, SCM_EOL); + alignment_ = 0; + } + if (to_boolean (get_property ("figuredBassCenterContinuations"))) - center_repeated_continuations(); + center_repeated_continuations (); - groups_.clear (); + for (vsize i = 0; i < groups_.size (); i++) + { + if (groups_[i].group_) + { + announce_end_grob (groups_[i].group_ , SCM_EOL); + groups_[i].group_ = 0; + } + + if (groups_[i].continuation_line_) + { + announce_end_grob (groups_[i].continuation_line_ , SCM_EOL); + groups_[i].continuation_line_ = 0; + } + } + + /* Check me, groups_.clear () ? */ } void Figured_bass_engraver::add_brackets () { - Link_array encompass; + vector encompass; bool inside = false; - for (int i = 0; i < groups_.size (); i ++) + for (vsize i = 0; i < groups_.size (); i ++) { - if (!groups_[i].current_music_) + if (!groups_[i].current_event_) continue; - if (to_boolean (groups_[i].current_music_->get_property ("bracket-start"))) - { - inside = true; - } + if (to_boolean (groups_[i].current_event_->get_property ("bracket-start"))) + inside = true; if (inside && groups_[i].figure_item_) - encompass.push (groups_[i].figure_item_); + encompass.push_back (groups_[i].figure_item_); - if (to_boolean (groups_[i].current_music_->get_property ("bracket-stop"))) + if (to_boolean (groups_[i].current_event_->get_property ("bracket-stop"))) { inside = false; - Item * brack = make_item ("BassFigureBracket", groups_[i].current_music_->self_scm ()); - for (int j = 0; j < encompass.size (); j++) + Item * brack = make_item ("BassFigureBracket", groups_[i].current_event_->self_scm ()); + for (vsize j = 0; j < encompass.size (); j++) { Pointer_group_interface::add_grob (brack, ly_symbol2scm ("elements"), @@ -258,23 +301,28 @@ Figured_bass_engraver::add_brackets () void Figured_bass_engraver::process_music () { + if (alignment_ && !to_boolean (get_property ("useBassFigureExtenders"))) + clear_spanners (); + if (rest_event_) { clear_spanners (); + groups_.clear (); return; } if (!continuation_ - && new_musics_.is_empty ()) + && new_events_.empty ()) { clear_spanners (); + groups_.clear (); return; } - if (!new_music_found_) - return ; + if (!new_event_found_) + return; - new_music_found_ = false; + new_event_found_ = false; /* Don't need to sync alignments, if we're not using extenders. @@ -282,60 +330,58 @@ Figured_bass_engraver::process_music () bool use_extenders = to_boolean (get_property ("useBassFigureExtenders")); if (!use_extenders) { - if (to_boolean (get_property ("figuredBassCenterContinuations"))) - center_repeated_continuations (); - alignment_ = 0; - for (int i = 0; i < groups_.size (); i++) - { - groups_[i].group_ = 0; - groups_[i].continuation_line_ = 0; - } + clear_spanners (); } if (!continuation_) { clear_spanners (); + groups_.clear (); } - - int k = 0; - for (int i = 0; i < new_musics_.size (); i++) + + vsize k = 0; + for (vsize i = 0; i < new_events_.size (); i++) { - while (k < groups_.size() && - groups_[k].current_music_) + while (k < groups_.size () + && groups_[k].current_event_) k++; if (k >= groups_.size ()) { Figure_group group; - groups_.push (group); + groups_.push_back (group); } - groups_[k].current_music_ = new_musics_[i]; + groups_[k].current_event_ = new_events_[i]; groups_[k].figure_item_ = 0; k++; } - for (int i = 0; i < groups_.size (); i++) + for (vsize i = 0; i < groups_.size (); i++) { if (!groups_[i].is_continuation ()) { groups_[i].number_ = SCM_BOOL_F; groups_[i].alteration_ = SCM_BOOL_F; + groups_[i].augmented_ = SCM_BOOL_F; + groups_[i].diminished_ = SCM_BOOL_F; + groups_[i].augmented_slash_ = SCM_BOOL_F; } } if (use_extenders) { - Array junk_continuations; - for (int i = 0; i < groups_.size(); i++) + vector junk_continuations; + for (vsize i = 0; i < groups_.size (); i++) { - Figure_group &group = groups_[i]; + Figure_group &group = groups_[i]; if (group.is_continuation ()) { if (!group.continuation_line_) { - Spanner * line = make_spanner ("BassFigureContinuation", SCM_EOL); + Spanner * line + = make_spanner ("BassFigureContinuation", SCM_EOL); Item * item = group.figure_item_; group.continuation_line_ = line; line->set_bound (LEFT, item); @@ -351,30 +397,30 @@ Figured_bass_engraver::process_music () } } else if (group.continuation_line_) - junk_continuations.push (i); + junk_continuations.push_back (i); } /* Ugh, repeated code. */ - Link_array consecutive; + vector consecutive; if (to_boolean (get_property ("figuredBassCenterContinuations"))) { - for (int i = 0; i <= junk_continuations.size (); i++) + for (vsize i = 0; i <= junk_continuations.size (); i++) { - if (i < junk_continuations.size() + if (i < junk_continuations.size () && (i == 0 || junk_continuations[i-1] == junk_continuations[i] - 1)) - consecutive.push (groups_[junk_continuations[i]].continuation_line_); + consecutive.push_back (groups_[junk_continuations[i]].continuation_line_); else { center_continuations (consecutive); consecutive.clear (); if (i < junk_continuations.size ()) - consecutive.push (groups_[junk_continuations[i]].continuation_line_); + consecutive.push_back (groups_[junk_continuations[i]].continuation_line_); } } } - for (int i = 0; i < junk_continuations.size (); i++) + for (vsize i = 0; i < junk_continuations.size (); i++) groups_[junk_continuations[i]].continuation_line_ = 0; } @@ -385,7 +431,8 @@ Figured_bass_engraver::process_music () void Figured_bass_engraver::create_grobs () { - Grob *muscol = dynamic_cast (unsmob_grob (get_property ("currentMusicalColumn"))); + Grob *muscol + = dynamic_cast (unsmob_grob (get_property ("currentMusicalColumn"))); if (!alignment_) { alignment_ = make_spanner ("BassFigureAlignment", SCM_EOL); @@ -394,18 +441,18 @@ Figured_bass_engraver::create_grobs () alignment_->set_bound (RIGHT, muscol); SCM proc = get_property ("figuredBassFormatter"); - for (int i = 0; i < groups_.size(); i++) + for (vsize i = 0; i < groups_.size (); i++) { Figure_group &group = groups_[i]; - if (group.current_music_) + if (group.current_event_) { Item *item = make_item ("BassFigure", - group.current_music_->self_scm ()); + group.current_event_->self_scm ()); - SCM fig = group.current_music_->get_property ("figure"); + SCM fig = group.current_event_->get_property ("figure"); if (!group.group_) { group.group_ = make_spanner ("BassFigureLine", SCM_EOL); @@ -421,13 +468,16 @@ Figured_bass_engraver::create_grobs () } group.number_ = fig; - group.alteration_ = group.current_music_->get_property ("alteration"); + group.alteration_ = group.current_event_->get_property ("alteration"); + group.augmented_ = group.current_event_->get_property ("augmented"); + group.diminished_ = group.current_event_->get_property ("diminished"); + group.augmented_slash_ = group.current_event_->get_property ("augmented-slash"); - SCM text = group.current_music_->get_property ("text"); + SCM text = group.current_event_->get_property ("text"); if (!Text_interface::is_markup (text) && ly_is_procedure (proc)) { - text = scm_call_3 (proc, fig, group.current_music_->self_scm (), + text = scm_call_3 (proc, fig, group.current_event_->self_scm (), context ()->self_scm ()); } @@ -445,34 +495,33 @@ Figured_bass_engraver::create_grobs () group.figure_item_->set_property ("transparent", SCM_BOOL_T); group.continuation_line_->set_bound (RIGHT, group.figure_item_); } - if (groups_[i].group_) groups_[i].group_->set_bound (RIGHT, muscol); + } } ADD_TRANSLATOR (Figured_bass_engraver, /* doc */ - "Make figured bass numbers.", + /* create */ "BassFigure " "BassFigureAlignment " - "BassFigureBracket", + "BassFigureBracket " "BassFigureContinuation " - "BassFigureLine " - - /* accept */ - "bass-figure-event rest-event", + "BassFigureLine ", /* read */ + "figuredBassAlterationDirection " "figuredBassCenterContinuations " - "implicitBassFigures " "figuredBassFormatter " - "figuredBassAlterationDirection " - "useBassFigureExtenders", + "implicitBassFigures " + "useBassFigureExtenders " + "ignoreFiguredBassRest ", /* write */ - ""); + "" + );