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