]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
(print): remove neutral position.
[lilypond.git] / lily / custos-engraver.cc
1 /*
2   custos-engraver.cc -- implement Custos_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2004 Juergen Reuter <reuter@ipd.uka.de>,
7                   Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 */
9
10 #include "engraver.hh"
11 #include "bar-line.hh"
12 #include "item.hh"
13 #include "note-head.hh"
14 #include "staff-symbol-referencer.hh"
15 #include "warn.hh"
16 #include "event.hh"
17
18 /*
19  * This class implements an engraver for custos symbols.
20  *
21  * FIXME: note heads inside of ligatures (i.e. ligature heads) are
22  * sometimes not recognized by this engraver. --jr
23  */
24 class Custos_engraver : public Engraver
25 {
26 public:
27   TRANSLATOR_DECLARATIONS (Custos_engraver);
28   virtual void start_translation_timestep ();
29   virtual void acknowledge_grob (Grob_info);
30   virtual void process_acknowledged_grobs ();
31   virtual void stop_translation_timestep ();
32   virtual void finalize ();
33
34
35 private:
36   Item * create_custos ();
37   bool custos_permitted;
38   Link_array<Grob> custodes_;
39   Array<Pitch> pitches_;
40 };
41
42 Custos_engraver::Custos_engraver ()
43 {
44   custos_permitted = false;
45 }
46
47
48 void
49 Custos_engraver::stop_translation_timestep ()
50 {
51   /*
52     delay typeset until we're at the next moment, so we can silence custodes at the end of the piece.
53    */
54   for (int i = custodes_.size (); i--;)
55     {
56       typeset_grob (custodes_[i]);
57     }
58   pitches_.clear ();
59
60   custos_permitted = false;
61 }
62
63 void
64 Custos_engraver::start_translation_timestep ()
65 {
66   custodes_.clear ();
67 }
68
69
70 void
71 Custos_engraver::acknowledge_grob (Grob_info info)
72 {
73   Item *item = dynamic_cast <Item *> (info.grob_);
74   if (item)
75     {
76       Music * m = info.music_cause ();
77       if (Bar_line::has_interface (info.grob_))
78         custos_permitted = true;
79       else if (Note_head::has_interface (info.grob_)
80                && m
81                && m->is_mus_type ("note-event"))
82         {
83
84           /*
85             ideally, we'd do custos->set_parent (Y_AXIS, notehead),
86             but since the note head lives on the other system, we can't
87
88             So we copy the position from the note head pitch.  We
89             don't look at the staff-position, since we can't be sure
90             whether Clef_engraver already applied a vertical shift.
91           */
92             pitches_.push (*unsmob_pitch (m->get_property ("pitch")));
93         }
94     }
95 }
96
97 void
98 Custos_engraver::process_acknowledged_grobs ()
99 {
100   if (gh_string_p (get_property ("whichBar")))
101     custos_permitted = true;
102   
103   if (custos_permitted)
104     {
105       for (int i = pitches_.size (); i--;)
106         {
107           Item *c = create_custos ();
108
109           int p = pitches_[i].steps ();
110           SCM c0 = get_property ("middleCPosition");
111           if (gh_number_p (c0))
112             p += gh_scm2int (c0);
113
114           
115           c->set_property ("staff-position",
116                                 gh_int2scm (p));
117           
118         }
119
120       pitches_.clear ();
121     }
122 }
123
124 Item* 
125 Custos_engraver::create_custos ()
126 {
127   Item* custos = make_item ("Custos");
128   
129   announce_grob (custos, SCM_EOL);
130   custodes_.push (custos);
131   
132   return custos;
133 }
134
135 void
136 Custos_engraver::finalize ()
137 {
138   for (int i = custodes_.size (); i--;)
139     {
140       custodes_[i]->suicide ();
141       typeset_grob (custodes_[i]);
142     }
143   custodes_.clear ();
144 }
145
146
147
148 ENTER_DESCRIPTION (Custos_engraver,
149 /* descr */       "",
150 /* creats*/       "Custos",
151 /* accepts */     "",
152 /* acks  */      "bar-line-interface note-head-interface",
153 /* reads */       "",
154 /* write */       "");