]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-spacing-engraver.cc
Fix 399.
[lilypond.git] / lily / note-spacing-engraver.cc
1 /* 
2   note-spacing-engraver.cc -- implement Note_spacing_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2006--2007 Han-Wen Nienhuys <hanwen@lilypond.org>
7   
8 */
9
10 #include "engraver.hh"
11
12 #include "grob-array.hh"
13 #include "context.hh"
14 #include "item.hh"
15 #include "pointer-group-interface.hh"
16
17 #include <map>
18
19 #include "translator.icc"
20
21 class Note_spacing_engraver : public Engraver
22 {
23   typedef map <Context*, Grob*> Last_spacing_map;
24   Last_spacing_map last_spacings_;
25   
26   Grob *spacing_;
27
28   void add_spacing_item (Grob *);
29   TRANSLATOR_DECLARATIONS (Note_spacing_engraver);
30 protected:
31
32   DECLARE_ACKNOWLEDGER (rhythmic_grob);
33   DECLARE_ACKNOWLEDGER (note_column);
34   void stop_translation_timestep ();
35   virtual void finalize ();
36   virtual void derived_mark () const;
37 };
38
39 void
40 Note_spacing_engraver::derived_mark () const
41 {
42   for (Last_spacing_map::const_iterator i = last_spacings_.begin ();
43        i != last_spacings_.end (); i++)
44     scm_gc_mark (i->first->self_scm ());
45 }
46
47 Note_spacing_engraver::Note_spacing_engraver ()
48 {
49   spacing_ = 0;
50 }
51
52 void
53 Note_spacing_engraver::add_spacing_item (Grob *g)
54 {
55   if (!spacing_)
56     {
57       spacing_ = make_item ("NoteSpacing", g->self_scm ());
58     }
59   
60   if (spacing_)
61     {
62       Pointer_group_interface::add_grob (spacing_,
63                                          ly_symbol2scm ("left-items"),
64                                          g);
65
66       Grob *last_spacing = last_spacings_[context ()->get_parent_context ()];
67       if (last_spacing)
68         Pointer_group_interface::add_grob (last_spacing,
69                                            ly_symbol2scm ("right-items"),
70                                            g);
71     }
72 }
73
74
75 void
76 Note_spacing_engraver::acknowledge_note_column (Grob_info gi)
77 {
78   add_spacing_item (gi.grob ());
79 }
80
81 void
82 Note_spacing_engraver::acknowledge_rhythmic_grob (Grob_info gi)
83 {
84   add_spacing_item (gi.grob ());
85 }
86
87 void
88 Note_spacing_engraver::finalize ()
89 {
90   Context *parent = context ()->get_parent_context ();
91   Grob *last_spacing = last_spacings_[parent];
92
93   if (last_spacing
94       && !unsmob_grob_array (last_spacing->get_object ("right-items")))
95     {
96       Grob *col  = unsmob_grob (get_property ("currentCommandColumn"));
97       
98       Pointer_group_interface::add_grob (last_spacing,
99                                          ly_symbol2scm ("right-items"),
100                                          col);
101     }
102 }
103
104 void
105 Note_spacing_engraver::stop_translation_timestep ()
106 {
107   Context *parent = context ()->get_parent_context ();
108   Grob *last_spacing = last_spacings_[parent];
109
110   if (last_spacing
111       && to_boolean (get_property ("hasStaffSpacing")))
112     {
113       Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
114       Pointer_group_interface::add_grob (last_spacing,
115                                          ly_symbol2scm ("right-items"),
116                                          col);
117     }
118   
119   if (spacing_)
120     {
121       last_spacings_[parent] = spacing_;
122       spacing_ = 0;
123     }
124
125 }
126
127 ADD_ACKNOWLEDGER (Note_spacing_engraver, note_column);
128 ADD_ACKNOWLEDGER (Note_spacing_engraver, rhythmic_grob);
129
130 ADD_TRANSLATOR (Note_spacing_engraver,
131                 /* doc */ "Generates NoteSpacing, an object linking horizontal lines for use in spacing.",
132                 /* create */ "NoteSpacing",
133                 /* read */ "",
134                 /* write */ "");