]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
* lily/include/lily-guile.hh: compatibility glue for 1.6
[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   pitches_.clear ();
55
56   custos_permitted = false;
57 }
58
59 void
60 Custos_engraver::start_translation_timestep ()
61 {
62   custodes_.clear ();
63 }
64
65
66 void
67 Custos_engraver::acknowledge_grob (Grob_info info)
68 {
69   Item *item = dynamic_cast <Item *> (info.grob_);
70   if (item)
71     {
72       Music * m = info.music_cause ();
73       if (Bar_line::has_interface (info.grob_))
74         custos_permitted = true;
75       else if (Note_head::has_interface (info.grob_)
76                && m
77                && m->is_mus_type ("note-event"))
78         {
79
80           /*
81             ideally, we'd do custos->set_parent (Y_AXIS, notehead),
82             but since the note head lives on the other system, we can't
83
84             So we copy the position from the note head pitch.  We
85             don't look at the staff-position, since we can't be sure
86             whether Clef_engraver already applied a vertical shift.
87           */
88             pitches_.push (*unsmob_pitch (m->get_property ("pitch")));
89         }
90     }
91 }
92
93 void
94 Custos_engraver::process_acknowledged_grobs ()
95 {
96   if (scm_is_string (get_property ("whichBar")))
97     custos_permitted = true;
98   
99   if (custos_permitted)
100     {
101       for (int i = pitches_.size (); i--;)
102         {
103           Item *c = create_custos ();
104
105           int p = pitches_[i].steps ();
106           SCM c0 = get_property ("middleCPosition");
107           if (ly_c_number_p (c0))
108             p += ly_scm2int (c0);
109
110           
111           c->set_property ("staff-position",
112                                 scm_int2num (p));
113           
114         }
115
116       pitches_.clear ();
117     }
118 }
119
120 Item* 
121 Custos_engraver::create_custos ()
122 {
123   Item* custos = make_item ("Custos", SCM_EOL);
124   
125   
126   custodes_.push (custos);
127   
128   return custos;
129 }
130
131 void
132 Custos_engraver::finalize ()
133 {
134   for (int i = custodes_.size (); i--;)
135     {
136       custodes_[i]->suicide ();
137     }
138   custodes_.clear ();
139 }
140
141
142
143 ENTER_DESCRIPTION (Custos_engraver,
144 /* descr */       "",
145 /* creats*/       "Custos",
146 /* accepts */     "",
147 /* acks  */      "bar-line-interface note-head-interface",
148 /* reads */       "",
149 /* write */       "");