-#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 */ "");