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