2 key-engraver.cc -- implement Key_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "key-engraver.hh"
10 #include "key-item.hh"
11 #include "command-request.hh"
12 #include "local-key-engraver.hh"
13 #include "musical-request.hh"
14 #include "local-key-item.hh"
16 #include "time-description.hh"
18 Key_engraver::Key_engraver ()
21 do_post_move_processing ();
25 Key_engraver::create_key ()
29 kit_p_
= new Key_item
;
30 kit_p_
->break_priority_i_
= -1; // ugh
31 kit_p_
->multi_octave_b_
= key_
.multi_octave_b_
;
32 announce_element (Score_element_info (kit_p_
,keyreq_l_
));
35 for (int i
= 0; i
< accidental_idx_arr_
.size(); i
++)
37 Musical_pitch m_l
=accidental_idx_arr_
[i
];
38 int a
=m_l
.accidental_i_
;
39 if (key_
.multi_octave_b_
)
40 kit_p_
->add (m_l
.steps (), a
);
42 kit_p_
->add (m_l
.notename_i_
, a
);
45 for (int i
= 0 ; i
< old_accidental_idx_arr_
.size(); i
++)
47 Musical_pitch m_l
=old_accidental_idx_arr_
[i
];
48 int a
=m_l
.accidental_i_
;
49 if (key_
.multi_octave_b_
)
50 kit_p_
->add_old (m_l
.steps (), a
);
52 kit_p_
->add_old (m_l
.notename_i_
, a
);
59 Key_engraver::do_try_music (Music
* req_l
)
61 if (Key_change_req
*kc
= dynamic_cast <Key_change_req
*> (req_l
))
64 warning ("Fixme: key change merge.");
73 Key_engraver::acknowledge_element (Score_element_info info
)
75 if (dynamic_cast <Clef_change_req
*> (info
.req_l_
))
77 int i
= get_property ("createKeyOnClefChange").length_i ();
81 else if (dynamic_cast<Bar
*> (info
.elem_l_
)
82 && accidental_idx_arr_
.size ())
85 default_key_b_
= true;
92 Key_engraver::do_process_requests ()
101 Key_engraver::do_pre_move_processing ()
105 kit_p_
->default_b_
= default_key_b_
;
106 typeset_element (kit_p_
);
116 Key_engraver::read_req (Key_change_req
const * r
)
118 old_accidental_idx_arr_
= accidental_idx_arr_
;
120 Scalar prop
= get_property ("keyoctaviation");
121 if (prop
.length_i () > 0)
123 key_
.multi_octave_b_
= ! prop
.to_bool ();
126 accidental_idx_arr_
.clear ();
128 if (r
->ordinary_key_b_
)
131 if (r
->pitch_arr_
.size () < 1)
133 r
->warning (_ ("No key name: assuming `C'"));
138 p
= r
->pitch_arr_
[0].semitone_pitch ();
141 /* Solve the equation 7*no_of_acc mod 12 = p, -6 <= no_of_acc <= 5 */
142 int no_of_acc
= (7*p
) % 12;
143 no_of_acc
= (no_of_acc
+ 18) % 12 -6;
145 /* Correct from flats to sharps or vice versa */
146 if (no_of_acc
* r
->pitch_arr_
[0].accidental_i_
< 0)
147 no_of_acc
+= 12 * sign (r
->pitch_arr_
[0].accidental_i_
);
151 int accidental
= 6 ; // First accidental: bes
152 for ( ; no_of_acc
< 0 ; no_of_acc
++ )
155 m
.accidental_i_
= -1;
156 m
.notename_i_
= accidental
;
157 if (key_
.multi_octave_b_
)
160 key_
.set (m
.notename_i_
, m
.accidental_i_
);
161 accidental_idx_arr_
.push (m
);
163 accidental
= (accidental
+ 3) % 7 ;
168 int accidental
= 3 ; // First accidental: fis
169 for ( ; no_of_acc
> 0 ; no_of_acc
-- )
173 m
.notename_i_
= accidental
;
174 if (key_
.multi_octave_b_
)
177 key_
.set (m
.notename_i_
, m
.accidental_i_
);
178 accidental_idx_arr_
.push (m
);
180 accidental
= (accidental
+ 4) % 7 ;
186 for (int i
= 0; i
< r
->pitch_arr_
.size (); i
++)
188 Musical_pitch m_l
=r
->pitch_arr_
[i
];
189 if (key_
.multi_octave_b_
)
192 key_
.set (m_l
.notename_i_
, m_l
.accidental_i_
);
194 accidental_idx_arr_
.push (m_l
);
200 Key_engraver::do_post_move_processing ()
203 default_key_b_
= false;
204 old_accidental_idx_arr_
.clear ();
209 ADD_THIS_TRANSLATOR (Key_engraver
);