]> git.donarmstrong.com Git - lilypond.git/blob - lily/key-engraver.cc
6f331d75c4db95e10372963c54bbef6504ca58a2
[lilypond.git] / lily / key-engraver.cc
1 /*
2   key-engraver.cc -- implement Key_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   */
8
9 #include "key-item.hh"
10 #include "command-request.hh"
11 #include "musical-request.hh"
12 #include "item.hh"
13 #include "bar.hh"
14 #include "staff-symbol-referencer.hh"
15 #include "translator-group.hh"
16 #include "engraver.hh"
17 #include "pitch.hh"
18 #include "protected-scm.hh"
19 #include "clef.hh"
20
21 /**
22   Make the key signature.
23  */
24 class Key_engraver : public Engraver
25 {
26   void create_key (bool);
27   void read_req (Key_change_req const * r);
28   Key_change_req * keyreq_l_;
29   Item * item_p_;
30
31 public:
32   TRANSLATOR_DECLARATIONS(Key_engraver);
33
34 protected:
35   virtual void initialize ();
36   virtual void finalize ();
37   virtual bool try_music (Music *req_l);
38   virtual void stop_translation_timestep ();
39   virtual void start_translation_timestep ();
40   virtual void create_grobs ();
41   virtual void acknowledge_grob (Grob_info);
42 };
43
44
45 void
46 Key_engraver::finalize ()
47 {
48 }
49
50
51 Key_engraver::Key_engraver ()
52 {
53   keyreq_l_ = 0;
54   item_p_ = 0;
55 }
56
57
58 void
59 Key_engraver::create_key (bool def)
60 {
61   if (!item_p_) 
62     {
63       item_p_ = new Item (get_property ("KeySignature"));
64
65       item_p_->set_grob_property ("c0-position",
66                                   get_property ("centralCPosition"));
67       
68       // todo: put this in basic props.
69       item_p_->set_grob_property ("old-accidentals", get_property ("lastKeySignature"));
70       item_p_->set_grob_property ("new-accidentals", get_property ("keySignature"));
71
72       Staff_symbol_referencer::set_interface (item_p_);
73       Key_item::set_interface (item_p_);
74       announce_grob (item_p_,keyreq_l_);
75     }
76
77   if (!def)
78     {
79       SCM vis = get_property ("explicitKeySignatureVisibility"); 
80       if (gh_procedure_p (vis))
81         item_p_->set_grob_property ("visibility-lambda",vis);
82     }
83 }      
84
85
86 bool
87 Key_engraver::try_music (Music * req_l)
88 {
89   if (Key_change_req *kc = dynamic_cast <Key_change_req *> (req_l))
90     {
91       if (keyreq_l_ && !keyreq_l_->equal_b (kc))
92         {
93           kc->origin ()->warning (_ ("Conflicting key signatures found."));
94           keyreq_l_->origin ()->warning (_ ("This was the other key definition."));       
95           return false;
96         }
97       keyreq_l_ = kc;
98       read_req (keyreq_l_);
99
100       return true;
101     }   
102   return  false;
103 }
104
105
106 void
107 Key_engraver::acknowledge_grob (Grob_info info)
108 {
109   if (Clef::has_interface (info.grob_l_))
110     {
111       SCM c =  get_property ("createKeyOnClefChange");
112       if (to_boolean (c))
113         {
114           create_key (false);
115         }
116     }
117   else if (Bar::has_interface (info.grob_l_)
118            && gh_pair_p (get_property ("keySignature")))
119     {
120       create_key (true);
121     }
122 }
123
124
125 void
126 Key_engraver::create_grobs ()
127 {
128   if (keyreq_l_ ||
129       get_property ("lastKeySignature") != get_property ("keySignature"))
130     create_key (false);
131 }
132
133
134 void
135 Key_engraver::stop_translation_timestep ()
136 {
137   if (item_p_) 
138     {
139       typeset_grob (item_p_);
140       item_p_ = 0;
141     }
142 }
143
144
145 void
146 Key_engraver::read_req (Key_change_req const * r)
147 {
148   SCM p = r->get_mus_property ("pitch-alist");
149   if (!gh_pair_p (p))
150     return;
151
152   SCM n = scm_list_copy (p);
153   SCM accs = SCM_EOL;
154   for (SCM s = get_property ("keyAccidentalOrder");
155        gh_pair_p (s); s = ly_cdr (s))
156     {
157       if (gh_pair_p (scm_member (ly_car (s), n)))
158         {
159           accs = gh_cons (ly_car (s), accs);
160           n = scm_delete_x (ly_car (s), n);
161         }
162     }
163   
164   for (SCM s = n ; gh_pair_p (s); s = ly_cdr (s))
165     if (gh_scm2int (ly_cdar (s)))
166       accs = gh_cons (ly_car (s), accs);
167
168   daddy_trans_l_->set_property ("lastKeySignature",
169                                 get_property ("keySignature"));
170   daddy_trans_l_->set_property ("keySignature", accs);
171 }
172
173
174 void
175 Key_engraver::start_translation_timestep ()
176 {
177   keyreq_l_ = 0;
178   daddy_trans_l_->set_property ("lastKeySignature", get_property ("keySignature"));
179 }
180
181
182 void
183 Key_engraver::initialize ()
184 {
185   daddy_trans_l_->set_property ("keySignature", SCM_EOL);
186   daddy_trans_l_->set_property ("lastKeySignature", SCM_EOL);
187 }
188
189
190 ENTER_DESCRIPTION(Key_engraver,
191 /* descr */       "",
192 /* creats*/       "KeySignature",
193 /* acks  */       "bar-line-interface clef-interface",
194 /* reads */       "keySignature lastKeySignature explicitKeySignatureVisibility createKeyOnClefChange keyAccidentalOrder keySignature",
195 /* write */       "lastKeySignature");