]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/note-spacing-engraver.cc
Strip midi-debugging ; add memory check to watch RSS value.
[lilypond.git] / lily / note-spacing-engraver.cc
index 47b11ae5ac9f57271b943c4670be328eafccf909..569735f85920ea9b988087db6d9ca2fa9ab03fe2 100644 (file)
-#if 0
-/*   
-  note-spacing-engraver.cc --  implement  Note_spacing_engraver.
-
+/* 
+  note-spacing-engraver.cc -- implement Note_spacing_engraver
+  
   source file of the GNU LilyPond music typesetter
-
-  (c) 2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
+  
+  (c) 2006--2007 Han-Wen Nienhuys <hanwen@lilypond.org>
+  
 */
 
-#include "grob.hh"
-#include "moment.hh"
 #include "engraver.hh"
-#include "note-spacing.hh"
-#include "note-column.hh"
-
-/*
-  Originally, we tried to have this functionality at Staff_level
-  
-  - by simply using the sequence of Separation-item as
-  spacing-sequences. Unfortunately, this fucks up if there are
-  different kinds of tuplets combined (8th and 8ths triplets combined
-  made the program believe there were 1/12 th notes.).
 
+#include "grob-array.hh"
+#include "context.hh"
+#include "item.hh"
+#include "pointer-group-interface.hh"
 
-  - We also created them from Rhythmic_column_engraver, but this has
-  the problem that voices can appear and disappear at will, leaving
-  lots of loose ends (the StaffSpacing don't know where to connect the
-  last note of the voice on the right with)
-  
- */
-
-struct Grob_moment_tuple
-{
-  Link_array<Grob> current_heads_;
-  Link_array<Grob> todo_heads_;
-  
-  Moment length_;
-  
-  static int time_compare (Grob_moment_tuple const &a, Grob_moment_tuple const &b)
-  {
-    return Moment::compare (a.length_, b.length_);
-  }
-};
+#include "translator.icc"
 
 class Note_spacing_engraver : public Engraver
 {
-public:
-  TRANSLATOR_DECLARATIONS(Note_spacing_engraver);
-
+  Grob *last_spacing_;
+  Context *last_spacing_parent_context_;
+  
+  Grob *spacing_;
 
+  void add_spacing_item (Grob *);
+  TRANSLATOR_DECLARATIONS (Note_spacing_engraver);
 protected:
-  Array<Grob_moment_tuple> lengths_found_;
 
-  virtual void acknowledge_grob (Grob_info);
+  DECLARE_ACKNOWLEDGER (rhythmic_grob);
+  DECLARE_ACKNOWLEDGER (note_column);
+  void stop_translation_timestep ();
+  virtual void finalize ();
+  virtual void derived_mark () const;
 };
 
-Note_spacing_engraver::Note_spacing_engraver()
+void
+Note_spacing_engraver::derived_mark () const
 {
+  if (last_spacing_parent_context_)
+    scm_gc_mark (last_spacing_parent_context_->self_scm ());
 }
 
+Note_spacing_engraver::Note_spacing_engraver ()
+{
+  last_spacing_parent_context_ = 0;
+  last_spacing_ = 0;
+  spacing_ = 0;
+}
 
 void
-Note_spacing_engraver::acknowledge_grob (Grob_info gi)
+Note_spacing_engraver::add_spacing_item (Grob *g)
 {
-  if (Note_head::has_interface (gi.grob_l_))
+  if (!spacing_)
     {
-      Music *m = gi.music_cause();
-      Moment now = now_mom ();
-      Moment len = m->length_mom(); 
-      if (now.grace_part_ && len.main_part_)
-       {
-         len.grace_part_ += len.main_part_;
-         len.main_part_ = 0;
-       }
-      
-      for (int  i=0; i <  
+      spacing_ = make_item ("NoteSpacing", g->self_scm ());
     }
-  Note_column::has_interface (gi.grob_l_))
+  
+  if (spacing_)
     {
-      Grob *head  =Note_column::first_head (gi.grob_l_);
-
-      head->
+      Pointer_group_interface::add_grob (spacing_,
+                                        ly_symbol2scm ("left-items"),
+                                        g);
+
+      if (last_spacing_)
+       Pointer_group_interface::add_grob (last_spacing_,
+                                          ly_symbol2scm ("right-items"),
+                                          g);
     }
 }
 
 
+void
+Note_spacing_engraver::acknowledge_note_column (Grob_info gi)
+{
+  add_spacing_item (gi.grob ());
+}
+
+void
+Note_spacing_engraver::acknowledge_rhythmic_grob (Grob_info gi)
+{
+  add_spacing_item (gi.grob ());
+}
+
+void
+Note_spacing_engraver::finalize ()
+{
+  if (last_spacing_
+      && last_spacing_parent_context_
+      && last_spacing_parent_context_ == context ()->get_parent_context ()
+      && !unsmob_grob_array (last_spacing_->get_object ("right-items")))
+    {
+      SCM ccol = get_property ("currentCommandColumn");
+      Grob *column = unsmob_grob (ccol);
+      
+      Pointer_group_interface::add_grob (last_spacing_,
+                                        ly_symbol2scm ("right-items"),
+                                        column);
+    }
+}
 
-ENTER_DESCRIPTION(Note_spacing_engraver,
-/* descr */       "This engraver creates spacing objects. It should be placed at staff
-level, but will also function at voice level.
+void
+Note_spacing_engraver::stop_translation_timestep ()
+{
+  if (last_spacing_
+      && last_spacing_parent_context_
+      && last_spacing_parent_context_ == context ()->get_parent_context ())
+    {
+      Grob *sep = unsmob_grob (get_property ("breakableSeparationItem"));
+      if (sep)
+       Pointer_group_interface::add_grob (last_spacing_,
+                                          ly_symbol2scm ("right-items"),
+                                          sep);
+    }
+  
+  if (spacing_)
+    {
+      last_spacing_ = spacing_;
+      last_spacing_parent_context_ = context ()->get_parent_context ();
+      spacing_ = 0;
+    }
+
+}
 
-",
-/* creats*/       "NoteSpacing",
-/* acks  */       "rhythmic-column-interface",
-/* reads */       "",
-/* write */       "");
+ADD_ACKNOWLEDGER (Note_spacing_engraver, note_column);
+ADD_ACKNOWLEDGER (Note_spacing_engraver, rhythmic_grob);
 
-#endif
+ADD_TRANSLATOR (Note_spacing_engraver,
+               /* doc */ "Generates NoteSpacing, an object linking horizontal lines for use in spacing.",
+               /* create */ "NoteSpacing",
+               /* read */ "",
+               /* write */ "");