X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnote-spacing-engraver.cc;h=8a5f5c7944228753efbc518241bf09773827fac6;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=47b11ae5ac9f57271b943c4670be328eafccf909;hpb=8dbb0048c1ac59125562d5adc1c68512eab8541b;p=lilypond.git diff --git a/lily/note-spacing-engraver.cc b/lily/note-spacing-engraver.cc index 47b11ae5ac..8a5f5c7944 100644 --- a/lily/note-spacing-engraver.cc +++ b/lily/note-spacing-engraver.cc @@ -1,99 +1,145 @@ -#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 - + + (c) 2006--2008 Han-Wen Nienhuys + */ -#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" +#include - - 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) - - */ +#include "translator.icc" -struct Grob_moment_tuple +class Note_spacing_engraver : public Engraver { - Link_array current_heads_; - Link_array todo_heads_; + typedef map Last_spacing_map; + Last_spacing_map last_spacings_; + Grob *last_spacing_; - Moment length_; - - static int time_compare (Grob_moment_tuple const &a, Grob_moment_tuple const &b) - { - return Moment::compare (a.length_, b.length_); - } + Grob *spacing_; + + void add_spacing_item (Grob *); + TRANSLATOR_DECLARATIONS (Note_spacing_engraver); +protected: + + DECLARE_ACKNOWLEDGER (rhythmic_grob); + DECLARE_ACKNOWLEDGER (note_column); + void stop_translation_timestep (); + virtual void finalize (); + virtual void derived_mark () const; }; -class Note_spacing_engraver : public Engraver +void +Note_spacing_engraver::derived_mark () const { -public: - TRANSLATOR_DECLARATIONS(Note_spacing_engraver); + 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; +} -protected: - Array lengths_found_; +void +Note_spacing_engraver::add_spacing_item (Grob *g) +{ + if (!spacing_) + { + spacing_ = make_item ("NoteSpacing", g->self_scm ()); + } + + if (spacing_) + { + 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); + } +} - virtual void acknowledge_grob (Grob_info); -}; -Note_spacing_engraver::Note_spacing_engraver() +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::acknowledge_grob (Grob_info gi) +Note_spacing_engraver::finalize () { - if (Note_head::has_interface (gi.grob_l_)) + Context *parent = context ()->get_parent_context (); + Grob *last_spacing = last_spacings_[parent]; + + if (last_spacing + && !unsmob_grob_array (last_spacing->get_object ("right-items"))) { - 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; - } + Grob *col = unsmob_grob (get_property ("currentCommandColumn")); - for (int i=0; i < + Pointer_group_interface::add_grob (last_spacing, + ly_symbol2scm ("right-items"), + col); } - Note_column::has_interface (gi.grob_l_)) - { - Grob *head =Note_column::first_head (gi.grob_l_); +} + +void +Note_spacing_engraver::stop_translation_timestep () +{ + Context *parent = context ()->get_parent_context (); + Grob *last_spacing = last_spacings_[parent]; - head-> + 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 */ + "" + );