]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
d0546bf65e3ee2749f4a6e0c240afd8088f9ab2d
[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--2007 Juergen Reuter <reuter@ipd.uka.de>,
7   Han-Wen Nienhuys <hanwen@xs4all.nl>
8 */
9
10 #include "engraver.hh"
11 #include "bar-line.hh"
12 #include "item.hh"
13 #include "note-head.hh"
14 #include "pitch.hh"
15 #include "staff-symbol-referencer.hh"
16 #include "stream-event.hh"
17 #include "warn.hh"
18
19 #include "translator.icc"
20
21 /*
22  * This class implements an engraver for custos symbols.
23  *
24  * FIXME: note heads inside of ligatures (i.e. ligature heads) are
25  * sometimes not recognized by this engraver. --jr
26  */
27 class Custos_engraver : public Engraver
28 {
29 public:
30   TRANSLATOR_DECLARATIONS (Custos_engraver);
31   void start_translation_timestep ();
32   DECLARE_ACKNOWLEDGER (bar);
33   DECLARE_ACKNOWLEDGER (note_head);
34   void process_acknowledged ();
35   void stop_translation_timestep ();
36   virtual void finalize ();
37
38 private:
39   Item *create_custos ();
40   bool custos_permitted_;
41   vector<Grob*> custodes_;
42   vector<Pitch> pitches_;
43 };
44
45 Custos_engraver::Custos_engraver ()
46 {
47   custos_permitted_ = false;
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   pitches_.clear ();
57
58   custos_permitted_ = false;
59 }
60
61 void
62 Custos_engraver::start_translation_timestep ()
63 {
64   custodes_.clear ();
65 }
66
67 void
68 Custos_engraver::acknowledge_bar (Grob_info info)
69 {
70   (void) info;
71   custos_permitted_ = true;
72 }
73
74 void
75 Custos_engraver::acknowledge_note_head (Grob_info info)
76 {
77   Stream_event *ev = info.event_cause ();
78   if (ev && ev->in_event_class ("note-event"))
79     {
80
81       /*
82         ideally, we'd do custos->set_parent (Y_AXIS, notehead),
83         but since the note head lives on the other system, we can't
84
85         So we copy the position from the note head pitch.  We
86         don't look at the staff-position, since we can't be sure
87         whether Clef_engraver already applied a vertical shift.
88       */
89       pitches_.push_back (*unsmob_pitch (ev->get_property ("pitch")));
90     }
91 }
92
93 void
94 Custos_engraver::process_acknowledged ()
95 {
96   if (scm_is_string (get_property ("whichBar")))
97     custos_permitted_ = true;
98
99   if (custos_permitted_)
100     {
101       for (vsize 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 (scm_is_number (c0))
108             p += scm_to_int (c0);
109
110           c->set_property ("staff-position",
111                            scm_from_int (p));
112         }
113
114       pitches_.clear ();
115     }
116 }
117
118 Item *
119 Custos_engraver::create_custos ()
120 {
121   Item *custos = make_item ("Custos", SCM_EOL);
122
123   custodes_.push_back (custos);
124
125   return custos;
126 }
127
128 void
129 Custos_engraver::finalize ()
130 {
131   for (vsize i = custodes_.size (); i--;)
132     custodes_[i]->suicide ();
133   custodes_.clear ();
134 }
135
136 ADD_ACKNOWLEDGER (Custos_engraver, bar);
137 ADD_ACKNOWLEDGER (Custos_engraver, note_head);
138
139 ADD_TRANSLATOR (Custos_engraver,
140                 /* doc */
141                 "Engrave custodes.",
142
143                 /* create */
144                 "Custos ",
145
146                 /* read */
147                 "",
148
149                 /* write */
150                 ""
151                 );