]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/completion-note-heads-engraver.cc
Completion_rest_engraver: new engraver.
[lilypond.git] / lily / completion-note-heads-engraver.cc
index 1522dad8b3d4ada7bdb589003b6ae95dddd74ab4..08bbcb47e83ed7001d251270704c75562e2cf861 100644 (file)
@@ -1,7 +1,20 @@
 /*
-  completion-note-heads-engraver.cc -- Completion_heads_engraver
+  This file is part of LilyPond, the GNU music typesetter.
 
-  (c) 1997--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include <cctype>
@@ -32,12 +45,13 @@ struct Pending_tie
 {
   Moment when_;
   Stream_event* tie_event_;
-  Pending_tie() { tie_event_ = 0; }
+  Pending_tie () : tie_event_ (0) {}
 };
 
-int compare(Pending_tie const &a, Pending_tie const &b)
+static int
+compare (Pending_tie const &a, Pending_tie const &b)
 {
-  return compare(a.when_, b.when_);
+  return compare (a.when_, b.when_);
 }
 
 
@@ -60,19 +74,18 @@ class Completion_heads_engraver : public Engraver
 {
   vector<Item*> notes_;
   vector<Item*> prev_notes_;
-
   // Must remember notes for explicit ties.
   vector<Item*> tie_note_candidates_;
   vector<Stream_event*> tie_note_candidate_events_;
   vector<Grob*> ties_;
   PQueue<Pending_tie> pending_ties_;
   vector<Stream_event*> note_events_;
-
   Stream_event *current_tie_event_;
   Moment note_end_mom_;
   bool is_first_;
   Rational left_to_do_;
   Rational do_nothing_until_;
+  Rational factor_;
 
   Moment next_barline_moment ();
   Item *make_note_head (Stream_event*);
@@ -174,22 +187,33 @@ Completion_heads_engraver::process_music ()
   Duration note_dur;
   Duration *orig = 0;
   if (left_to_do_)
-    note_dur = Duration (left_to_do_, false);
+    {
+      /*
+       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_);
+    }
   else
     {
       orig = unsmob_duration (note_events_[0]->get_property ("duration"));
       note_dur = *orig;
+      factor_ = note_dur.factor ();
+      left_to_do_ = orig->get_length ();
     }
   Moment nb = next_barline_moment ();
   if (nb.main_part_ && nb < note_dur.get_length ())
     {
-      note_dur = Duration (nb.main_part_, false);
-
-      do_nothing_until_ = now.main_part_ + note_dur.get_length ();
+      if (factor_.denominator () == 1 && factor_ > Rational (1, 1))
+       note_dur = Duration (nb.main_part_, false);
+      else
+       note_dur = Duration (nb.main_part_ / factor_, false).compressed (factor_);
     }
 
-  if (orig)
-    left_to_do_ = orig->get_length ();
+  do_nothing_until_ = now.main_part_ + note_dur.get_length ();
 
   for (vsize i = 0; left_to_do_ && i < note_events_.size (); i++)
     {
@@ -200,7 +224,6 @@ Completion_heads_engraver::process_music ()
        event = event->clone ();
 
       SCM pits = note_events_[i]->get_property ("pitch");
-
       event->set_property ("pitch", pits);
       event->set_property ("duration", note_dur.smobbed_copy ());
       event->set_property ("length", Moment (note_dur.get_length ()).smobbed_copy ());
@@ -290,18 +313,18 @@ ADD_TRANSLATOR (Completion_heads_engraver,
                /* doc */
                "This engraver replaces @code{Note_heads_engraver}.  It plays"
                " some trickery to break long notes and automatically tie them"
-               " into the next measure.",
-
+               " into the next measure."
+               ,
                /* create */
                "NoteHead "
                "Dots "
-               "Tie ",
-
+               "Tie "
+               ,
                /* read */
                "middleCPosition "
                "measurePosition "
-               "measureLength ",
-
+               "measureLength "
+               ,
                /* write */
                "completionBusy "
                );