]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-spacing-engraver.cc
Run `make grand-replace'.
[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--2008 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   Grob *last_spacing_;
26   
27   Grob *spacing_;
28
29   void add_spacing_item (Grob *);
30   TRANSLATOR_DECLARATIONS (Note_spacing_engraver);
31 protected:
32
33   DECLARE_ACKNOWLEDGER (rhythmic_grob);
34   DECLARE_ACKNOWLEDGER (note_column);
35   void stop_translation_timestep ();
36   virtual void finalize ();
37   virtual void derived_mark () const;
38 };
39
40 void
41 Note_spacing_engraver::derived_mark () const
42 {
43   for (Last_spacing_map::const_iterator i = last_spacings_.begin ();
44        i != last_spacings_.end (); i++)
45     scm_gc_mark (i->first->self_scm ());
46 }
47
48 Note_spacing_engraver::Note_spacing_engraver ()
49 {
50   spacing_ = 0;
51   last_spacing_ = 0;
52 }
53
54 void
55 Note_spacing_engraver::add_spacing_item (Grob *g)
56 {
57   if (!spacing_)
58     {
59       spacing_ = make_item ("NoteSpacing", g->self_scm ());
60     }
61   
62   if (spacing_)
63     {
64       Pointer_group_interface::add_grob (spacing_,
65                                          ly_symbol2scm ("left-items"),
66                                          g);
67
68       if (last_spacing_)
69         Pointer_group_interface::add_grob (last_spacing_,
70                                            ly_symbol2scm ("right-items"),
71                                            g);
72     }
73 }
74
75
76 void
77 Note_spacing_engraver::acknowledge_note_column (Grob_info gi)
78 {
79   add_spacing_item (gi.grob ());
80 }
81
82 void
83 Note_spacing_engraver::acknowledge_rhythmic_grob (Grob_info gi)
84 {
85   add_spacing_item (gi.grob ());
86 }
87
88 void
89 Note_spacing_engraver::finalize ()
90 {
91   Context *parent = context ()->get_parent_context ();
92   Grob *last_spacing = last_spacings_[parent];
93
94   if (last_spacing
95       && !unsmob_grob_array (last_spacing->get_object ("right-items")))
96     {
97       Grob *col  = unsmob_grob (get_property ("currentCommandColumn"));
98       
99       Pointer_group_interface::add_grob (last_spacing,
100                                          ly_symbol2scm ("right-items"),
101                                          col);
102     }
103 }
104
105 void
106 Note_spacing_engraver::stop_translation_timestep ()
107 {
108   Context *parent = context ()->get_parent_context ();
109   Grob *last_spacing = last_spacings_[parent];
110
111   if (last_spacing
112       && to_boolean (get_property ("hasStaffSpacing")))
113     {
114       Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
115       Pointer_group_interface::add_grob (last_spacing,
116                                          ly_symbol2scm ("right-items"),
117                                          col);
118     }
119   
120   if (spacing_)
121     {
122       last_spacings_[parent] = spacing_;
123       last_spacing_ = spacing_;
124       spacing_ = 0;
125     }
126
127 }
128
129 ADD_ACKNOWLEDGER (Note_spacing_engraver, note_column);
130 ADD_ACKNOWLEDGER (Note_spacing_engraver, rhythmic_grob);
131
132 ADD_TRANSLATOR (Note_spacing_engraver,
133                 /* doc */
134                 "Generate @code{NoteSpacing}, an object linking horizontal"
135                 " lines for use in spacing.",
136
137                 /* create */
138                 "NoteSpacing ",
139
140                 /* read */
141                 "",
142
143                 /* write */
144                 ""
145                 );