-#if 0
-/*
- note-spacing-engraver.cc -- implement Note_spacing_engraver.
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2006--2014 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
+ && !unsmob_grob_array (last_spacing->get_object ("right-items")))
+ {
+ Grob *col = unsmob_grob (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 = unsmob_grob (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 */
+ ""
+ );