]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
* lily/include/event.hh: remove file.
[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--2005 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 "pitch.hh"
17
18
19 /*
20  * This class implements an engraver for custos symbols.
21  *
22  * FIXME: note heads inside of ligatures (i.e. ligature heads) are
23  * sometimes not recognized by this engraver. --jr
24  */
25 class Custos_engraver : public Engraver
26 {
27 public:
28   TRANSLATOR_DECLARATIONS (Custos_engraver);
29   virtual void start_translation_timestep ();
30   virtual void acknowledge_grob (Grob_info);
31   virtual void process_acknowledged_grobs ();
32   virtual void stop_translation_timestep ();
33   virtual void finalize ();
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 void
48 Custos_engraver::stop_translation_timestep ()
49 {
50   /*
51     delay typeset until we're at the next moment, so we can silence custodes at the end of the piece.
52   */
53   pitches_.clear ();
54
55   custos_permitted = false;
56 }
57
58 void
59 Custos_engraver::start_translation_timestep ()
60 {
61   custodes_.clear ();
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_property ("pitch")));
87         }
88     }
89 }
90
91 void
92 Custos_engraver::process_acknowledged_grobs ()
93 {
94   if (scm_is_string (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 ("middleCPosition");
105           if (scm_is_number (c0))
106             p += scm_to_int (c0);
107
108           c->set_property ("staff-position",
109                            scm_int2num (p));
110         }
111
112       pitches_.clear ();
113     }
114 }
115
116 Item *
117 Custos_engraver::create_custos ()
118 {
119   Item *custos = make_item ("Custos", SCM_EOL);
120
121   custodes_.push (custos);
122
123   return custos;
124 }
125
126 void
127 Custos_engraver::finalize ()
128 {
129   for (int i = custodes_.size (); i--;)
130     {
131       custodes_[i]->suicide ();
132     }
133   custodes_.clear ();
134 }
135
136 ADD_TRANSLATOR (Custos_engraver,
137                 /* descr */ "",
138                 /* creats*/ "Custos",
139                 /* accepts */ "",
140                 /* acks  */ "bar-line-interface note-head-interface",
141                 /* reads */ "",
142                 /* write */ "");