]> git.donarmstrong.com Git - lilypond.git/blob - lily/clef-engraver.cc
8195fbd9bf6c382b4e76f2f489e7fdcf15ac3ebf
[lilypond.git] / lily / clef-engraver.cc
1 /*
2   clef.cc -- implement Clef_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>,
7   Mats Bengtsson <matsb@s3.kth.se>
8 */
9
10 #include <ctype.h>
11 #include "bar.hh"
12 #include "clef-engraver.hh"
13 #include "clef-item.hh"
14 #include "debug.hh"
15 #include "command-request.hh"
16 #include "time-description.hh"
17
18
19 #include "note-head.hh"
20 #include "key-item.hh"
21 #include "local-key-item.hh"
22
23 Clef_engraver::Clef_engraver()
24 {
25   clef_p_ = 0;
26   clef_req_l_ = 0;
27   clef_type_str_ = "";
28   c0_position_i_ = 0;
29   clef_position_i_ = 0;
30   octave_dir_ = CENTER;
31 }
32
33 /*
34   Ugh.  Should have support for Dictionaries in mudela.
35  */
36 bool
37 Clef_engraver::set_type (String s)
38 {
39   if (s.right_str(2) == "_8") // Down one octave
40     {
41       octave_dir_ = DOWN;
42       s = s.left_str(s.length_i() - 2);
43     }
44   else if (s.right_str(2) == "^8") // Up one octave
45     {
46       octave_dir_ = UP;
47       s = s.left_str(s.length_i() - 2);
48     }
49   else
50     octave_dir_ = CENTER;
51   if (s == "treble" ||
52       s == "violin" ||
53       s == "G" || s == "G2")
54     {
55       clef_type_str_ = "violin";
56       clef_position_i_ = -2;
57     }
58   else if (s == "french")
59     {
60       clef_type_str_ = "violin";
61       clef_position_i_ = -4;
62     }
63   else if (s == "soprano")
64     {
65       clef_type_str_ = "alto";
66       clef_position_i_ = -4;
67     }
68   else if (s == "mezzosoprano")
69     {
70       clef_type_str_ = "alto";
71       clef_position_i_ = -2;
72     }
73   else if (s == "alto")
74     {
75       clef_type_str_ = "alto";
76       clef_position_i_ = 0;
77     }
78   else if (s == "tenor")
79     {
80       clef_type_str_ = "alto";
81       clef_position_i_ = 2;
82     }
83   else if (s == "baritone")
84     {
85       clef_type_str_ = "alto";
86       clef_position_i_ = 4;
87     }
88   else if (s == "varbaritone")
89     {
90       clef_type_str_ = "bass";
91       clef_position_i_ = 0;
92     }
93   else if (s == "bass" || s == "F")
94     {
95       clef_type_str_ = "bass";
96       clef_position_i_ = 2;
97     }
98   else if (s == "subbass")
99     {
100       clef_type_str_ = "bass";
101       clef_position_i_ = 4;
102     }
103   else 
104     {
105       switch(toupper (s[0]))
106         {
107         case 'F': 
108           clef_type_str_ = "bass";
109           break;
110         case  'G':
111           clef_type_str_ = "violin";
112           break;
113         case 'C': 
114           clef_type_str_ = "alto";
115           break;
116         default:
117           return false;
118         }
119       clef_position_i_ = 2 * (s[1] - '0') - 6;
120     }
121   if (clef_type_str_ == "violin")
122     c0_position_i_ = clef_position_i_ - 4;
123   else if (clef_type_str_ == "alto")
124     c0_position_i_ = clef_position_i_;
125   else if (clef_type_str_ == "bass")
126     c0_position_i_ = clef_position_i_ + 4;
127   else
128     assert (false);
129
130       
131   c0_position_i_ -= (int) octave_dir_ * 7;
132   
133   return true;
134 }
135
136 void
137 Clef_engraver::read_req (Clef_change_req*c_l)
138 {
139   if (!set_type (c_l->clef_str_))
140     c_l->error (_ ("unknown clef type "));
141 }
142
143
144 /** 
145   Generate a clef at the start of a measure. (when you see a Bar,
146   ie. a breakpoint) 
147   */
148 void
149 Clef_engraver::acknowledge_element (Score_element_info info)
150 {
151   if (info.elem_l_->is_type_b (Bar::static_name ()) 
152       && clef_type_str_.length_i())
153     {
154       create_clef();
155       if (!clef_req_l_)
156         clef_p_->default_b_ = true;
157     }
158
159   /* ugh; should make Clef_referenced baseclass */
160   Item * it_l =info.elem_l_->access_Item ();
161 if (it_l)
162   {
163   if (it_l->is_type_b (Note_head::static_name ()))
164     {
165       Note_head * h = (Note_head*)it_l;
166       h->position_i_ += c0_position_i_;
167     }
168   else if (it_l->is_type_b (Local_key_item::static_name ()))
169     {
170       Local_key_item *i = (Local_key_item*)it_l;
171       i->c0_position_i_ =c0_position_i_;
172     }
173   else if (it_l->is_type_b (Key_item::static_name ()))
174     {
175       Key_item *k = (Key_item*)it_l;
176       k-> set_c_position (c0_position_i_);
177     }
178   } 
179 }
180
181 void
182 Clef_engraver::do_creation_processing()
183 {
184   Scalar def = get_property ("defaultClef");
185   if (def.to_bool ()) // egcs: Scalar to bool is ambiguous
186     set_type (def);
187   
188   if (clef_type_str_.length_i ())
189     { 
190       create_clef();
191       clef_p_->default_b_ = false;
192     }
193 }
194
195 bool
196 Clef_engraver::do_try_request (Request * r_l)
197 {
198   Command_req* creq_l= r_l->access_Command_req ();
199   if (!creq_l || !creq_l->access_Clef_change_req ())
200     return false;
201
202   clef_req_l_ = creq_l->access_Clef_change_req ();
203   read_req (clef_req_l_);
204   return true;
205 }
206
207 void
208 Clef_engraver::create_clef()
209 {
210   if (!clef_p_)
211     {
212       clef_p_ = new Clef_item;
213       clef_p_->break_priority_i_ = -2; // ugh
214       announce_element (Score_element_info (clef_p_,clef_req_l_));
215     }
216   clef_p_->read (*this);
217 }
218
219 void
220 Clef_engraver::do_process_requests()
221 {
222   if (clef_req_l_)
223     {
224       create_clef();
225       clef_p_->default_b_ = false;
226     }
227 }
228
229 void
230 Clef_engraver::do_pre_move_processing()
231 {
232   if (clef_p_)
233     {
234       typeset_element (clef_p_);
235       clef_p_ = 0;
236     }
237 }
238 void
239 Clef_engraver::do_post_move_processing()
240 {
241   clef_req_l_ = 0;
242 }
243
244 void
245 Clef_engraver::do_removal_processing()
246 {
247   if (clef_p_)
248     {
249       clef_p_->unlink ();       
250       delete clef_p_;
251       clef_p_ =0;
252     }
253 }
254
255
256 IMPLEMENT_IS_TYPE_B1(Clef_engraver,Engraver);
257 ADD_THIS_TRANSLATOR(Clef_engraver);