2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2000--2015 Juergen Reuter <reuter@ipd.uka.de>,
5 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 LilyPond is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 LilyPond is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21 #include "engraver.hh"
23 #include "note-head.hh"
25 #include "staff-symbol-referencer.hh"
26 #include "stream-event.hh"
29 #include "translator.icc"
34 * This class implements an engraver for custos symbols.
36 * FIXME: note heads inside of ligatures (i.e. ligature heads) are
37 * sometimes not recognized by this engraver. --jr
39 class Custos_engraver : public Engraver
42 TRANSLATOR_DECLARATIONS (Custos_engraver);
43 void start_translation_timestep ();
44 DECLARE_ACKNOWLEDGER (bar);
45 DECLARE_ACKNOWLEDGER (note_head);
46 void process_acknowledged ();
47 void stop_translation_timestep ();
48 virtual void finalize ();
51 Item *create_custos ();
52 bool custos_permitted_;
53 vector<Grob *> custodes_;
54 vector<Pitch> pitches_;
57 Custos_engraver::Custos_engraver ()
59 custos_permitted_ = false;
63 Custos_engraver::stop_translation_timestep ()
66 delay typeset until we're at the next moment, so we can silence custodes at the end of the piece.
70 custos_permitted_ = false;
74 Custos_engraver::start_translation_timestep ()
80 Custos_engraver::acknowledge_bar (Grob_info /* info */)
82 custos_permitted_ = true;
86 Custos_engraver::acknowledge_note_head (Grob_info info)
88 Stream_event *ev = info.event_cause ();
89 if (ev && ev->in_event_class ("note-event"))
93 ideally, we'd do custos->set_parent (Y_AXIS, notehead),
94 but since the note head lives on the other system, we can't
96 So we copy the position from the note head pitch. We
97 don't look at the staff-position, since we can't be sure
98 whether Clef_engraver already applied a vertical shift.
100 pitches_.push_back (*unsmob<Pitch> (ev->get_property ("pitch")));
105 Custos_engraver::process_acknowledged ()
107 if (scm_is_string (get_property ("whichBar")))
108 custos_permitted_ = true;
110 if (custos_permitted_)
112 for (vsize i = pitches_.size (); i--;)
114 Item *c = create_custos ();
116 int p = pitches_[i].steps ();
117 SCM c0 = get_property ("middleCPosition");
118 if (scm_is_number (c0))
119 p += scm_to_int (c0);
121 c->set_property ("staff-position",
130 Custos_engraver::create_custos ()
132 Item *custos = make_item ("Custos", SCM_EOL);
134 custodes_.push_back (custos);
140 Custos_engraver::finalize ()
142 for (vsize i = custodes_.size (); i--;)
143 custodes_[i]->suicide ();
147 ADD_ACKNOWLEDGER (Custos_engraver, bar);
148 ADD_ACKNOWLEDGER (Custos_engraver, note_head);
150 ADD_TRANSLATOR (Custos_engraver,