]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
*** empty log message ***
[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--2003 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 acknowledge_grob (Grob_info);
29   virtual void process_acknowledged_grobs ();
30   virtual void stop_translation_timestep ();
31   virtual void finalize ();
32
33
34 private:
35   Item * create_custos ();
36   bool custos_permitted;
37   Link_array<Grob> custodes_;
38   Array<Pitch> pitches_;
39 };
40
41 Custos_engraver::Custos_engraver ()
42 {
43   custos_permitted = false;
44 }
45
46
47 void
48 Custos_engraver::stop_translation_timestep ()
49 {
50   for (int i = custodes_.size (); i--;)
51     {
52       typeset_grob (custodes_[i]);
53     }
54
55   /*
56     delay clear until we're at the next moment, so we can silence
57     custodes at the end of the piece.
58    */
59   pitches_.clear ();
60   custos_permitted = false;
61 }
62
63
64 void
65 Custos_engraver::acknowledge_grob (Grob_info info)
66 {
67   Item *item = dynamic_cast <Item *> (info.grob_);
68   if (item)
69     {
70       Music * m = info.music_cause();
71       if (Bar_line::has_interface (info.grob_))
72         custos_permitted = true;
73       else if (Note_head::has_interface (info.grob_)
74                && m
75                && m->is_mus_type ("note-event"))
76         {
77
78           /*
79             ideally, we'd do custos->set_parent (Y_AXIS, notehead),
80             but since the note head lives on the other system, we can't
81
82             So we copy the position from the note head pitch.  We
83             don't look at the staff-position, since we can't be sure
84             whether Clef_engraver already applied a vertical shift.
85           */
86             pitches_.push (*unsmob_pitch (m->get_mus_property ("pitch")));
87         }
88     }
89 }
90
91 void
92 Custos_engraver::process_acknowledged_grobs ()
93 {
94   if (gh_string_p (get_property ("whichBar")))
95     custos_permitted = true;
96   
97   if (custos_permitted)
98     {
99       for (int i = pitches_.size (); i--;)
100         {
101           Item *c = create_custos ();
102
103           int p = pitches_[i].steps ();
104           SCM c0 = get_property ("centralCPosition");
105           if (gh_number_p (c0))
106             p += gh_scm2int (c0);
107
108           
109           c->set_grob_property ("staff-position",
110                                 gh_int2scm (p));
111           
112         }
113
114       pitches_.clear ();
115     }
116 }
117
118 Item* 
119 Custos_engraver::create_custos ()
120 {
121   SCM basicProperties = get_property ("Custos");
122   Item* custos = new Item (basicProperties);
123   
124   announce_grob(custos, SCM_EOL);
125   custodes_.push (custos);
126   
127   return custos;
128 }
129
130 void
131 Custos_engraver::finalize ()
132 {
133   for (int i = custodes_.size (); i--;)
134     {
135       custodes_[i]->suicide ();
136     }
137   custodes_.clear ();
138 }
139
140
141
142 ENTER_DESCRIPTION(Custos_engraver,
143 /* descr */       "",
144 /* creats*/       "Custos",
145 /* accepts */     "",
146 /* acks  */      "bar-line-interface note-head-interface",
147 /* reads */       "",
148 /* write */       "");