2 key-engraver.cc -- implement Key_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "bar-line.hh"
11 #include "staff-symbol-referencer.hh"
13 #include "engraver.hh"
14 #include "protected-scm.hh"
18 #include "translator.icc"
21 TODO: The representation of key sigs is all fucked.
25 Make the key signature.
27 class Key_engraver
: public Engraver
29 void create_key (bool);
30 void read_event (Music
const *r
);
36 TRANSLATOR_DECLARATIONS (Key_engraver
);
39 virtual void initialize ();
40 virtual void finalize ();
41 virtual bool try_music (Music
*event
);
42 void stop_translation_timestep ();
43 void process_music ();
45 DECLARE_ACKNOWLEDGER (clef
);
46 DECLARE_ACKNOWLEDGER (bar_line
);
50 Key_engraver::finalize ()
54 Key_engraver::Key_engraver ()
62 Key_engraver::create_key (bool is_default
)
66 item_
= make_item ("KeySignature",
67 key_event_
? key_event_
->self_scm () : SCM_EOL
);
69 item_
->set_property ("c0-position",
70 get_property ("middleCPosition"));
72 SCM last
= get_property ("lastKeySignature");
73 SCM key
= get_property ("keySignature");
75 if ((to_boolean (get_property ("printKeyCancellation"))
77 && !scm_is_eq (last
, key
))
79 cancellation_
= make_item ("KeyCancellation",
81 ? key_event_
->self_scm () : SCM_EOL
);
83 SCM restore
= SCM_EOL
;
85 for (SCM s
= last
; scm_is_pair (s
); s
= scm_cdr (s
))
87 if (scm_assoc (scm_caar (s
), key
) == SCM_BOOL_F
)
89 *tail
= scm_acons (scm_caar (s
),
90 scm_from_int (0), *tail
);
91 tail
= SCM_CDRLOC (*tail
);
95 cancellation_
->set_property ("alteration-alist", restore
);
96 cancellation_
->set_property ("c0-position",
97 get_property ("middleCPosition"));
99 item_
->set_property ("alteration-alist", key
);
104 SCM visibility
= get_property ("explicitKeySignatureVisibility");
105 item_
->set_property ("break-visibility", visibility
);
110 Key_engraver::try_music (Music
*event
)
112 if (event
->is_mus_type ("key-change-event"))
114 /* do this only once, just to be on the safe side. */
118 read_event (key_event_
);
126 Key_engraver::acknowledge_clef (Grob_info info
)
129 SCM c
= get_property ("createKeyOnClefChange");
137 Key_engraver::acknowledge_bar_line (Grob_info info
)
140 if (scm_is_pair (get_property ("keySignature")))
147 Key_engraver::process_music ()
150 || get_property ("lastKeySignature") != get_property ("keySignature"))
155 Key_engraver::stop_translation_timestep ()
158 context ()->set_property ("lastKeySignature", get_property ("keySignature"));
164 Key_engraver::read_event (Music
const *r
)
166 SCM p
= r
->get_property ("pitch-alist");
167 if (!scm_is_pair (p
))
170 SCM n
= scm_list_copy (p
);
172 for (SCM s
= get_property ("keyAlterationOrder");
173 scm_is_pair (s
); s
= scm_cdr (s
))
175 if (scm_is_pair (scm_member (scm_car (s
), n
)))
177 accs
= scm_cons (scm_car (s
), accs
);
178 n
= scm_delete_x (scm_car (s
), n
);
182 for (SCM s
= n
; scm_is_pair (s
); s
= scm_cdr (s
))
183 if (scm_to_int (scm_cdar (s
)))
184 accs
= scm_cons (scm_car (s
), accs
);
186 context ()->set_property ("keySignature", accs
);
187 context ()->set_property ("tonic",
188 r
->get_property ("tonic"));
192 Key_engraver::initialize ()
194 context ()->set_property ("keySignature", SCM_EOL
);
195 context ()->set_property ("lastKeySignature", SCM_EOL
);
198 context ()->set_property ("tonic", p
.smobbed_copy ());
201 ADD_ACKNOWLEDGER (Key_engraver
, clef
);
202 ADD_ACKNOWLEDGER (Key_engraver
, bar_line
);
204 ADD_TRANSLATOR (Key_engraver
,
206 /* create */ "KeySignature",
207 /* accept */ "key-change-event",
208 /* read */ "keySignature printKeyCancellation lastKeySignature "
209 "explicitKeySignatureVisibility createKeyOnClefChange "
210 "keyAlterationOrder keySignature",
211 /* write */ "lastKeySignature tonic keySignature");