X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fcompletion-note-heads-engraver.cc;h=ef3a5012a26cbc5a77d192904ffb216d5082c4ab;hb=5944d20489bb5b8e4c4907fa3b3bcae9ec275ccb;hp=52a7d6c0bd4d0a64db0fb6610a889c313f9c0781;hpb=25ca54b640c067e2286a1d7ba47f24a1b4dc070e;p=lilypond.git diff --git a/lily/completion-note-heads-engraver.cc b/lily/completion-note-heads-engraver.cc index 52a7d6c0bd..ef3a5012a2 100644 --- a/lily/completion-note-heads-engraver.cc +++ b/lily/completion-note-heads-engraver.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 1997--2012 Han-Wen Nienhuys + Copyright (C) 1997--2015 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 @@ -59,7 +59,7 @@ class Completion_heads_engraver : public Engraver vector notes_; vector prev_notes_; // Must remember notes for explicit ties. - vector ties_; + vector ties_; vector note_events_; Spanner *tie_column_; Moment note_end_mom_; @@ -80,7 +80,7 @@ protected: void start_translation_timestep (); void process_music (); void stop_translation_timestep (); - DECLARE_TRANSLATOR_LISTENER (note); + void listen_note (Stream_event *); }; void @@ -89,7 +89,6 @@ Completion_heads_engraver::initialize () is_first_ = false; } -IMPLEMENT_TRANSLATOR_LISTENER (Completion_heads_engraver, note); void Completion_heads_engraver::listen_note (Stream_event *ev) { @@ -109,15 +108,21 @@ Completion_heads_engraver::listen_note (Stream_event *ev) Moment Completion_heads_engraver::next_moment (Rational const ¬e_len) { - Moment *e = unsmob_moment (get_property ("measurePosition")); - Moment *l = unsmob_moment (get_property ("measureLength")); + Moment *e = unsmob (get_property ("measurePosition")); + Moment *l = unsmob (get_property ("measureLength")); if (!e || !l || !to_boolean (get_property ("timing"))) { return Moment (0, 0); } Moment result = *l - *e; - Moment const *unit = unsmob_moment (get_property ("completionUnit")); + if (result < 0) + { + programming_error ("invalid measure position: " + + e->to_string () + " of " + l->to_string ()); + return 0; + } + Moment const *unit = unsmob (get_property ("completionUnit")); if (unit) { @@ -156,9 +161,9 @@ Item * Completion_heads_engraver::make_note_head (Stream_event *ev) { Item *note = make_item ("NoteHead", ev->self_scm ()); - Pitch *pit = unsmob_pitch (ev->get_property ("pitch")); + Pitch *pit = unsmob (ev->get_property ("pitch")); - int pos = pit->steps (); + int pos = pit ? pit->steps () : 0; SCM c0 = get_property ("middleCPosition"); if (scm_is_number (c0)) pos += scm_to_int (c0); @@ -188,25 +193,24 @@ Completion_heads_engraver::process_music () note that note_dur may be strictly less than left_to_do_ (say, if left_to_do_ == 5/8) */ - if (factor_.denominator () == 1 && factor_ > Rational (1, 1)) - note_dur = Duration (left_to_do_, false); - else - note_dur = Duration (left_to_do_ / factor_, false).compressed (factor_); + note_dur = Duration (left_to_do_ / factor_, false).compressed (factor_); } else { - orig = unsmob_duration (note_events_[0]->get_property ("duration")); + orig = unsmob (note_events_[0]->get_property ("duration")); note_dur = *orig; - factor_ = note_dur.factor (); + SCM factor = get_property ("completionFactor"); + if (ly_is_procedure (factor)) + factor = scm_call_2 (factor, + context ()->self_scm (), + note_dur.smobbed_copy ()); + factor_ = robust_scm2rational (factor, note_dur.factor ()); left_to_do_ = orig->get_length (); } Moment nb = next_moment (note_dur.get_length ()); if (nb.main_part_ && nb < note_dur.get_length ()) { - if (factor_.denominator () == 1 && factor_.numerator () > 1) - note_dur = Duration (nb.main_part_, false); - else - note_dur = Duration (nb.main_part_ / factor_, false).compressed (factor_); + note_dur = Duration (nb.main_part_ / factor_, false).compressed (factor_); } do_nothing_until_ = now.main_part_ + note_dur.get_length (); @@ -266,7 +270,7 @@ Completion_heads_engraver::process_music () void Completion_heads_engraver::make_tie (Grob *left, Grob *right) { - Grob *p = make_spanner ("Tie", SCM_EOL); + Spanner *p = make_spanner ("Tie", SCM_EOL); Tie::set_head (p, LEFT, left); Tie::set_head (p, RIGHT, right); announce_end_grob (p, SCM_EOL); @@ -302,6 +306,12 @@ Completion_heads_engraver::Completion_heads_engraver () tie_column_ = 0; } +void +Completion_heads_engraver::boot () +{ + ADD_LISTENER (Completion_heads_engraver, note); +} + ADD_TRANSLATOR (Completion_heads_engraver, /* doc */ "This engraver replaces @code{Note_heads_engraver}. It plays" @@ -314,6 +324,7 @@ ADD_TRANSLATOR (Completion_heads_engraver, "TieColumn ", /* read */ + "completionFactor " "completionUnit " "measureLength " "measurePosition "