]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/note-spacing-engraver.cc
Run grand replace for 2015.
[lilypond.git] / lily / note-spacing-engraver.cc
index 47b11ae5ac9f57271b943c4670be328eafccf909..7a7ca7275fc832a0ee978e30400eb0a4ba754d48 100644 (file)
-#if 0
-/*   
-  note-spacing-engraver.cc --  implement  Note_spacing_engraver.
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 2006--2015 Han-Wen Nienhuys <hanwen@lilypond.org>
 
-  source file of the GNU LilyPond music typesetter
+  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.
 
-  (c) 2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  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 "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.).
-
-
-  - 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 "grob-array.hh"
+#include "context.hh"
+#include "item.hh"
+#include "pointer-group-interface.hh"
+
+#include <map>
+
+#include "translator.icc"
 
 class Note_spacing_engraver : public Engraver
 {
-public:
-  TRANSLATOR_DECLARATIONS(Note_spacing_engraver);
+  typedef map <Context *, Grob *> Last_spacing_map;
+  Last_spacing_map last_spacings_;
+  Grob *last_spacing_;
 
+  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
 {
+  for (Last_spacing_map::const_iterator i = last_spacings_.begin ();
+       i != last_spacings_.end (); i++)
+    scm_gc_mark (i->first->self_scm ());
 }
 
+Note_spacing_engraver::Note_spacing_engraver ()
+{
+  spacing_ = 0;
+  last_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_);
+      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);
+    }
+}
 
-      head->
+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 ()
+{
+  Context *parent = context ()->get_parent_context ();
+  Grob *last_spacing = last_spacings_[parent];
+
+  if (last_spacing
+      && !Grob_array::is_smob (last_spacing->get_object ("right-items")))
+    {
+      Grob *col = Grob::unsmob (get_property ("currentCommandColumn"));
+
+      Pointer_group_interface::add_grob (last_spacing,
+                                         ly_symbol2scm ("right-items"),
+                                         col);
+    }
+}
+
+void
+Note_spacing_engraver::stop_translation_timestep ()
+{
+  Context *parent = context ()->get_parent_context ();
+  Grob *last_spacing = last_spacings_[parent];
+
+  if (last_spacing
+      && to_boolean (get_property ("hasStaffSpacing")))
+    {
+      Grob *col = Grob::unsmob (get_property ("currentCommandColumn"));
+      Pointer_group_interface::add_grob (last_spacing,
+                                         ly_symbol2scm ("right-items"),
+                                         col);
     }
+
+  if (spacing_)
+    {
+      last_spacings_[parent] = spacing_;
+      last_spacing_ = spacing_;
+      spacing_ = 0;
+    }
+
 }
 
+ADD_ACKNOWLEDGER (Note_spacing_engraver, note_column);
+ADD_ACKNOWLEDGER (Note_spacing_engraver, rhythmic_grob);
 
+ADD_TRANSLATOR (Note_spacing_engraver,
+                /* doc */
+                "Generate @code{NoteSpacing}, an object linking horizontal"
+                " lines for use in spacing.",
 
-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.
+                /* create */
+                "NoteSpacing ",
 
-",
-/* creats*/       "NoteSpacing",
-/* acks  */       "rhythmic-column-interface",
-/* reads */       "",
-/* write */       "");
+                /* read */
+                "",
 
-#endif
+                /* write */
+                ""
+               );