]> git.donarmstrong.com Git - lilypond.git/blob - lily/pitched-trill-engraver.cc
Web-ja: update introduction
[lilypond.git] / lily / pitched-trill-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2005--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "engraver.hh"
21
22 #include "axis-group-interface.hh"
23 #include "context.hh"
24 #include "dots.hh"
25 #include "item.hh"
26 #include "note-head.hh"
27 #include "pitch.hh"
28 #include "pointer-group-interface.hh"
29 #include "side-position-interface.hh"
30 #include "stream-event.hh"
31 #include "warn.hh"
32
33 #include "translator.icc"
34
35 class Pitched_trill_engraver : public Engraver
36 {
37 public:
38   TRANSLATOR_DECLARATIONS (Pitched_trill_engraver);
39
40 protected:
41   void acknowledge_note_head (Grob_info);
42   void acknowledge_dots (Grob_info);
43   void acknowledge_stem (Grob_info);
44   void acknowledge_flag (Grob_info);
45   void acknowledge_trill_spanner (Grob_info);
46   void stop_translation_timestep ();
47
48 private:
49   Item *trill_head_;
50   Item *trill_group_;
51   Item *trill_accidental_;
52
53   vector<Grob *> heads_;
54
55   void make_trill (Stream_event *);
56 };
57
58 Pitched_trill_engraver::Pitched_trill_engraver (Context *c)
59   : Engraver (c)
60 {
61   trill_head_ = 0;
62   trill_group_ = 0;
63   trill_accidental_ = 0;
64 }
65
66 void
67 Pitched_trill_engraver::acknowledge_dots (Grob_info info)
68 {
69   heads_.push_back (info.grob ());
70 }
71 void
72 Pitched_trill_engraver::acknowledge_stem (Grob_info info)
73 {
74   heads_.push_back (info.grob ());
75 }
76 void
77 Pitched_trill_engraver::acknowledge_flag (Grob_info info)
78 {
79   heads_.push_back (info.grob ());
80 }
81 void
82 Pitched_trill_engraver::acknowledge_note_head (Grob_info info)
83 {
84   heads_.push_back (info.grob ());
85 }
86
87 void
88 Pitched_trill_engraver::acknowledge_trill_spanner (Grob_info info)
89 {
90   Stream_event *ev = info.event_cause ();
91   if (ev
92       && ev->in_event_class ("trill-span-event")
93       && to_dir (ev->get_property ("span-direction")) == START
94       && unsmob<Pitch> (ev->get_property ("pitch")))
95     make_trill (ev);
96 }
97
98 void
99 Pitched_trill_engraver::make_trill (Stream_event *ev)
100 {
101   SCM scm_pitch = ev->get_property ("pitch");
102   Pitch *p = unsmob<Pitch> (scm_pitch);
103
104   SCM keysig = get_property ("localAlterations");
105
106   SCM key = scm_cons (scm_from_int (p->get_octave ()),
107                       scm_from_int (p->get_notename ()));
108
109   int bn = measure_number (context ());
110
111   SCM handle = scm_assoc (key, keysig);
112   if (scm_is_true (handle))
113     {
114       bool same_bar = (bn == robust_scm2int (scm_caddr (handle), 0));
115       bool same_alt
116         = (p->get_alteration () == robust_scm2rational (scm_cadr (handle), 0));
117
118       if (!same_bar || (same_bar && !same_alt))
119         handle = SCM_BOOL_F;
120     }
121
122   bool print_acc = scm_is_false (handle)
123                    || p->get_alteration () == Rational (0)
124                    || to_boolean (ev->get_property ("force-accidental"));
125
126   if (trill_head_)
127     {
128       programming_error ("already have a trill head.");
129       trill_head_ = 0;
130     }
131
132   trill_head_ = make_item ("TrillPitchHead", ev->self_scm ());
133   SCM c0scm = get_property ("middleCPosition");
134
135   int c0 = scm_is_number (c0scm) ? scm_to_int (c0scm) : 0;
136
137   trill_head_->set_property ("staff-position",
138                              scm_from_int (unsmob<Pitch> (scm_pitch)->steps ()
139                                            + c0));
140
141   trill_group_ = make_item ("TrillPitchGroup", ev->self_scm ());
142   trill_group_->set_parent (trill_head_, Y_AXIS);
143
144   Axis_group_interface::add_element (trill_group_, trill_head_);
145
146   if (print_acc)
147     {
148       trill_accidental_ = make_item ("TrillPitchAccidental", ev->self_scm ());
149
150       // fixme: naming -> alterations
151       trill_accidental_->set_property ("alteration", ly_rational2scm (p->get_alteration ()));
152       Side_position_interface::add_support (trill_accidental_, trill_head_);
153
154       trill_head_->set_object ("accidental-grob", trill_accidental_->self_scm ());
155       trill_accidental_->set_parent (trill_head_, Y_AXIS);
156       Axis_group_interface::add_element (trill_group_, trill_accidental_);
157     }
158 }
159
160 void
161 Pitched_trill_engraver::stop_translation_timestep ()
162 {
163   if (trill_group_)
164     for (vsize i = 0; i < heads_.size (); i++)
165       Side_position_interface::add_support (trill_group_, heads_[i]);
166
167   heads_.clear ();
168   trill_head_ = 0;
169   trill_group_ = 0;
170   trill_accidental_ = 0;
171 }
172
173
174 void
175 Pitched_trill_engraver::boot ()
176 {
177   ADD_ACKNOWLEDGER (Pitched_trill_engraver, note_head);
178   ADD_ACKNOWLEDGER (Pitched_trill_engraver, dots);
179   ADD_ACKNOWLEDGER (Pitched_trill_engraver, stem);
180   ADD_ACKNOWLEDGER (Pitched_trill_engraver, flag);
181   ADD_ACKNOWLEDGER (Pitched_trill_engraver, trill_spanner);
182 }
183
184 ADD_TRANSLATOR (Pitched_trill_engraver,
185                 /* doc */
186                 "Print the bracketed note head after a note head with trill.",
187
188                 /* create */
189                 "TrillPitchHead "
190                 "TrillPitchAccidental "
191                 "TrillPitchGroup ",
192
193                 /* read */
194                 "",
195
196                 /* write */
197                 ""
198                );