]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
Web-ja: update introduction
[lilypond.git] / lily / custos-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2000--2015 Juergen Reuter <reuter@ipd.uka.de>,
5   Han-Wen Nienhuys <hanwen@xs4all.nl>
6
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.
11
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.
16
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/>.
19 */
20
21 #include "engraver.hh"
22 #include "item.hh"
23 #include "note-head.hh"
24 #include "pitch.hh"
25 #include "staff-symbol-referencer.hh"
26 #include "stream-event.hh"
27 #include "warn.hh"
28
29 #include "translator.icc"
30
31 /*
32  * This class implements an engraver for custos symbols.
33  *
34  * FIXME: note heads inside of ligatures (i.e. ligature heads) are
35  * sometimes not recognized by this engraver. --jr
36  */
37 class Custos_engraver : public Engraver
38 {
39 public:
40   TRANSLATOR_DECLARATIONS (Custos_engraver);
41   void start_translation_timestep ();
42   void acknowledge_bar (Grob_info);
43   void acknowledge_note_head (Grob_info);
44   void process_acknowledged ();
45   void stop_translation_timestep ();
46   virtual void finalize ();
47
48 private:
49   Item *create_custos ();
50   bool custos_permitted_;
51   vector<Grob *> custodes_;
52   vector<Pitch> pitches_;
53 };
54
55 Custos_engraver::Custos_engraver (Context *c)
56   : Engraver (c)
57 {
58   custos_permitted_ = false;
59 }
60
61 void
62 Custos_engraver::stop_translation_timestep ()
63 {
64   /*
65     delay typeset until we're at the next moment, so we can silence custodes at the end of the piece.
66   */
67   pitches_.clear ();
68
69   custos_permitted_ = false;
70 }
71
72 void
73 Custos_engraver::start_translation_timestep ()
74 {
75   custodes_.clear ();
76 }
77
78 void
79 Custos_engraver::acknowledge_bar (Grob_info /* info */)
80 {
81   custos_permitted_ = true;
82 }
83
84 void
85 Custos_engraver::acknowledge_note_head (Grob_info info)
86 {
87   Stream_event *ev = info.event_cause ();
88   if (ev && ev->in_event_class ("note-event"))
89     {
90
91       /*
92         ideally, we'd do custos->set_parent (Y_AXIS, notehead),
93         but since the note head lives on the other system, we can't
94
95         So we copy the position from the note head pitch.  We
96         don't look at the staff-position, since we can't be sure
97         whether Clef_engraver already applied a vertical shift.
98       */
99       pitches_.push_back (*unsmob<Pitch> (ev->get_property ("pitch")));
100     }
101 }
102
103 void
104 Custos_engraver::process_acknowledged ()
105 {
106   if (scm_is_string (get_property ("whichBar")))
107     custos_permitted_ = true;
108
109   if (custos_permitted_)
110     {
111       for (vsize i = pitches_.size (); i--;)
112         {
113           Item *c = create_custos ();
114
115           int p = pitches_[i].steps ();
116           SCM c0 = get_property ("middleCPosition");
117           if (scm_is_number (c0))
118             p += scm_to_int (c0);
119
120           c->set_property ("staff-position",
121                            scm_from_int (p));
122         }
123
124       pitches_.clear ();
125     }
126 }
127
128 Item *
129 Custos_engraver::create_custos ()
130 {
131   Item *custos = make_item ("Custos", SCM_EOL);
132
133   custodes_.push_back (custos);
134
135   return custos;
136 }
137
138 void
139 Custos_engraver::finalize ()
140 {
141   for (vsize i = custodes_.size (); i--;)
142     custodes_[i]->suicide ();
143   custodes_.clear ();
144 }
145
146
147 void
148 Custos_engraver::boot ()
149 {
150   ADD_ACKNOWLEDGER (Custos_engraver, bar);
151   ADD_ACKNOWLEDGER (Custos_engraver, note_head);
152 }
153
154 ADD_TRANSLATOR (Custos_engraver,
155                 /* doc */
156                 "Engrave custodes.",
157
158                 /* create */
159                 "Custos ",
160
161                 /* read */
162                 "",
163
164                 /* write */
165                 ""
166                );