]> git.donarmstrong.com Git - lilypond.git/blob - lily/key-engraver.cc
patch::: 1.3.18.jcn1
[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--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   */
8 // clean me up 
9
10 #include "key-engraver.hh"
11 #include "key-item.hh"
12 #include "command-request.hh"
13 #include "local-key-engraver.hh"
14 #include "musical-request.hh"
15 #include "local-key-item.hh"
16 #include "bar.hh"
17 #include "timing-translator.hh"
18 #include "staff-symbol-referencer.hh"
19
20 ADD_THIS_TRANSLATOR (Key_engraver);
21
22 Key_engraver::Key_engraver ()
23 {
24   item_p_ = 0;
25   do_post_move_processing ();
26 }
27
28 bool
29 Key_engraver::key_changed_b () const
30 {
31   return keyreq_l_ ;
32 }
33
34 void
35 Key_engraver::create_key ()
36 {
37   if (!item_p_) 
38     {
39       item_p_ = new Key_item;
40       Staff_symbol_referencer_interface st (item_p_);
41       st.set_interface ();
42       
43       item_p_->set_elt_property ("break-aligned", SCM_BOOL_T); // ugh
44       
45       item_p_->set_elt_property ("multi-octave",
46                                  gh_bool2scm (key_.multi_octave_b_));
47       
48       announce_element (Score_element_info (item_p_,keyreq_l_));
49       
50
51       for (int i = 0; i < accidental_idx_arr_.size(); i++) 
52         {
53           Musical_pitch m_l =accidental_idx_arr_[i];
54           int a =m_l.accidental_i_;      
55           if (key_.multi_octave_b_)
56             item_p_->add (m_l.steps (), a);
57           else
58             item_p_->add (m_l.notename_i_, a);
59         }
60
61       for (int i = 0 ; i < old_accidental_idx_arr_.size(); i++) 
62         {
63           Musical_pitch m_l =old_accidental_idx_arr_[i];
64           int a =m_l.accidental_i_;
65           if (key_.multi_octave_b_)
66             item_p_->add_old (m_l.steps  (), a);
67           else
68             item_p_->add_old (m_l.notename_i_, a);
69         }
70     }
71 }      
72
73
74 bool
75 Key_engraver::do_try_music (Music * req_l)
76 {
77   if (Key_change_req *kc = dynamic_cast <Key_change_req *> (req_l))
78     {
79       if (keyreq_l_)
80         warning (_ ("FIXME: key change merge"));
81       keyreq_l_ = kc;
82       read_req (keyreq_l_);
83       return true;
84     }   
85   return  false;
86 }
87
88 void
89 Key_engraver::acknowledge_element (Score_element_info info)
90 {
91   if (dynamic_cast <Clef_change_req *> (info.req_l_)) 
92     {
93       SCM c =  get_property ("createKeyOnClefChange", 0);
94       if (to_boolean (c))
95         create_key ();
96     }
97   else if (dynamic_cast<Bar *> (info.elem_l_)
98            && accidental_idx_arr_.size ()) 
99     {
100       bool def =  (!item_p_);
101       create_key ();
102       if (!def)
103         {
104           item_p_->set_elt_property ("visibility-lambda",
105                                     ly_eval_str ("all-visibility"));
106         }
107     }
108
109 }
110
111 void
112 Key_engraver::do_process_requests ()
113 {
114   if (keyreq_l_) 
115     {
116       create_key ();
117     }
118 }
119
120 void
121 Key_engraver::do_pre_move_processing ()
122
123   if (item_p_) 
124     {
125       typeset_element (item_p_);
126       item_p_ = 0;
127     }
128 }
129
130
131 /*
132   TODO Slightly hairy.  
133  */
134 void
135 Key_engraver::read_req (Key_change_req const * r)
136 {
137   old_accidental_idx_arr_ = accidental_idx_arr_;
138   key_.clear ();
139   SCM prop = get_property ("keyOctaviation", 0);
140
141   key_.multi_octave_b_ = to_boolean (prop);
142   
143   accidental_idx_arr_.clear ();
144
145   if (r->key_.ordinary_key_b_) 
146     {
147       int no_of_acc = r->key_.ordinary_accidentals_i ();
148
149       // Hmm, can't these be handled/constructed by Key_change_req?
150       if (no_of_acc < 0) 
151         {
152           int accidental = 6 ; // First accidental: bes
153           for ( ; no_of_acc < 0 ; no_of_acc++ ) 
154             {
155               Musical_pitch m;
156               m.accidental_i_ = -1;
157               m.notename_i_ = accidental;
158               if (key_.multi_octave_b_)
159                 key_.set (m);
160               else
161                 key_.set (m.notename_i_, m.accidental_i_);
162               accidental_idx_arr_.push (m);
163               
164               accidental = (accidental + 3) % 7 ;
165             }
166         }
167       else 
168         { 
169           int accidental = 3 ; // First accidental: fis
170           for ( ; no_of_acc > 0 ; no_of_acc-- ) 
171             {
172               Musical_pitch m;
173               m.accidental_i_ = 1;
174               m.notename_i_ = accidental;
175               if (key_.multi_octave_b_)
176                 key_.set (m);
177               else
178                 key_.set (m.notename_i_, m.accidental_i_);
179               accidental_idx_arr_.push (m);
180               
181               accidental = (accidental + 4) % 7 ;
182             }
183         }
184     }
185   else // Special key
186     {
187       for (int i = 0; i < r->key_.pitch_arr_.size (); i ++) 
188         {
189           Musical_pitch m_l =r->key_.pitch_arr_[i];
190           if (key_.multi_octave_b_)
191             key_.set (m_l);
192           else
193             key_.set (m_l.notename_i_, m_l.accidental_i_);
194           
195           accidental_idx_arr_.push (m_l);
196         }
197     }
198 }
199
200 void
201 Key_engraver::do_post_move_processing ()
202 {
203   keyreq_l_ = 0;
204   old_accidental_idx_arr_.clear ();
205 }
206